diff --git a/CMakeLists.txt b/CMakeLists.txt index 327ae97f61a..62487d77a7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,6 @@ include(Utils) env_with_default("QTC_BUILD_WITH_PCH" ENV_QTC_BUILD_WITH_PCH ON) env_with_default("QTC_WITH_TESTS" ENV_QTC_WITH_TESTS OFF) -env_with_default("QTC_WITH_QMLDESIGNER" ENV_QTC_WITH_QMLDESIGNER ON) option(BUILD_WITH_PCH "Build with precompiled headers" "${ENV_QTC_BUILD_WITH_PCH}") @@ -78,12 +77,9 @@ find_package(Qt6 REQUIRED ) -if (Qt6_VERSION VERSION_GREATER_EQUAL 6.5.4) - option(WITH_QMLDESIGNER "Build QmlDesigner" ${ENV_QTC_WITH_QMLDESIGNER}) -else() - option(WITH_QMLDESIGNER "Build QmlDesigner" OFF) -endif() -add_feature_info("Build QmlDesigner and related code (only if Qt is 6.5.4 or newer)" ${WITH_QMLDESIGNER} "") +# depending on Qt version and compiler version enable or disable Qml Designer +# can be overwritten by variable WITH_QMLDESIGNER / QTC_WITH_QMLDESIGNER (env) +configure_qml_designer(${Qt6_VERSION}) # hack for Qbs which still supports Qt5 and Qt6 if (TARGET Qt6::Core5CompatPrivate) diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake index c53b479982d..5d39157b020 100644 --- a/cmake/QtCreatorAPI.cmake +++ b/cmake/QtCreatorAPI.cmake @@ -126,7 +126,7 @@ endfunction() function(add_qtc_library name) cmake_parse_arguments(_arg "STATIC;OBJECT;SHARED;SKIP_TRANSLATION;ALLOW_ASCII_CASTS;FEATURE_INFO;SKIP_PCH;EXCLUDE_FROM_INSTALL" "DESTINATION;COMPONENT;SOURCES_PREFIX;BUILD_DEFAULT" - "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES" ${ARGN} + "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES;PRIVATE_COMPILE_OPTIONS;PUBLIC_COMPILE_OPTIONS" ${ARGN} ) get_default_defines(default_defines_copy ${_arg_ALLOW_ASCII_CASTS}) @@ -209,6 +209,8 @@ function(add_qtc_library name) EXPLICIT_MOC ${_arg_EXPLICIT_MOC} SKIP_AUTOMOC ${_arg_SKIP_AUTOMOC} EXTRA_TRANSLATIONS ${_arg_EXTRA_TRANSLATIONS} + PRIVATE_COMPILE_OPTIONS ${_arg_PRIVATE_COMPILE_OPTIONS} + PUBLIC_COMPILE_OPTIONS ${_arg_PUBLIC_COMPILE_OPTIONS} ) if (QTC_STATIC_BUILD) @@ -330,7 +332,7 @@ function(add_qtc_plugin target_name) cmake_parse_arguments(_arg "SKIP_INSTALL;INTERNAL_ONLY;SKIP_TRANSLATION;EXPORT;SKIP_PCH" "VERSION;COMPAT_VERSION;PLUGIN_PATH;PLUGIN_NAME;OUTPUT_NAME;BUILD_DEFAULT;PLUGIN_CLASS" - "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PLUGIN_DEPENDS;PLUGIN_RECOMMENDS;PLUGIN_TEST_DEPENDS;PLUGIN_MANUAL_DEPENDS;PROPERTIES" + "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PLUGIN_DEPENDS;PLUGIN_RECOMMENDS;PLUGIN_TEST_DEPENDS;PLUGIN_MANUAL_DEPENDS;PROPERTIES;PRIVATE_COMPILE_OPTIONS;PUBLIC_COMPILE_OPTIONS" ${ARGN} ) @@ -498,6 +500,8 @@ function(add_qtc_plugin target_name) EXPLICIT_MOC ${_arg_EXPLICIT_MOC} SKIP_AUTOMOC ${_arg_SKIP_AUTOMOC} EXTRA_TRANSLATIONS ${_arg_EXTRA_TRANSLATIONS} + PRIVATE_COMPILE_OPTIONS ${_arg_PRIVATE_COMPILE_OPTIONS} + PUBLIC_COMPILE_OPTIONS ${_arg_PUBLIC_COMPILE_OPTIONS} ) if (QTC_STATIC_BUILD) @@ -635,7 +639,7 @@ endfunction() function(add_qtc_executable name) cmake_parse_arguments(_arg "SKIP_INSTALL;SKIP_TRANSLATION;ALLOW_ASCII_CASTS;SKIP_PCH;QTC_RUNNABLE" "DESTINATION;COMPONENT;BUILD_DEFAULT" - "CONDITION;DEPENDS;DEFINES;INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES" ${ARGN}) + "CONDITION;DEPENDS;DEFINES;INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES;PRIVATE_COMPILE_OPTIONS;PUBLIC_COMPILE_OPTIONS" ${ARGN}) if (${_arg_UNPARSED_ARGUMENTS}) message(FATAL_ERROR "add_qtc_executable had unparsed arguments!") @@ -711,6 +715,8 @@ function(add_qtc_executable name) EXPLICIT_MOC ${_arg_EXPLICIT_MOC} SKIP_AUTOMOC ${_arg_SKIP_AUTOMOC} EXTRA_TRANSLATIONS ${_arg_EXTRA_TRANSLATIONS} + PRIVATE_COMPILE_OPTIONS ${_arg_PRIVATE_COMPILE_OPTIONS} + PUBLIC_COMPILE_OPTIONS ${_arg_PUBLIC_COMPILE_OPTIONS} ) set(skip_translation OFF) @@ -838,7 +844,7 @@ endfunction() function(add_qtc_test name) cmake_parse_arguments(_arg "GTEST;MANUALTEST;EXCLUDE_FROM_PRECHECK;NEEDS_GUI" "TIMEOUT" - "DEFINES;DEPENDS;INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;SKIP_PCH;CONDITION;PROPERTIES" ${ARGN}) + "DEFINES;DEPENDS;INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;SKIP_PCH;CONDITION;PROPERTIES;PRIVATE_COMPILE_OPTIONS;PUBLIC_COMPILE_OPTIONS" ${ARGN}) if (${_arg_UNPARSED_ARGUMENTS}) message(FATAL_ERROR "add_qtc_test had unparsed arguments!") @@ -890,6 +896,8 @@ function(add_qtc_test name) DEFINES ${_arg_DEFINES} ${TEST_DEFINES} ${default_defines_copy} EXPLICIT_MOC ${_arg_EXPLICIT_MOC} SKIP_AUTOMOC ${_arg_SKIP_AUTOMOC} + PRIVATE_COMPILE_OPTIONS ${_arg_PRIVATE_COMPILE_OPTIONS} + PUBLIC_COMPILE_OPTIONS ${_arg_PUBLIC_COMPILE_OPTIONS} ) set_target_properties(${name} PROPERTIES diff --git a/cmake/QtCreatorAPIInternal.cmake b/cmake/QtCreatorAPIInternal.cmake index 9fc986205df..6dcee09f065 100644 --- a/cmake/QtCreatorAPIInternal.cmake +++ b/cmake/QtCreatorAPIInternal.cmake @@ -484,7 +484,7 @@ function(extend_qtc_target target_name) cmake_parse_arguments(_arg "" "SOURCES_PREFIX;SOURCES_PREFIX_FROM_TARGET;FEATURE_INFO" - "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES;SOURCES_PROPERTIES" + "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES;SOURCES_PROPERTIES;PRIVATE_COMPILE_OPTIONS;PUBLIC_COMPILE_OPTIONS" ${ARGN} ) @@ -572,6 +572,16 @@ function(extend_qtc_target target_name) if (_arg_SOURCES_PROPERTIES) set_source_files_properties(${_arg_SOURCES} PROPERTIES ${_arg_SOURCES_PROPERTIES}) endif() + + + if (_arg_PRIVATE_COMPILE_OPTIONS) + target_compile_options(${target_name} PRIVATE ${_arg_PRIVATE_COMPILE_OPTIONS}) + endif() + + if (_arg_PUBLIC_COMPILE_OPTIONS) + target_compile_options(${target_name} PUBLIC ${_arg_PUBLIC_COMPILE_OPTIONS}) + endif() + endfunction() function (qtc_env_with_default envName varToSet default) diff --git a/cmake/QtCreatorIDEBranding.cmake b/cmake/QtCreatorIDEBranding.cmake index 81d76cce980..4dd9f6fa21c 100644 --- a/cmake/QtCreatorIDEBranding.cmake +++ b/cmake/QtCreatorIDEBranding.cmake @@ -8,6 +8,8 @@ set(IDE_DISPLAY_NAME "Qt Creator") # The IDE display name. set(IDE_ID "qtcreator") # The IDE id (no spaces, lowercase!) set(IDE_CASED_ID "QtCreator") # The cased IDE id (no spaces!) set(IDE_BUNDLE_IDENTIFIER "org.qt-project.${IDE_ID}") # The macOS application bundle identifier. +set(IDE_APP_ID "org.qt-project.${IDE_ID}") # The free desktop application identifier. + set(PROJECT_USER_FILE_EXTENSION .user) set(IDE_DOC_FILE "qtcreator/qtcreator.qdocconf") @@ -17,5 +19,5 @@ set(IDE_DOC_FILE_ONLINE "qtcreator/qtcreator-online.qdocconf") # Should contain qtcreator.ico, qtcreator.xcassets set(IDE_ICON_PATH "") # Absolute, or relative to /src/app -# Should contain images/logo/(16|24|32|48|64|128|256|512)/QtProject-qtcreator.png +# Should contain images/logo/(16|24|32|48|64|128|256|512)/QtProject-${IDE_ID}.png set(IDE_LOGO_PATH "") diff --git a/cmake/Utils.cmake b/cmake/Utils.cmake index 3dbe0f1e810..e7fa26d918d 100644 --- a/cmake/Utils.cmake +++ b/cmake/Utils.cmake @@ -59,3 +59,45 @@ function(setup_dependencies_component) ) endif() endfunction() + +function(configure_qml_designer Qt6_VERSION) + set(QMLDESIGNER_QT6_REQUIRED_VERSION 6.5.4) + set(QMLDESIGNER_GCC_REQUIRED_VERSION 10.0) + set(QMLDESIGNER_CLANG_REQUIRED_VERSION 13.0) + set(QMLDESIGNER_APPLECLANG_REQUIRED_VERSION 15.0) + + string(CONCAT QMLDESIGNER_FEATURE_DESC + "Needs a Qt ${QMLDESIGNER_QT6_REQUIRED_VERSION} or newer") + + if (Qt6_VERSION VERSION_GREATER_EQUAL ${QMLDESIGNER_QT6_REQUIRED_VERSION}) + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND + CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${QMLDESIGNER_GCC_REQUIRED_VERSION}) + set(QTC_WITH_QMLDESIGNER_DEFAULT OFF) + string(APPEND QMLDESIGNER_FEATURE_DESC " and at least GCC ${QMLDESIGNER_GCC_REQUIRED_VERSION}") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND + CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${QMLDESIGNER_APPLECLANG_REQUIRED_VERSION}) + set(QTC_WITH_QMLDESIGNER_DEFAULT OFF) + string(APPEND QMLDESIGNER_FEATURE_DESC " and at least AppleClang ${QMLDESIGNER_APPLECLANG_REQUIRED_VERSION}") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND + CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${QMLDESIGNER_CLANG_REQUIRED_VERSION}) + set(QTC_WITH_QMLDESIGNER_DEFAULT OFF) + string(APPEND QMLDESIGNER_FEATURE_DESC " and at least Clang ${QMLDESIGNER_CLANG_REQUIRED_VERSION}") + else() + set(QTC_WITH_QMLDESIGNER_DEFAULT ON) + endif() + else() + set(QTC_WITH_QMLDESIGNER_DEFAULT OFF) + endif() + + env_with_default("QTC_WITH_QMLDESIGNER" ENV_QTC_WITH_QMLDESIGNER ${QTC_WITH_QMLDESIGNER_DEFAULT}) + option(WITH_QMLDESIGNER "Build QmlDesigner" ${ENV_QTC_WITH_QMLDESIGNER}) + add_feature_info("WITH_QMLDESIGNER" ${WITH_QMLDESIGNER} "${QMLDESIGNER_FEATURE_DESC}") + + set(QTC_IS_SUPPORTED_PROJECTSTORAGE_QT_DEFAULT OFF) + if(Qt6_VERSION VERSION_GREATER_EQUAL 6.7.3 AND Qt6_VERSION VERSION_LESS 6.8.0) + set(QTC_IS_SUPPORTED_PROJECTSTORAGE_QT_DEFAULT ON) + endif() + env_with_default("QTC_IS_SUPPORTED_PROJECTSTORAGE_QT" ENV_QTC_IS_SUPPORTED_PROJECTSTORAGE_QT ${QTC_IS_SUPPORTED_PROJECTSTORAGE_QT_DEFAULT}) + option(IS_SUPPORTED_PROJECTSTORAGE_QT "IS_SUPPORTED_PROJECTSTORAGE_QT" ${ENV_QTC_IS_SUPPORTED_PROJECTSTORAGE_QT}) + add_feature_info("IS_SUPPORTED_PROJECTSTORAGE_QT" ${IS_SUPPORTED_PROJECTSTORAGE_QT} "is ${IS_SUPPORTED_PROJECTSTORAGE_QT}") +endfunction() diff --git a/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake b/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake index 69479620f8d..ebbd7edfe94 100644 --- a/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake +++ b/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake @@ -1,6 +1,6 @@ set(IDE_VERSION "4.6.0") # The IDE version. set(IDE_VERSION_COMPAT "4.6.0") # The IDE Compatibility version. -set(IDE_VERSION_DISPLAY "4.6.0") # The IDE display version. +set(IDE_VERSION_DISPLAY "4.6") # The IDE display version. set(IDE_COPYRIGHT_YEAR "2024") # The IDE current copyright year. set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation. @@ -9,6 +9,7 @@ set(IDE_DISPLAY_NAME "Qt Design Studio") # The IDE display name. set(IDE_ID "qtdesignstudio") # The IDE id (no spaces, lowercase!) set(IDE_CASED_ID "QtDesignStudio") # The cased IDE id (no spaces!) set(IDE_BUNDLE_IDENTIFIER "org.qt-project.${IDE_ID}") # The macOS application bundle identifier. +set(IDE_APP_ID "io.qt.${IDE_ID}") # The free desktop application identifier. set(PROJECT_USER_FILE_EXTENSION .qtds) set(IDE_DOC_FILE "qtdesignstudio/qtdesignstudio.qdocconf") diff --git a/dist/branding/qtdesignstudio/QtProject/QtDesignStudio.ini b/dist/branding/qtdesignstudio/QtProject/QtDesignStudio.ini index 70dec8082df..2aaba0a6e31 100644 --- a/dist/branding/qtdesignstudio/QtProject/QtDesignStudio.ini +++ b/dist/branding/qtdesignstudio/QtProject/QtDesignStudio.ini @@ -63,3 +63,6 @@ Settings\ShowRunOutput=0 [KeyboardShortcutsV2] QtCreator.ReturnToEditor= + +[J.QtQuick] +QmlJSEditor.UseQmlls=false diff --git a/dist/branding/qtdesignstudio/images/logo/128/QtProject-qtcreator.png b/dist/branding/qtdesignstudio/images/logo/128/QtProject-qtdesignstudio.png similarity index 100% rename from dist/branding/qtdesignstudio/images/logo/128/QtProject-qtcreator.png rename to dist/branding/qtdesignstudio/images/logo/128/QtProject-qtdesignstudio.png diff --git a/dist/branding/qtdesignstudio/images/logo/16/QtProject-qtcreator.png b/dist/branding/qtdesignstudio/images/logo/16/QtProject-qtdesignstudio.png similarity index 100% rename from dist/branding/qtdesignstudio/images/logo/16/QtProject-qtcreator.png rename to dist/branding/qtdesignstudio/images/logo/16/QtProject-qtdesignstudio.png diff --git a/dist/branding/qtdesignstudio/images/logo/24/QtProject-qtcreator.png b/dist/branding/qtdesignstudio/images/logo/24/QtProject-qtdesignstudio.png similarity index 100% rename from dist/branding/qtdesignstudio/images/logo/24/QtProject-qtcreator.png rename to dist/branding/qtdesignstudio/images/logo/24/QtProject-qtdesignstudio.png diff --git a/dist/branding/qtdesignstudio/images/logo/256/QtProject-qtcreator.png b/dist/branding/qtdesignstudio/images/logo/256/QtProject-qtdesignstudio.png similarity index 100% rename from dist/branding/qtdesignstudio/images/logo/256/QtProject-qtcreator.png rename to dist/branding/qtdesignstudio/images/logo/256/QtProject-qtdesignstudio.png diff --git a/dist/branding/qtdesignstudio/images/logo/32/QtProject-qtcreator.png b/dist/branding/qtdesignstudio/images/logo/32/QtProject-qtdesignstudio.png similarity index 100% rename from dist/branding/qtdesignstudio/images/logo/32/QtProject-qtcreator.png rename to dist/branding/qtdesignstudio/images/logo/32/QtProject-qtdesignstudio.png diff --git a/dist/branding/qtdesignstudio/images/logo/48/QtProject-qtcreator.png b/dist/branding/qtdesignstudio/images/logo/48/QtProject-qtdesignstudio.png similarity index 100% rename from dist/branding/qtdesignstudio/images/logo/48/QtProject-qtcreator.png rename to dist/branding/qtdesignstudio/images/logo/48/QtProject-qtdesignstudio.png diff --git a/dist/branding/qtdesignstudio/images/logo/512/QtProject-qtcreator.png b/dist/branding/qtdesignstudio/images/logo/512/QtProject-qtdesignstudio.png similarity index 100% rename from dist/branding/qtdesignstudio/images/logo/512/QtProject-qtcreator.png rename to dist/branding/qtdesignstudio/images/logo/512/QtProject-qtdesignstudio.png diff --git a/dist/branding/qtdesignstudio/images/logo/64/QtProject-qtcreator.png b/dist/branding/qtdesignstudio/images/logo/64/QtProject-qtdesignstudio.png similarity index 100% rename from dist/branding/qtdesignstudio/images/logo/64/QtProject-qtcreator.png rename to dist/branding/qtdesignstudio/images/logo/64/QtProject-qtdesignstudio.png diff --git a/doc/config/macros.qdocconf b/doc/config/macros.qdocconf index 751bc80ab71..b3461ad939f 100644 --- a/doc/config/macros.qdocconf +++ b/doc/config/macros.qdocconf @@ -40,6 +40,7 @@ macro.QSDK = "Qt" macro.QUL = "Qt Quick Ultralite" macro.QUV = "Qt UI Viewer" macro.QOI = "Qt Online Installer" +macro.QM = "Qt Multimedia" macro.QMT = "Qt Maintenance Tool" macro.qtcversion = $QTC_VERSION macro.param = "\\e" diff --git a/doc/qtcreator/images/extraimages/images/h0p27_HScxc.jpg b/doc/qtcreator/images/extraimages/images/h0p27_HScxc.jpg new file mode 100644 index 00000000000..be60737539a Binary files /dev/null and b/doc/qtcreator/images/extraimages/images/h0p27_HScxc.jpg differ diff --git a/doc/qtcreator/images/extraimages/qtdesignstudio-extraimages.qdocconf b/doc/qtcreator/images/extraimages/qtdesignstudio-extraimages.qdocconf index 6eead9aa2cd..c1aaede46d5 100644 --- a/doc/qtcreator/images/extraimages/qtdesignstudio-extraimages.qdocconf +++ b/doc/qtcreator/images/extraimages/qtdesignstudio-extraimages.qdocconf @@ -11,4 +11,5 @@ images/pEETxSxYazg.jpg \ images/V3Po15bNErw.jpg \ images/9MqUCP6JLCQ.jpg \ - images/KDxnMQzgmIY.jpg + images/KDxnMQzgmIY.jpg \ + images/h0p27_HScxc.jpg diff --git a/doc/qtcreator/src/external-resources/external-resources-qds.qdoc b/doc/qtcreator/src/external-resources/external-resources-qds.qdoc index 2a340b9ea99..c46066168e8 100644 --- a/doc/qtcreator/src/external-resources/external-resources-qds.qdoc +++ b/doc/qtcreator/src/external-resources/external-resources-qds.qdoc @@ -105,3 +105,139 @@ \externalpage https://doc.qt.io/qt/linguist-id-based-i18n.html \title Text ID based translations */ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-4.5.1-released + \title Qt Design Studio 4.5.1 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-4.5-released + \title Qt Design Studio 4.5 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-4.4-released + \title Qt Design Studio 4.4 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-4.3.2-released + \title Qt Design Studio 4.3.2 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-4.3.1-released + \title Qt Design Studio 4.3.1 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-4.3-released + \title Qt Design Studio 4.3 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-4.2-released + \title Qt Design Studio 4.2 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-4.1-released + \title Qt Design Studio 4.1 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-4.0.1-released + \title Qt Design Studio 4.0.1 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-4.0-released + \title Qt Design Studio 4.0 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-3.9-released + \title Qt Design Studio 3.9 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-3.8-released + \title Qt Design Studio 3.8 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-3.7-released + \title Qt Design Studio 3.7 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-3.6-released + \title Qt Design Studio 3.6 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-3.5-released + \title Qt Design Studio 3.5 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-3.4-released + \title Qt Design Studio 3.4 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-3.3-released + \title Qt Design Studio 3.3 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-3.2-released + \title Qt Design Studio 3.2 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-3.1-released + \title Qt Design Studio 3.1 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-3.0-released + \title Qt Design Studio 3.0 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-2.3-released + \title Qt Design Studio 2.3 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-2.2-released + \title Qt Design Studio 2.2 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-2.1-released + \title Qt Design Studio 2.1 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-2.0-released + \title Qt Design Studio 2.0 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-1.6.1-released + \title Qt Design Studio 1.6.1 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-1.6-released + \title Qt Design Studio 1.6 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-1.5-released + \title Qt Design Studio 1.5 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-1.4-released + \title Qt Design Studio 1.4 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-1.3.1-released + \title Qt Design Studio 1.3.1 released +*/ +/*! + \externalpage https://www.qt.io/blog/qt-design-studio-1.3-released + \title Qt Design Studio 1.3 released +*/ +/*! + \externalpage https://www.qt.io/blog/2019/06/03/qt-design-studio-1-2-released + \title Qt Design Studio 1.2 released +*/ +/*! + \externalpage https://www.qt.io/blog/2019/04/12/qt-design-studio-1-1-1-released + \title Qt Design Studio 1.1.1 released +*/ +/*! + \externalpage https://www.qt.io/blog/2019/02/19/qt-design-studio-1-1-released + \title Qt Design Studio 1.1 released +*/ +/*! + \externalpage https://www.qt.io/blog/2018/10/25/qt-design-studio-1-0-released + \title Qt Design Studio 1.0 released +*/ diff --git a/doc/qtdesignstudio/config/style/qt5-sidebar.html b/doc/qtdesignstudio/config/style/qt5-sidebar.html index 994ecd3db30..7ca7d5b1e65 100644 --- a/doc/qtdesignstudio/config/style/qt5-sidebar.html +++ b/doc/qtdesignstudio/config/style/qt5-sidebar.html @@ -3,6 +3,11 @@
  • View All Topics
  • +
    + +

    Getting Started

    diff --git a/doc/qtdesignstudio/examples/doc/DesignEffect.qdoc b/doc/qtdesignstudio/examples/doc/DesignEffect.qdoc new file mode 100644 index 00000000000..4311b802cc2 --- /dev/null +++ b/doc/qtdesignstudio/examples/doc/DesignEffect.qdoc @@ -0,0 +1,152 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page design-effect-example.html + \ingroup studioexamples + + \title Design Effect + \brief Illustrates how to use the \QDS design effect. + + \image studio-design-effects-demo-gallery.webp + + The \e{Design Effects Demo Gallery} example illustrates the use cases of the + design effects in \QDS. Learn more about design effects + \l {https://doc.qt.io/qtdesignstudio/quick-design-effects.html}{here}. + + In this example, you see and interact with the implementation of the following design effect + principles: + \table + \header + \li Design Effect + \li Description + \row + \li Neumorphism + \li Creates a soft and light look with elements that appear to protrude from or dent + into the background rather than float on top of it. + \row + \li Skeuomorphism + \li Emulates the appearance of physical objects. + \row + \li Glassmorphism + \li Uses transparency and blur to emulate the appearance of frosted glass. + \endtable + + You can also try the \uicontrol {Demo Project} in the example. This project + represents Neumorphism, Skeuomorphism, and Glassmorphism effects used in a digital calculator + environment. + + Watch this video tutorial to learn how to create these effects using \QDS design effects: + \youtube h0p27_HScxc + + \section1 Using Neumorphism Example + + \image studio-neumorphism.webp + + In the \e {Design Effects Demo Gallery}, go to the \uicontrol Intro, + \uicontrol {Design Studies}, or \uicontrol Animation to see the Neumorphism effects + created using design effects in \QDS. To access these sections: + + \list 1 + \li Select \uicontrol Neumorphism. + \li Select \uicontrol Intro, \uicontrol {Design Studies}, \uicontrol {Design Studies 2}, + \uicontrol or \uicontrol Animation to see the corresponding section in display. + \endlist + + \note These design studies show different Neumorphism effects achieved using Figma, and how + accurately they translate into \QDS design effects. + The animation gives a real-time animated Neumorphism design effect in \QDS. + + \section1 Using Skeuomorphism Example + + \image studio-skeuomorphism.webp + + In the \e {Design Effects Demo Gallery}, go to the \uicontrol Intro, + \uicontrol {Design Studies}, or \uicontrol Interaction to see the Skeuomorphism effects + created using design effects in \QDS. To access these sections: + + \list 1 + \li Select \uicontrol Skeuomorphism. + \li Select \uicontrol Intro, \uicontrol {Design Studies}, or \uicontrol Interaction + to see the corresponding section in display. + \li To try the Skeuomorphism effects further, go to \uicontrol Skeuomorphism > + \uicontrol Interaction and select the \e{Actual Qt Quick Buttons}. + \endlist + + \note The design study here shows the Skeuomorphism effects achieved using Figma, and how + accurately they translate into \QDS design effects. The \e{Actual Qt Quick Buttons} are + interactive buttons where Skeuomorphism design principles work. You can click + these buttons to test different stages of the Skeuomorphism effect. + + + \section1 Using Glassmorphism Example + + \image studio-glassmorphism.webp + + In the \e {Design Effects Demo Gallery}, go to the \uicontrol Intro, + \uicontrol {Design studies}, or \uicontrol Interaction to see the Glassmorphism effects + created using design effects in \QDS. To access these sections: + + \list 1 + \li Select \uicontrol Glassmorphism. + \li Select \uicontrol Intro, \uicontrol {Design Studies}, \uicontrol Animation, or + \uicontrol Interaction to see the corresponding section in the display area. + \li Try the Glassmorphism effects further in \uicontrol Interaction. Go to + \uicontrol Glassmorphism > \uicontrol Interaction, and drag the window with the + Glassmorphism effect where you want to move it. Due to the Glassmorphism effect, the + part of the image hidden behind it would become blurred. + \endlist + + \section1 Using the Design Effect Demo Project + + \image studio-design-effects-demo-project.webp + + The \uicontrol {Demo Project} combines design effects, including \uicontrol Neumorphism, + \uicontrol Skeuomorphism, and \uicontrol Glassmorphism. It also includes sound effects using + \l {https://doc.qt.io/qt-6/qtmultimedia-index.html} {\QM}. In the \uicontrol {Demo Project}, + you can interact with a Single Toggle Operation Integer Calculator. + + To run the Single Toggle Operation Integer Calculator, go to \uicontrol {Demo Project}, + and select \uicontrol {Run Demo}. + + To remove the previous calculation data and make the calculator ready for a new + arithmetic operation, select \uicontrol CLR. + + To change the theme of the calculator between light and dark, select \uicontrol DARK. + + \section2 Using Shadow or Blur Effects + + To change the direction of the shadows on the calculator, drag \uicontrol {SHADOW DIR} + up or down. + + To control how much the shadow can spread on the calculator, go to \uicontrol SPREAD, + click and hold, and then move the mouse in a circular motion to the left or right. + + To adjust the level of blur in the calculator control and display, go to \uicontrol BLUR, + click and hold, and then move the mouse in a circular motion to the left or right. + + To turn the design effects on or off in the calculator, select \uicontrol FX. + + \section2 Using Music or Sound Effects + + To play sound or music in the calculator: + \list + \li To play music in a loop, select \uicontrol CHRD, \uicontrol TECH, or + \uicontrol DUB. + \li To play brief sounds, select \uicontrol KCK or \uicontrol WMP. You can also play these + sounds while one of the \uicontrol CHRD, \uicontrol TECH, or \uicontrol DUB music + is playing. + \li To play laughter, select \uicontrol {":)"}. + + \note You cannot play \uicontrol CHRD, \uicontrol TECH, and \uicontrol DUB music together. + When you select one of them, the other stops immediately. + \endlist + + To change the volume of the sound effects in the calculator, go to \uicontrol VOLUME, + and then move the mouse in a circular motion to the left or right. + + To stop all the sounds and music, select \uicontrol MUTE. If the \uicontrol MUTE is inactive, + each button you select for the arithmetic operation also plays a brief sound. + + +*/ diff --git a/doc/qtdesignstudio/examples/doc/images/studio-design-effects-demo-gallery.webp b/doc/qtdesignstudio/examples/doc/images/studio-design-effects-demo-gallery.webp new file mode 100644 index 00000000000..93e629ec31d Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/studio-design-effects-demo-gallery.webp differ diff --git a/doc/qtdesignstudio/examples/doc/images/studio-design-effects-demo-project.webp b/doc/qtdesignstudio/examples/doc/images/studio-design-effects-demo-project.webp new file mode 100644 index 00000000000..56fc750eb8b Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/studio-design-effects-demo-project.webp differ diff --git a/doc/qtdesignstudio/examples/doc/images/studio-glassmorphism.webp b/doc/qtdesignstudio/examples/doc/images/studio-glassmorphism.webp new file mode 100644 index 00000000000..1c183eac381 Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/studio-glassmorphism.webp differ diff --git a/doc/qtdesignstudio/examples/doc/images/studio-neumorphism.webp b/doc/qtdesignstudio/examples/doc/images/studio-neumorphism.webp new file mode 100644 index 00000000000..bbe8625910a Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/studio-neumorphism.webp differ diff --git a/doc/qtdesignstudio/examples/doc/images/studio-skeuomorphism.webp b/doc/qtdesignstudio/examples/doc/images/studio-skeuomorphism.webp new file mode 100644 index 00000000000..d6920c766f4 Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/studio-skeuomorphism.webp differ diff --git a/doc/qtdesignstudio/images/qmldesigner-anchors.png b/doc/qtdesignstudio/images/qmldesigner-anchors.png deleted file mode 100644 index 6038027d70b..00000000000 Binary files a/doc/qtdesignstudio/images/qmldesigner-anchors.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qt-figma-bridge-settings.png b/doc/qtdesignstudio/images/qt-figma-bridge-settings.png index e19eb3cd3a9..d6d0f01483c 100644 Binary files a/doc/qtdesignstudio/images/qt-figma-bridge-settings.png and b/doc/qtdesignstudio/images/qt-figma-bridge-settings.png differ diff --git a/doc/qtdesignstudio/images/qtquick-layout-components.webp b/doc/qtdesignstudio/images/qtquick-layout-components.webp new file mode 100644 index 00000000000..fbeb2167c6d Binary files /dev/null and b/doc/qtdesignstudio/images/qtquick-layout-components.webp differ diff --git a/doc/qtdesignstudio/images/qtquick-layout-context-menu.webp b/doc/qtdesignstudio/images/qtquick-layout-context-menu.webp new file mode 100644 index 00000000000..64dbe9713fc Binary files /dev/null and b/doc/qtdesignstudio/images/qtquick-layout-context-menu.webp differ diff --git a/doc/qtdesignstudio/images/qtquick-layout-grid-layout-properties.webp b/doc/qtdesignstudio/images/qtquick-layout-grid-layout-properties.webp new file mode 100644 index 00000000000..6dd0b0d1cee Binary files /dev/null and b/doc/qtdesignstudio/images/qtquick-layout-grid-layout-properties.webp differ diff --git a/doc/qtdesignstudio/images/qtquick-layout-grid-properties.png b/doc/qtdesignstudio/images/qtquick-layout-grid-properties.png deleted file mode 100644 index 2a6d744f73f..00000000000 Binary files a/doc/qtdesignstudio/images/qtquick-layout-grid-properties.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qtquick-layout-grid-properties.webp b/doc/qtdesignstudio/images/qtquick-layout-grid-properties.webp new file mode 100644 index 00000000000..c50750bd6d4 Binary files /dev/null and b/doc/qtdesignstudio/images/qtquick-layout-grid-properties.webp differ diff --git a/doc/qtdesignstudio/images/qtquick-layout-in-grid-enlarged.webp b/doc/qtdesignstudio/images/qtquick-layout-in-grid-enlarged.webp new file mode 100644 index 00000000000..9228210186a Binary files /dev/null and b/doc/qtdesignstudio/images/qtquick-layout-in-grid-enlarged.webp differ diff --git a/doc/qtdesignstudio/images/qtquick-layout-in-grid.webp b/doc/qtdesignstudio/images/qtquick-layout-in-grid.webp new file mode 100644 index 00000000000..de9c49a409b Binary files /dev/null and b/doc/qtdesignstudio/images/qtquick-layout-in-grid.webp differ diff --git a/doc/qtdesignstudio/images/studio-import-3d.png b/doc/qtdesignstudio/images/studio-import-3d.png deleted file mode 100644 index 106bba5bb57..00000000000 Binary files a/doc/qtdesignstudio/images/studio-import-3d.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/studio-import-3d.webp b/doc/qtdesignstudio/images/studio-import-3d.webp new file mode 100644 index 00000000000..4dad4360afe Binary files /dev/null and b/doc/qtdesignstudio/images/studio-import-3d.webp differ diff --git a/doc/qtdesignstudio/images/studio-project-additional-files.webp b/doc/qtdesignstudio/images/studio-project-additional-files.webp new file mode 100644 index 00000000000..396c82c0d92 Binary files /dev/null and b/doc/qtdesignstudio/images/studio-project-additional-files.webp differ diff --git a/doc/qtdesignstudio/images/studio-project-files.webp b/doc/qtdesignstudio/images/studio-project-files.webp new file mode 100644 index 00000000000..091a2b32466 Binary files /dev/null and b/doc/qtdesignstudio/images/studio-project-files.webp differ diff --git a/doc/qtdesignstudio/images/studio-qmldesigner-anchors.webp b/doc/qtdesignstudio/images/studio-qmldesigner-anchors.webp new file mode 100644 index 00000000000..bd2ae3065b6 Binary files /dev/null and b/doc/qtdesignstudio/images/studio-qmldesigner-anchors.webp differ diff --git a/doc/qtdesignstudio/images/studio-slider-setup-for-stack-layout-components.webp b/doc/qtdesignstudio/images/studio-slider-setup-for-stack-layout-components.webp new file mode 100644 index 00000000000..3374c482dbc Binary files /dev/null and b/doc/qtdesignstudio/images/studio-slider-setup-for-stack-layout-components.webp differ diff --git a/doc/qtdesignstudio/images/studio-stack-layout-add-binding.webp b/doc/qtdesignstudio/images/studio-stack-layout-add-binding.webp new file mode 100644 index 00000000000..789fa589006 Binary files /dev/null and b/doc/qtdesignstudio/images/studio-stack-layout-add-binding.webp differ diff --git a/doc/qtdesignstudio/images/studio-stack-layout-binding-setup.webp b/doc/qtdesignstudio/images/studio-stack-layout-binding-setup.webp new file mode 100644 index 00000000000..1567bfe1574 Binary files /dev/null and b/doc/qtdesignstudio/images/studio-stack-layout-binding-setup.webp differ diff --git a/doc/qtdesignstudio/images/studio-stack-layout-components.webp b/doc/qtdesignstudio/images/studio-stack-layout-components.webp new file mode 100644 index 00000000000..42a06d2607a Binary files /dev/null and b/doc/qtdesignstudio/images/studio-stack-layout-components.webp differ diff --git a/doc/qtdesignstudio/images/studio-stack-layout-example-output.webp b/doc/qtdesignstudio/images/studio-stack-layout-example-output.webp new file mode 100644 index 00000000000..f36aac9fe77 Binary files /dev/null and b/doc/qtdesignstudio/images/studio-stack-layout-example-output.webp differ diff --git a/doc/qtdesignstudio/src/components/qtquick-positioning.qdoc b/doc/qtdesignstudio/src/components/qtquick-positioning.qdoc index 6c91124d697..98ea7d12264 100644 --- a/doc/qtdesignstudio/src/components/qtquick-positioning.qdoc +++ b/doc/qtdesignstudio/src/components/qtquick-positioning.qdoc @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! @@ -8,7 +8,7 @@ \title Scalable Layouts - The position of a \l{glossary-component}{component} in a UI can be either + The position of a \l{glossary-component}{component} in a UI is either absolute or relative to other components. The visual components exist at a particular location in the screen coordinate system at any instant in time. The x and y coordinates of a visual component are relative to those of its @@ -17,32 +17,46 @@ If you are designing a static UI, \l{Important Concepts In Qt Quick - Positioning#manual-positioning} {manual positioning} provides the most efficient form of positioning - components. For a dynamic UI, you can employ the following positioning + components. For a dynamic UI, use the following positioning methods: - \list - \li \l{Setting Bindings} - \li \l{Setting Anchors and Margins} - \li \l{Aligning and Distributing Components} - \li \l{Using Positioners} - \li \l{Using Layouts} - \li \l{Organizing Components} - \endlist + \table + \header + \li Action + \li Purpose + \row + \li \l{Setting Bindings} + \li To connect the properties of components. + \row + \li \l{Setting Anchors and Margins} + \li To set the rules for attaching the component to other components. You can define + the distance between the components and put margins on the components. + \row + \li \l{Aligning and Distributing Components} + \li To align the unanchored components left, right, vertical, horizontal, top, and + bottom with respect to each other. + \row + \li \l{Using Positioners} + \li To arrange components in rows, columns, grids, or flows. + \row + \li \l{Using Layouts} + \li To place the components in columns, grids, rows and stacks in layouts. + The layouts adept the nature of dynamic and resizable UI. + \row + \li \l {Organizing Components} + \li To keep the components or controls collected with frames, groups, + group boxes, pages, and panes. + \endtable \section2 Setting Bindings - \l{Positioning with Bindings}{Property binding} is a declarative way of - specifying the value of a property. Binding allows a property value to be - expressed as a JavaScript expression that defines the value relative to - other property values or data accessible in the application. The property - value is automatically kept up to date if the other properties or data - values change. + Using \e {Property Binding}, you can connect the properties of components. So, change in + one can affect another. Once the binding is set, the property value is automatically + kept up to date if the other properties or data values change. - Property bindings are created implicitly whenever a property is assigned a - JavaScript expression. To set JavaScript expressions as values of properties - in the \l Properties view: + To set \e {Property Binding} to a component property: \list 1 - \li Select the \inlineimage icons/action-icon.png + \li Go to the \uicontrol Properties view and select \inlineimage icons/action-icon.png (\uicontrol Actions) menu next to a property, and then select \uicontrol {Set Binding}. @@ -55,86 +69,83 @@ \endlist When a binding is set, the \uicontrol Actions menu icon changes to - \inlineimage icons/action-icon-binding.png - . To remove bindings, select \uicontrol Actions > \uicontrol Reset. + \inlineimage icons/action-icon-binding.png. + To remove bindings, select \uicontrol Actions > \uicontrol Reset. - You can set bindings also on the \uicontrol Bindings tab in the - \l Connections view. - For more information, see \l {Adding Bindings Between Properties}. + See \l {Adding Bindings Between Properties} to learn how to set bindings using + the \uicontrol Bindings tab in the \l Connections view. - For more information on the JavaScript environment provided, see - \l{Integrating QML and JavaScript}. - - Bindings are a black box for \QDS and using them might have a - negative impact on performance, so consider setting anchors and margins for - components, instead. For example, instead of setting \c {parent.width} for a - component, you could anchor the component to its sibling components on the + \note For better performance, set anchors and margins for binding + components. For example, instead of setting \c {parent.width} for a + component, anchor the component to its sibling components on the left and the right. \section2 Setting Anchors and Margins In an \l{Important Concepts In Qt Quick - Positioning#anchors} - {anchor-based} layout, each component can be thought of as having a set of + {anchor-based} layout, each component has a set of invisible \e anchor lines: top, bottom, left, right, fill, horizontal center, vertical center, and baseline. - In \l Properties > \uicontrol Layout, you can set anchors and margins for - components. To set the anchors of a component, click the anchor buttons. - You can combine the top/bottom, left/right, and horizontal/vertical anchors - to anchor components in the corners of the parent component or center them - horizontally or vertically within the parent component. + To set anchors and margins for components: + + \list 1 + \li Go to \l Properties > \uicontrol Layout > \uicontrol Anchors. + \li Select the corresponding button for the anchor you want for the component. + You can combine multiple anchors. For each selected button, you can + choose the target component of that anchor from the corresponding dropdown. + \li To apply fill anchors to a component, select + \inlineimage icons/anchor-fill.png (\uicontrol {Fill to Parent}). + \li To reset the anchors to their saved state, select + \inlineimage icons/qtcreator-anchors-reset-icon.png (\uicontrol {Reset Anchors}). + \endlist \image qmldesigner-anchor-buttons.png "Anchor buttons" - For convenience, you can click the \inlineimage icons/anchor-fill.png - (\uicontrol {Fill to Parent}) toolbar button to apply fill anchors to a - component and the \inlineimage icons/qtcreator-anchors-reset-icon.png - (\uicontrol {Reset Anchors}) button to reset the anchors to their saved - state. - - You can specify the baseline anchor in the \l{Code} view. - For performance reasons, you can only anchor a component to its siblings - and direct parent. By default, a component is anchored to its parent when - you use the anchor buttons. Select a sibling of the component in the - \uicontrol Target field to anchor to it instead. + or direct parent. By default, a component is anchored to its parent when + you use the anchor buttons. To anchor to a sibling of the component, select + the sibling component as \uicontrol Target. - Arbitrary anchoring is not supported. For example, you cannot specify: - \c {anchor.left: parent.right}. You have to specify: + Arbitrary anchoring is not supported. For example, don't select: + \c {anchor.left: parent.right}. Select: \c {anchor.left: parent.left}. When you use the anchor buttons, anchors to - the parent component are always specified to the same side. However, anchors - to sibling components are specified to the opposite side: + the parent component are always set to the same side. However, anchors + to sibling components are set to the opposite side: \c {anchor.left: sibling.right}. This allows you to keep sibling components together. - In the following image, the left edge of \e rectangle1 is anchored to the - right edge of the sibling on its left side, \e rectangle, while its top + In the following image, the left edge of \e rectangle2 is anchored to the + right edge of the sibling on its left side, \e rectangle1, while its top edge is anchored to the top of its parent. - \image qmldesigner-anchors.png "Anchoring sibling components" + \image studio-qmldesigner-anchors.webp "Anchoring sibling components" - The anchors are specified as follows in code: + The anchors are set as follows in code: \qml - Rectangle { - id: rectangle1 - anchors.left: rectangle.right - anchors.top: parent.top - anchors.leftMargin: 5 - anchors.topMargin: 30 - } + Rectangle { + id: rectangle2 + width: 84 + height: 84 + color: "#967de7" + anchors.left: rectangle1.right + anchors.top: parent.top + anchors.leftMargin: 51 + anchors.topMargin: 56 + } \endqml - Margins specify the amount of empty space to leave to the outside of a - component. Margins only have meaning for anchors. They do not take any + To define the empty space outside of a component, set the + \uicontrol Margin. Margins work for anchors. They do not take any effect when using layouts or absolute positioning. \section2 Aligning and Distributing Components - When you're working with a group of components, you can select them to align + For a group of components, select them to align and distribute them evenly. As the positions of the components are fixed, you cannot apply these functions to anchored components. For scalability, - you can anchor the aligned and distributed components when your design is + anchor the aligned and distributed components when your design is ready. \image qmldesigner-alignment.png "Aligning sibling components" @@ -150,12 +161,12 @@ that you select in the \uicontrol {Key object} field. The key component must be a part of the selection. - You can distribute either \e components or the \e spacing between them. + Distribute either \e components or the \e spacing between them. If the components or spacing cannot be distributed to equal pixel values - without ending up with half pixels, you receive a notification. You can - either allow \QDS to distribute components or spacing using the closest + without ending up with half pixels, you receive a notification. + Either allow \QDS to distribute components or spacing using the closest values possible or tweak your design so that the components and spacing - can be distributed perfectly. + is distributed perfectly. When distributing components, select the buttons in the \uicontrol {Distribute objects} field to determine whether the @@ -166,11 +177,11 @@ \uicontrol {Distribute spacing} field to determine whether it is distributed evenly within a target area or at specified distances, calculated from a starting point. - You can select the orientation in which the components are distributed + Select the orientation in which the components are distributed evenly within the target area: horizontally along the x axis or vertically along the y axis. - Alternatively, you can distribute spacing in pixels by selecting one of the + Alternatively, distribute spacing in pixels by selecting one of the starting point buttons: top/left or bottom/right edge of the target area or item, or its center. The edge to use depends on whether the items are distributed horizontally or vertically: @@ -193,121 +204,52 @@ \note Some components might end up outside the target area. - In the \uicontrol {Pixel spacing} field, you can set the space between - components in pixels. You can disable the distribution of spacing in - pixels by clicking the \inlineimage icons/distribute-origin-none.png + In the \uicontrol {Pixel spacing} field, set the space between + components in pixels. To disable the distribution of spacing in + pixels, click \inlineimage icons/distribute-origin-none.png button. - \section3 Summary of Aligment Buttons - - The following table summarizes the buttons available in the - \uicontrol Alignment section. - - \table - \header - \li Icon - \li Purpose - \row - \li \inlineimage icons/align-left.png - \li Aligns the left edges of the selected components to the one - farthest away from the center of the group. - \row - \li \inlineimage icons/align-center-horizontal.png - \li Aligns the horizontal centers of the selected components. - \row - \li \inlineimage icons/align-right.png - \li Aligns the right edges of the selected components. - \row - \li \inlineimage icons/align-top.png - \li Aligns the top edges of the selected components. - \row - \li \inlineimage icons/align-center-vertical.png - \li Aligns the verical centers of the selected components. - \row - \li \inlineimage icons/align-bottom.png - \li Aligns the bottom edges of the selected components. - \row - \li \inlineimage icons/distribute-left.png - \li Distributes the selected components and calculates the distance - between them from their left edges. - \row - \li \inlineimage icons/distribute-center-horizontal.png - \li Distributes the selected components and calculates the distance - between them from their horizontal centers. - \row - \li \inlineimage icons/distribute-right.png - \li Distributes the selected components and calculates the distance - between them from their right edges. - \row - \li \inlineimage icons/distribute-top.png - \li Distributes the selected components and calculates the distance - between them from their top edges. - \row - \li \inlineimage icons/distribute-center-vertical.png - \li Distributes the selected components and calculates the distance - between them from their vertical centers. - \row - \li \inlineimage icons/distribute-bottom.png - \li Distributes the selected components and calculates the distance - between them from their bottom edges. - \row - \li \inlineimage icons/distribute-spacing-horizontal.png - \li Distributes spacing between the selected components horizontally. - \row - \li \inlineimage icons/distribute-spacing-vertical.png - \li Distributes spacing between the selected components vertically. - \row - \li \inlineimage icons/distribute-origin-none.png - \li Disables the distribution of spacing in pixels. - \row - \li \inlineimage icons/distribute-origin-top-left.png - \li Sets the top or left edge of the target area or item as the - starting point for distributing spacing in pixels depending on - the distribution orientation. - \row - \li \inlineimage icons/distribute-origin-center.png - \li Sets the center of the target area as the starting point - for distributing spacing in pixels. - \row - \li \inlineimage icons/distribute-origin-bottom-right.png - \li Sets the bottom or right edge of the target area or item as the - starting point for distributing spacing in pixels, depending on - the distribution orientation. - \endtable - \section2 Using Positioners Positioner components are containers that manage the positions of their child components. For many use cases, the best positioner to use is a simple - column, row, flow, or grid. You can use the components available in + column, row, flow, or grid. Use the components available in \uicontrol Components > \uicontrol {Default Components} > \uicontrol Positioner to position the children of a component in these formations in the most efficient manner possible. - To position several components in a \uicontrol Column, \uicontrol Row, - \uicontrol Flow, or \uicontrol Grid, select the components in - the \l {2D} view, and then select \uicontrol Position in - the context menu. + To position several components in a + \uicontrol Column \inlineimage column-positioner-icon-16px.png, + \uicontrol Row \inlineimage row-positioner-icon-16px.png, + \uicontrol Grid \inlineimage grid-positioner-icon-16px.png, + or \uicontrol Flow \inlineimage flow-positioner-icon-16px.png : + + \list 1 + \li Select the components in the \l {2D} view. + \li Right-click anywhere in the \uicontrol 2D view and + select \uicontrol Positioner > \uicontrol Row, + \uicontrol Column, \uicontrol Grid or \uicontrol {Flow Positioner}. + \endlist \section3 Column Positioner A \uicontrol Column positions its child components along a single column. - It can be used as a convenient way to vertically position a series of + It is used as a convenient way to vertically position a series of components without using anchors. \image qtquick-positioner-column-properties.png "Column properties" - For all positioners, you can specify the spacing between the child - components that they contain in the \uicontrol Spacing field. + For all positioners, set the spacing between the child + components in the \uicontrol Spacing field. - In addition, you can specify the vertical and horizontal padding between - content and the left, right, top, and bottom edges of components as values - of the fields in the \l Padding section. + In addition, set the vertical and horizontal padding between + content and the left, right, top, and bottom edges of components + in the \l Padding section. \section3 Row and Flow Positioners - A \uicontrol Row positions its child components along a single row. It can - be used as a convenient way to horizontally position a series of components + A \uicontrol Row positions its child components along a single row. It is + used as a convenient way to horizontally position a series of components without using anchors. The \uicontrol Flow component positions its child components like words on a @@ -315,14 +257,14 @@ \image qtquick-positioner-flow-properties.png "Flow properties" - For flow and row positioners, you can also set the direction of a flow to + For flow and row positioners, also set the direction of a flow to either left-to-right or top-to-bottom in the \uicontrol Flow field. Components are positioned next to to each other according to the value you set in the \uicontrol {Layout direction} field until the width or height of the \uicontrol Flow component is exceeded, then wrapped to the next row or column. - You can set the layout direction to either \uicontrol LeftToRight or + Set the layout direction to either \uicontrol LeftToRight or \uicontrol RightToLeft in the \uicontrol {Layout direction} field. If the width of the row is explicitly set, the left anchor remains to the left of the row and the right anchor remains to the right of it. @@ -350,145 +292,120 @@ To also mirror the horizontal alignment of components, select \uicontrol AlignRight in the \uicontrol {Alignment H} field. - \section3 Summary of Positioners - - The following table lists the positioners that you can use to arrange - components in UIs. They are available in \uicontrol Components - > \uicontrol {Default Components} > \uicontrol Positioner. - - \table - \header - \li Icon - \li Name - \li Purpose - \row - \li \inlineimage column-positioner-icon-16px.png - \li \l[QtQuick] {Column} - \li Arranges its child components vertically. - \row - \li \inlineimage row-positioner-icon-16px.png - \li \l[QtQuick] {Row} - \li Arranges its child components horizontally. - \row - \li \inlineimage grid-positioner-icon-16px.png - \li \l[QtQuick] {Grid} - \li Arranges its child components so that they are aligned in a grid and - are not overlapping. - \row - \li \inlineimage flow-positioner-icon-16px.png - \li \l[QtQuick] {Flow} - \li Arranges its child components side by side, wrapping as necessary. - \endtable - \section2 Using Layouts - You can use the components available in \uicontrol Components + Use the components available in \uicontrol Components > \uicontrol {Qt Quick Layouts} to arrange components in UIs. Unlike positioners, layouts manage both the positions and sizes of their child components, and are therefore well suited for dynamic and resizable - UIs. However, this means that you should not specify fixed positions and + UIs. However, do not select fixed positions and sizes for the child components in the \l{2D Geometry}{Geometry - 2D} section in \l Properties, unless their implicit sizes are not satisfactory. - You can use anchors or the width and height properties of the layout itself - to specify its size in respect to its non-layout parent component. However, + Use anchors or the width and height properties of the layout itself + to select its size in respect to its non-layout parent component. However, do not anchor the child components within layouts. - To arrange several components in a column, row, grid, or - \uicontrol {Stack Layout}, select the components in the \l {2D} view, - and then select \uicontrol Layout in the context menu. + Follow the process to put components in the \uicontrol {Grid Layout}. + \list 1 + \li Select all the components and right-click on one of them. + \li From the context menu, select \uicontrol Layout > \uicontrol {Grid Layout}. + \image qtquick-layout-context-menu.webp "Grid Layout in the context-menu" + \li After you assign them to \uicontrol {Grid Layout}, the components are arranged + in rows and columns. + \image qtquick-layout-in-grid.webp "Components in grid rows and columns" - To make a component within a layout as wide as possible while respecting the - given constraints, select the component in the \uicontrol {2D} view, and - then select \uicontrol Layout > \uicontrol {Fill Width} in the context menu. - To make the component as high as possible, select \uicontrol {Fill Height}. + \endlist - \section3 Layout Properties - - A \uicontrol {Grid Layout} component provides a way of dynamically - arranging components in a grid. If the grid layout is resized, all - its child components are rearranged. If you want a layout with just - one row or one column, use the \uicontrol {Row Layout} or - \uicontrol {Column Layout} component. - - The child components of row and column layout components are automatically - positioned either horizontally from left to right as rows or vertically from - top to bottom as columns. The number of the child components determines the - width of the row or the height of the column. You can specify the spacing - between the child components in the \uicontrol Spacing field. - - The child components of grid layout components are arranged according to the - \uicontrol Flow property. When the direction of a flow is set to - \uicontrol LeftToRight, child components are positioned next to to each - other until the number of columns specified in the - \uicontrol {Columns & Rows} field is reached. Then, - the auto-positioning wraps back to the beginning of the next row. - - \image qtquick-layout-grid-properties.png "Grid Layout properties" - - If you set the direction of the flow to \uicontrol TopToBottom, child - components are auto-positioned vertically using the number of rows set - in the \uicontrol {Columns & Rows} field to determine the maximum number - of rows. - - You can set the layout direction to either \uicontrol LeftToRight or - \uicontrol RightToLeft in the \uicontrol {Layout direction} field. - When you select \uicontrol RightToLeft, the alignment of the components - will be mirrored. - - You can specify the spacing between rows and columns in the - \uicontrol Spacing field. + To make the components adept the width and height within the grid, follow these steps: + \list 1 + \li Select a \uicontrol Rectangle component in the \l {2D} view + and go to \uicontrol Layout in the \l {Properties} view. + \li In the \uicontrol {Fill layout}, select both the \uicontrol Width and + \uicontrol Height checkboxes. + \image qtquick-layout-grid-layout-properties.webp "Layout properties for the component" + \note Manipulate the \uicontrol {Row span} and the \uicontrol {Column span} + to allow the components to take more row and column spaces within the + \uicontrol {Grid Layout}. + \li Repeat the previous steps for all the \uicontrol Rectangle components. + \li Select \uicontrol {Grid Layout} in the \uicontrol Navigator view. + \li Go to \uicontrol {Geometry-2D} in the \uicontrol Properties view. In + \uicontrol Size, increase the \uicontrol Width and \uicontrol Height. + \li All the \uicontrol Rectangle components follow the change accordingly. + \image qtquick-layout-in-grid-enlarged.webp "Components follow the change in grid size" + \endlist \section3 Stack Layout - \image qtquick-designer-stacked-view.png + To stack components on top of each other you can use \uicontrol {Stack Layout}. - To add components to a \uicontrol {Stack Layout}, select the - \inlineimage icons/plus.png - button next to the component name in the \l {2D} view. - To move between components, select the \inlineimage icons/prev.png - (\uicontrol Previous) and \inlineimage icons/next.png - (\uicontrol Next) buttons. + To use \uicontrol {Stack Layout}: + \list 1 + \li Drag the \uicontrol {Stack Layout} component to the \uicontrol 2D view + or \uicontrol Navigator view. + \li Drag the components you want to stack from the \uicontrol Components view to + the \uicontrol 2D view or \uicontrol Navigator view, and place on the top of + the \uicontrol {Stack Layout} component. + \note Alternatively, you can add components to the \uicontrol {Stack Layout} by + selecting the \inlineimage icons/plus.png button next to the + \uicontrol {Stack Layout} component name in the \l {2D} view. + \li To move between components of \uicontrol {Stack Layout}, + select the \uicontrol {Stack Layout} component in the \uicontrol 2D view. Then + select the \inlineimage icons/prev.png + (\uicontrol Previous) and \inlineimage icons/next.png + (\uicontrol Next) buttons. This updates the \uicontrol {Current index} of the + \uicontrol {Stack Layout} and brings the \uicontrol {Current index} + component on top of the stack. + \note Alternatively, select the \uicontrol {Stack Layout} component, then + go to the \uicontrol Properties view > \uicontrol {Stack Layout}, and + update the \uicontrol {Current index}. The index starts from "0" (zero). - To add a tab bar to a stack layout, right-click on the - \uicontrol {Stack Layout} in \l Navigator to access the context menu, and - select \uicontrol {Stacked Container} > \uicontrol {Add Tab Bar}. + \endlist - To raise or lower the stacking order of a component, select - \uicontrol {Stacked Container} > \uicontrol {Increase Index} or - \uicontrol {Decrease Index}. + Follow the example below to understand how the \uicontrol {Stack Layout} works: - \section3 Summary of Layouts + \list 1 + \li Drag a \uicontrol {Stack Layout} from the \uicontrol Component view to + the \uicontrol Navigator or \uicontrol 2D view. + \li Drag three \uicontrol Rectangle components to the \uicontrol {Stack Layout} component + in the \uicontrol Navigator view. - The following table lists the layout components that you can use to arrange - components in UIs. They are available in \uicontrol Components - > \uicontrol {Qt Quick Layouts}. + \image studio-stack-layout-components.webp "Components in the Stack Layout" - \table - \header - \li Icon - \li Name - \li Purpose - \row - \li \inlineimage column-layouts-icon-16px.png - \li \l{ColumnLayout}{Column Layout} - \li Provides a grid layout with only one column. - \row - \li\inlineimage row-layouts-icon-16px.png - \li \l{RowLayout}{Row Layout} - \li Provides a grid layout with only one row. - \row - \li \inlineimage grid-layouts-icon-16px.png - \li \l{GridLayout}{Grid Layout} - \li Provides a way of dynamically arranging components in a grid. - \row - \li \inlineimage stack-layouts-icon-16px.png - \li \l{StackLayout}{Stack Layout} - \li Provides a stack of components where only one component is - visible at a time. - \endtable + \li Select a rectangle component and go to the \uicontrol Properties view > Rectangle > + \uicontrol {Fill color}, and change it to "#ff0000". + \li For the second rectangle, follow the previous process and change the + \uicontrol {Fill color} to "0000ff". + \li For the third rectangle, follow the previous process and change the + \uicontrol {Fill color} to "00ff00". + \li Drag a \uicontrol Slider component from the \uicontrol Components view to the + \uicontrol 2D view. + \li Select the \uicontrol Slider component and go to the \uicontrol Properties view + > \uicontrol Slider. Set the \uicontrol Value to "0", \uicontrol From to "0", + \uicontrol To to "2", and \uicontrol {Step size} to "1". + \image studio-slider-setup-for-stack-layout-components.webp "Adjusting the Slider" + + \li Go to the \uicontrol Navigator view and select the \uicontrol {Stack Layout} component. + \li Go to the \uicontrol Properties view > \uicontrol {Stack Layout}. Select + \inlineimage icons/action-icon.png to access the context menu, then select + \uicontrol {Set Binding}. + + \image studio-stack-layout-add-binding.webp "Getting the context menu to bind components" + + \li In the \uicontrol {Binding Editor}, in the left dropdown, select \uicontrol Slider; + in the right dropdown, select \uicontrol Value. Select \uicontrol OK to accept + the binding. + + \image studio-stack-layout-binding-setup.webp "Setting binding rules" + + \li Select \uicontrol {Live Preview} or \uicontrol {Run Project} to run the application. + \li Drag the slider to change the color in the rectangle. + + \image studio-stack-layout-example-output.webp "Stack Layout example output" + + \endlist \section2 Organizing Components @@ -533,4 +450,13 @@ \li Qt Quick Controls \li A background that matches the application style and theme. \endtable + + \note + \br + To access \uicontrol Frame, \uicontrol {Group Box}, \uicontrol Pane, and + \uicontrol Page controls, go to \uicontrol Components > + \uicontrol {Qt Quick Controls}. + \br + To access \uicontrol Group control, + go to \uicontrol Components > \uicontrol {Qt Quick Studio Components}. */ diff --git a/doc/qtdesignstudio/src/how-to/qtdesignstudio-live-preview-desktop.qdoc b/doc/qtdesignstudio/src/how-to/qtdesignstudio-live-preview-desktop.qdoc index 0178d7f6666..b047265f09e 100644 --- a/doc/qtdesignstudio/src/how-to/qtdesignstudio-live-preview-desktop.qdoc +++ b/doc/qtdesignstudio/src/how-to/qtdesignstudio-live-preview-desktop.qdoc @@ -43,4 +43,8 @@ \li In \uicontrol {Override device QML viewer}, select the folder where the preview tool executable is located. \endlist + + To preview the design on a device, see \l {Previewing on Devices}. + + \endif */ diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-figma-using.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-figma-using.qdoc index 22cc72105e7..3c58268c60a 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-figma-using.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-figma-using.qdoc @@ -72,7 +72,19 @@ handle, such as gradient fill colors or a mixed radius, the frames are exported as images. - + \section2 Using Variables + With \QDS 4.6, variables are exported as a QML module named \e DesignSystem. A QML singleton + is created for each collection. Modes of the collection are exported as theme objects. + A collection has a \e currentTheme property, updating the property changes the active theme. + + When a variable is bound to a property of a layer, the \e DesignSystem module import + is added to the generated code and the property binding is created accordingly. + + To export variables, select \uicontrol {Export Variables} from \l{Settings}. + + \note Remote variables are not supported. Setting the active mode on the page or + layer does not affect the generated code. + \section2 Using Variants Figma variants are exported as a component with states. All variants inside a \e component-set are merged together and the differences across @@ -241,6 +253,9 @@ \li \uicontrol {Create page hierarchy} \li Organize the generated UI in \QDS under the directory named after the parent page of the respective component. + \row + \li \uicontrol {Export Variables} + \li Enable exporting variables. \row \li \uicontrol {Reset plugin data} \li Resets all settings for all layers and groups (also in the diff --git a/doc/qtdesignstudio/src/qtdesignstudio-projects.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-projects.qdoc index 46b2ac8fbb0..02a82d02031 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-projects.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-projects.qdoc @@ -113,8 +113,8 @@ \li In \uicontrol {Target Qt Version}, select the Qt version to use for developing the application. While you can change the Qt version later in the \uicontrol {Run Settings} - of the project, keep in mind that the two versions are not fully - compatible. + of the project, as described in \l {Overriding the Preview Tool}, + keep in mind that the two versions are not fully compatible. \endlist \li In the \uicontrol {Style} tab, select one of the predefined \l{Styling Qt Quick Controls}{UI styles} to use. @@ -123,35 +123,94 @@ \QDS creates the following files and folders: - \list - \li .qmlproject project file defines that all component, JavaScript, and - image files in the project folder belong to the project. Therefore, - you do not need to individually list all the files in the project. - \li .qml file defines the functionality and appearance of a component. - \li \e Screen01.ui.qml defines a custom component that you can edit in - the \l {2D} view. For more information, see \l {UI Files}. + \image studio-project-files.webp "Qt Design Studio project files" - By default, this is the main file in the project, but you can - change that in the .qmlproject file. While the custom component - is a good starting point for new users, you don't have to use it. - Specifically, if you export and import designs using \QB, your main - file is most likely called something else. For more information, - see \l {Exporting from Design Tools}. - \li \e CMakeLists.txt project configuration file allowing you to - share your project as a fully working C++ application with - developers. - \li qtquickcontrols2.conf file specifies the preferred style and some - style-specific arguments. - \li \e fonts folder contains font files that you have added in - \uicontrol Assets. - \li \e imports folder contains a \e {Constants.qml} file that specifies - a font loader for the Arial font and the screen resolution. The size - of the default Screen.ui.qml \l{basic-rectangle}{Rectangle} should - be set as \c {width: Constants.width & height: Constants.height} so - that it inherits the global resolution saved here. - \li \e qmldir module definition file declares the Constant component. - For more information, see \l {Module Definition qmldir Files}. - \endlist + \table + \header + \li File/Folder + \li Description + \row + \li ProjectName.qmlproject + \li This file defines that all components, JavaScript, and image files in the project + folder belong to the project. Therefore, you do not need to individually list all + the files in the project. Since \QDS 4.5, the default + \l {https://doc.qt.io/qt-6/qtqml-syntax-directoryimports.html} {QML import path} + defined within the \c {.qmlproject} file is \c {"."}. However, you can add more + import paths by editing the \c {.qmlproject} file. + \row + \li \c {ProjectName} (folder) + \li This folder contains the essential QML files for the project. + \row + \li Constants.qml + \li This file defines a font loader for the Arial font and the screen resolution. + The size of the default Screen.ui.qml \l{basic-rectangle}{Rectangle} should + be set as \c {width: Constants.width & height: Constants.height} so + that it inherits the global resolution saved here. This is the default + QML singleton created by the wizard. You can add more singletons here. Afterward, + edit the qmldir file accordingly. + \row + \li EventListModel.qml + \li This file defines and triggers "Global Events" in a \QDS/QML application. + \row + \li EventListSimulator.qml + \li This file defines and triggers "Global Events" in a \QDS/QML application. + \row + \li qmldir + \li This is a module definition file that declares the Constant component. + For more information, see \l {Module Definition qmldir Files}. + \row + \li \c {ProjectNameContent} (folder) + \li This folder contains the default content, such as QML files, images, and other + necessary files. It is not considered a module in \QDS context. Do not import it + if you want to make singletons and objects. Use the ProjectName module instead. + \row + \li App.qml + \li This file defines the default dimension of the application window. + This is the entry point to QML application. + \row + \li Screen01.ui.qml + \li This file defines a custom component that you can edit in the \uicontrol {2D} view. + For more information, see \l {UI Files}. + The project wizard generates this as the first scene. + \row + \li qtquickcontrols2.conf + \li This file specifies the preferred style and style-specific arguments. + \endtable + + Depending on the assets, components, effects, and animations you use, the project might include + additional files and folders. + + \image studio-project-additional-files.webp "Qt Design Studio project files" + + \table + \header + \li File/Folder + \li Description + \row + \li \c {Generated} (folder) + \li This folder contains all the files related to + \l {https://doc.qt.io/qt-6/qtquick3d-index.html} {QtQuick3D} and the modules + for imported 3D components and elements from the content library, + such as Materials and Effects. + \row + \li \c {Bundles} (folder) + \li This folder contains imported 3D components and elements from the content library, + such as Materials. + \row + \li \c {QtQuick3D} (folder) + \li This folder contains all the files from an imported Qt Quick 3D object, such as + meshes, images, animations, and QML files. + + \row + \li \c {Effects} (folder) + \li This folder contains all the files related to the effects created with + \l {Effect Composer}. + \row + \li \c {Materials} (folder) + \li This folder contains the files related to the materials, such as images, shaders, + and QML files. + + \endtable To use JavaScript and image files in the UI, select \uicontrol Assets > \inlineimage icons/plus.png diff --git a/doc/qtdesignstudio/src/qtdesignstudio-qt-ui-viewer.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-qt-ui-viewer.qdoc index b947284d1a2..c3c8af08c92 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-qt-ui-viewer.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-qt-ui-viewer.qdoc @@ -15,6 +15,11 @@ These projects then run on your Android device. You can also adjust settings, view logs, and run example projects. + \note This feature is included in the + \l{https://www.qt.io/pricing}{Qt Design Studio Enterprise license}. + \uicontrol {Share Application Online} and \uicontrol {Deploy Project to Android} + are unavailable in \QDS without the Enterprise license. + \section1 Installing Qt UI Viewer \image qtuiviewer-appstore.webp @@ -39,6 +44,7 @@ \inlineimage menu-share-application-online.webp \inlineimage studio-share-application-online.webp + \li Open \QUV on your Android device. \li Select \uicontrol {Scan QR Code}. \image qtuiviewer-scan-qr-code.webp diff --git a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc index 6b3680de546..2584279e540 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc @@ -119,6 +119,7 @@ \li \l{Prototyping} \list \li \l{Creating UI Logic} + \li \l{Effects} \li \l{Simulating Complex Experiences} \list \li \l{Loading Placeholder Data} @@ -271,5 +272,6 @@ \endlist \li \l{Technical Support} \li \l{Acknowledgements} + \li \l{What's New} \endlist */ diff --git a/doc/qtdesignstudio/src/qtdesignstudio.qdoc b/doc/qtdesignstudio/src/qtdesignstudio.qdoc index d3a0b007d12..b4bbf9a0e78 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio.qdoc @@ -45,6 +45,7 @@ \li \b {\l{Prototyping}} \list \li \l{Creating UI Logic} + \li \l{Effects} \li \l{Simulating Complex Experiences} \li \l{Dynamic Behaviors} \li \l{Validating with Target Hardware} diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc index ff67fa14a8a..00f513e7fcf 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc @@ -364,6 +364,10 @@ \li Show Grid \li Toggles the visibility of the helper grid. \li \key G + \row + \li Show Look-at + \li Toggles the visibility of the edit camera look-at indicator. + \li \key L \row \li Show Selection Boxes \li Toggles the visibility of selection boxes for selected 3D objects. @@ -403,9 +407,12 @@ \li Select Grid Color \li Select a color for the grid. \row - \li Use Scene Environment Color - \li Sets the 3D view to use the scene environment color as background + \li Use Scene Environment + \li Sets the 3D view to use the scene environment or skybox as background color. + \note When \uicontrol {Use Scene Environment} is selected, a 3D scene that doesn't + have a \uicontrol View3D component, uses the scene environment of the previous + \uicontrol View3D for rendering the scene. \row \li Reset Colors \li Resets the background and grid colors to the default colors. diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc index 45d517a0bf4..ed33dfa04b5 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! @@ -23,42 +23,59 @@ For more information about exporting 3D graphics, see \l{Exporting 3D Assets}. - \image studio-import-3d.png + \image studio-import-3d.webp \section1 Importing a 3D Asset To import a 3D asset to a \QDS project: \list 1 - \li Drag-and-drop an external file containing the 3D asset from, - for example, File Explorer (on Windows), to the \uicontrol{3D} view. - \li In the \uicontrol {3D Scene Options} tab, select options for - importing the file. - \note To see all options, select \uicontrol{Show All Options}. - \li Select \uicontrol Import to import the 3D asset. + \li Open the import dialog in one of the following methods: + \list + \li Select \l Assets > \inlineimage icons/plus.png, select the file you + want to import, and click \uicontrol Open. + \li Drag the 3D asset to the \uicontrol 3D view. In this case, the 3D asset will be + added to your scene, so it will appear in the \uicontrol 3D and + \uicontrol Navigator views. + \endlist + \li Select \uicontrol Accept to import the 3D asset. \endlist - The 3D asset is now added to your scene, and you can see it in the - \uicontrol{3D} and \uicontrol Navigator views. It is also - available in \uicontrol Components > \uicontrol {My 3D Components}. + Additionally, you can define options for importing the file in the \uicontrol {3D Scene Options} + tab. To preview the 3D asset before importing it, rotate the preview image by dragging it. + Select \uicontrol Import to generate the 3D asset with the updated settings, and then select + \uicontrol Accept to close the import dialog. - Alternatively, you can initiate the import dialog from the - \uicontrol Assets view: + \note To see all options, select \uicontrol {Show All Options}. + + After importing the 3D asset, it is available in \uicontrol Components > \uicontrol + {My 3D Components}. + + \section1 Importing Multiple 3D Assets + + To import multiple 3D assets to a \QDS project: \list 1 - \li Select \l Assets > \inlineimage icons/plus.png - . - \li Select \uicontrol {3D Assets} in the dropdown menu to filter 3D - graphics files. - \li Select a file to import, and then select \uicontrol Open. - \li In the \uicontrol {3D Scene Options} tab, select options for - importing the file. - \note To see all options, select \uicontrol{Show All Options}. - \li Select \uicontrol Import to import the 3D asset. + \li Open the import dialog in one of the following methods: + \list + \li Select \uicontrol Assets > \inlineimage icons/plus.png, select the files you + want to import, and click \uicontrol Open. + \li Select the 3D asset files and drag them to the \uicontrol 3D view. In this + case, the 3D assets will be added to your scene, so they will appear in the + \uicontrol 3D and \uicontrol Navigator views. + \endlist + \li Select \uicontrol Accept to import the 3D assets. \endlist - The 3D asset now appears in \uicontrol Components > - \uicontrol {My 3D Components}. You can add it to the scene by - drag-and-dropping it to the \uicontrol{3D} view. + Additionally, you can define options for importing the files in the \uicontrol + {3D Scene Options} tab by selecting the asset you want to edit from the \uicontrol + {Imported objects} list. To preview the 3D asset before importing it, rotate the preview image + by dragging it. Select \uicontrol Import to generate the 3D asset with the updated settings, + and then select \uicontrol Accept to close the import dialog. + + \note To see all options, select \uicontrol {Show All Options}. + + After importing the 3D assets, they are available in \uicontrol {Components} > \uicontrol + {My 3D Components}. */ diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-loader-3d.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-loader-3d.qdoc index 209b1eba911..9f90554a1d3 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-loader-3d.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-loader-3d.qdoc @@ -8,10 +8,6 @@ \title Loader3D - \note The \uicontrol Loader3D component is released as a tech preview - feature in \QDS 2.2, and its functionality will be improved in future - releases. - \uicontrol Loader3D is a loader component used to dynamically load 3D components. It can load a QML file using the \uicontrol Source property or a component using the \uicontrol {Source component} property. \uicontrol Loader3D diff --git a/doc/qtdesignstudio/src/whats new/qds-releases.qdoc b/doc/qtdesignstudio/src/whats new/qds-releases.qdoc new file mode 100644 index 00000000000..ee792775f82 --- /dev/null +++ b/doc/qtdesignstudio/src/whats new/qds-releases.qdoc @@ -0,0 +1,68 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \previouspage studio-terms.html + \page whats-new.html + + \title What's New + + Read the \QDS release blog posts to see what's new in every version. + + \section1 \QDS Release Blog Posts + + \section2 \QDS 4 + + \list + \li \l{Qt Design Studio 4.5.1 released} + \li \l{Qt Design Studio 4.5 released} + \li \l{Qt Design Studio 4.4 released} + \li \l{Qt Design Studio 4.3.2 released} + \li \l{Qt Design Studio 4.3.1 released} + \li \l{Qt Design Studio 4.3 released} + \li \l{Qt Design Studio 4.2 released} + \li \l{Qt Design Studio 4.1 released} + \li \l{Qt Design Studio 4.0.1 released} + \li \l{Qt Design Studio 4.0 released} + \endlist + + \section2 \QDS 3 + + \list + \li \l{Qt Design Studio 3.9 released} + \li \l{Qt Design Studio 3.8 released} + \li \l{Qt Design Studio 3.7 released} + \li \l{Qt Design Studio 3.6 released} + \li \l{Qt Design Studio 3.5 released} + \li \l{Qt Design Studio 3.4 released} + \li \l{Qt Design Studio 3.3 released} + \li \l{Qt Design Studio 3.2 released} + \li \l{Qt Design Studio 3.1 released} + \li \l{Qt Design Studio 3.0 released} + \endlist + + \section2 \QDS 2 + + \list + \li \l{Qt Design Studio 2.3 released} + \li \l{Qt Design Studio 2.2 released} + \li \l{Qt Design Studio 2.1 released} + \li \l{Qt Design Studio 2.0 released} + \endlist + + \section2 \QDS 1 + + \list + \li \l{Qt Design Studio 1.6.1 released} + \li \l{Qt Design Studio 1.6 released} + \li \l{Qt Design Studio 1.5 released} + \li \l{Qt Design Studio 1.4 released} + \li \l{Qt Design Studio 1.3.1 released} + \li \l{Qt Design Studio 1.3 released} + \li \l{Qt Design Studio 1.2 released} + \li \l{Qt Design Studio 1.1.1 released} + \li \l{Qt Design Studio 1.1 released} + \li \l{Qt Design Studio 1.0 released} + \endlist + +*/ diff --git a/doc/qtdesignstudio/src/working with/effects/qtdesignstudio-effects.qdoc b/doc/qtdesignstudio/src/working with/effects/qtdesignstudio-effects.qdoc new file mode 100644 index 00000000000..6bd5ce93544 --- /dev/null +++ b/doc/qtdesignstudio/src/working with/effects/qtdesignstudio-effects.qdoc @@ -0,0 +1,55 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \previouspage studio-terms.html + \page working-with-effects.html + \nextpage best-practices.html + + \title Effects + + \QDS includes various ready-made effects that you can use in your applications. These effects + are customizable to meet your specific requirements. Alternatively, you can use your own shader + files to create a custom effect. + + The following table summarizes the available effects and their corresponding use cases. + + \table + \header + \li Effect + \li Description + \row + \li \l {Effect Composer} + \li A set of ready-made 2D, 3D, and particle effects that you can combine and customize. + Includes effects like \uicontrol {Color Overlay}, \uicontrol Rain, and \uicontrol + Swirl. + \row + \li \l {Adding an Effect to Your Project}{Content Library Effects} + \li A set of ready-made particle effects. Includes customizable effects like \uicontrol + Bubbles, \uicontrol Explosion, and \uicontrol Shockwave. + \row + \li \l {Design Effects} + \li A feature for adding 2D shadow and blur effects from the \uicontrol Properties + view. + \row + \li \l {Particles}{Particle Effects} + \li A set of ready-made particle effect components like \uicontrol Clouds, \uicontrol Dust, + and \uicontrol Steam. Includes also components for more advanced customization like + \uicontrol Attractor, \uicontrol {Scale Affector}, and \uicontrol Gravity. + \row + \li \l {3D Effects} + \li A set of ready-made 3D effect components. Includes customizable effects like \uicontrol + {Brush Strokes}, \uicontrol {Distortion Sphere}, and \uicontrol {Motion Blur}. + \row + \li \l {2D Effects} + \li A set of ready-made 2D effect components. Includes customizable effects like \uicontrol + {Brightness Control}, \uicontrol {Gamma Adjust}, and \uicontrol {Opacity Mask}. + \row + \li \l {Using Qt Quick Effect Maker Effects}{Qt Quick Effect Maker} + \li Import effects made with \QQEM to \QDS. + \row + \li \l {Custom Effects and Materials}{Custom Effects} + \li Use your own shader files to create a custom effect. + \endtable + +*/ diff --git a/qt_attributions.json b/qt_attributions.json index 93cfd169e99..37dabd8e7fc 100644 --- a/qt_attributions.json +++ b/qt_attributions.json @@ -630,5 +630,20 @@ "License": "MIT License", "LicenseFile": "share/qtcreator/lua-plugins/luatests/INSPECT-LICENSE.txt", "Copyright": "Copyright (c) 2022 Enrique García Cota" + }, + { + "Id": "zlib", + "Name": "ZLib", + "QDocModule": "qtcreator", + "QtParts": ["tools"], + "QtUsage": "Used by ZipWriter/ZipReader to support compress and uncompress operations.", + "Path": "src/libs/3rdparty/zlib", + "Description": "Zlib is a lossless data-compression library.", + "Homepage": "https://www.zlib.net", + "Version": "1.3.1", + "License": "BSD 3-Clause \"New\" or \"Revised\" License", + "LicenseFile": "src/libs/3rdparty/zlib/LICENSE", + "Copyright": "Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler" } ] + diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt index 575c0aea8ca..4c45c8f195a 100644 --- a/share/CMakeLists.txt +++ b/share/CMakeLists.txt @@ -6,17 +6,17 @@ if (NOT APPLE AND NOT WIN32) string(TIMESTAMP timestamp "%Y-%m-%d") set(DATE_ATTRIBUTE " date=\"${timestamp}\"") endif() - configure_file(metainfo/org.qt-project.qtcreator.appdata.xml.cmakein metainfo/org.qt-project.qtcreator.appdata.xml) + configure_file(metainfo/${IDE_APP_ID}.appdata.xml.cmakein metainfo/${IDE_APP_ID}.appdata.xml) install( - DIRECTORY - applications + FILES + applications/${IDE_APP_ID}.desktop DESTINATION - ${CMAKE_INSTALL_DATAROOTDIR} + ${CMAKE_INSTALL_DATAROOTDIR}/applications/ ) install( FILES - ${CMAKE_CURRENT_BINARY_DIR}/metainfo/org.qt-project.qtcreator.appdata.xml + ${CMAKE_CURRENT_BINARY_DIR}/metainfo/${IDE_APP_ID}.appdata.xml DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo/ ) diff --git a/share/applications/io.qt.qtdesignstudio.desktop b/share/applications/io.qt.qtdesignstudio.desktop new file mode 100644 index 00000000000..0c48adc6ed6 --- /dev/null +++ b/share/applications/io.qt.qtdesignstudio.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Type=Application +Exec=qtdesignstudio %F +Name=Qt Design Studio +GenericName=UI Designer for Qml applications +X-KDE-StartupNotify=true +Icon=QtProject-qtdesignstudio +StartupWMClass=org.qt-project.qtdesignstudio +Terminal=false +Categories=Development;GUIDesigner;Qt; +MimeType=application/x-qmlproject diff --git a/share/metainfo/io.qt.qtdesignstudio.appdata.xml.cmakein b/share/metainfo/io.qt.qtdesignstudio.appdata.xml.cmakein new file mode 100644 index 00000000000..53c0b29bc20 --- /dev/null +++ b/share/metainfo/io.qt.qtdesignstudio.appdata.xml.cmakein @@ -0,0 +1,63 @@ + + + + io.qt.qtdesignstudio + Qt Design Studio + + Qt Project + + UI Designer for Qml applications + CC0-1.0 + GPL-3.0 + +

    + Define the look and feel of the UI from wireframe to final implementation + with preset UI components. Import UI design files from 2D and 3D tools + to Qt Design Studio, which can turn them into code for developers. +

    +

    + Qt Design Studio prototyping features bring your designs to life and + simulate and validate interactions and dynamic behavior. +

    +

    + You can test, preview, and fine-tune your designs to pixel-perfection live + on the desktop or target device. +

    +
    + io.qt.qtdesignstudio.desktop + + https://www.qt.io/product/ui-design-tools + https://bugreports.qt.io/projects/QDS/summary + https://doc.qt.io/qtdesignstudio/ + https://codereview.qt-project.org/q/project:qt-creator/qt-creator + https://www.qt.io/community/contribute-to-qt + + Qt + + + + Overview 2D + https://www.qt.io/hs-fs/hubfs/image-png-Dec-13-2021-02-04-37-16-PM.png + + + Welcome + https://www.qt.io/hs-fs/hubfs/welcomescreen.png + + + Overview 3D + https://www.qt.io/hs-fs/hubfs/image-png-Feb-28-2022-03-08-54-80-PM.png + + + Examples + https://www.qt.io/hs-fs/hubfs/image-png-May-23-2022-12-38-02-61-PM.png + + + + + +

    Qt Design Studio ${IDE_VERSION_DISPLAY}

    +
    + https://www.qt.io/blog/qt-design-studio-${IDE_VERSION_DISPLAY}-released +
    +
    +
    diff --git a/share/metainfo/org.qt-project.qtcreator.appdata.xml.cmakein b/share/metainfo/org.qt-project.qtcreator.appdata.xml.cmakein index c7f4c18cf63..52e415e2a9d 100644 --- a/share/metainfo/org.qt-project.qtcreator.appdata.xml.cmakein +++ b/share/metainfo/org.qt-project.qtcreator.appdata.xml.cmakein @@ -1,7 +1,7 @@ - org.qt-project.qtcreator.desktop + org.qt-project.qtcreator Qt Creator Qt Project @@ -28,7 +28,13 @@ org.qt-project.qtcreator.desktop - https://www.qt.io/ide/ + https://www.qt.io/product/development-tools + https://bugreports.qt.io/projects/QTCREATORBUG/summary + https://doc.qt.io/qtcreator + https://lists.qt-project.org/listinfo/qt-creator + https://codereview.qt-project.org/q/project:qt-creator/qt-creator + https://www.qt.io/community/contribute-to-qt + Qt diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml index 26a1f6acd99..bb59e197442 100644 --- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml +++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml @@ -315,7 +315,7 @@ TreeViewDelegate { id: thumbnailImage visible: !root.__isDirectory y: StudioTheme.Values.border - x: root.depth * root.indentation + StudioTheme.Values.border + x: bg.x width: 48 height: 48 cache: false diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsView.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsView.qml index aeabc92c6d4..8513c29a298 100644 --- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsView.qml +++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsView.qml @@ -479,6 +479,6 @@ TreeView { delegate: AssetDelegate { assetsView: root assetsRoot: root.assetsRoot - indentation: 5 + indentation: 10 } } // TreeView diff --git a/share/qtcreator/qmldesigner/contentLibraryImages/camera.png b/share/qtcreator/qmldesigner/contentLibraryImages/camera.png new file mode 100644 index 00000000000..bc76845fb00 Binary files /dev/null and b/share/qtcreator/qmldesigner/contentLibraryImages/camera.png differ diff --git a/share/qtcreator/qmldesigner/contentLibraryImages/light.png b/share/qtcreator/qmldesigner/contentLibraryImages/light.png new file mode 100644 index 00000000000..441ac86ae2e Binary files /dev/null and b/share/qtcreator/qmldesigner/contentLibraryImages/light.png differ diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml index d3eb29563d2..94de88fc138 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml @@ -235,7 +235,6 @@ Item { cellWidth: root.thumbnailSize cellHeight: root.thumbnailSize + 20 numColumns: root.numColumns - hideHorizontalScrollBar: true searchBox: searchBox diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectsView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectsView.qml index 199f784db18..e373f3c1aa4 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectsView.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectsView.qml @@ -96,6 +96,7 @@ HelperWidgets.ScrollView { height: root.cellHeight onShowContextMenu: ctxMenu.popupMenu(modelData) + onAddToProject: ContentLibraryBackend.effectsModel.addInstance(modelData) } onCountChanged: root.assignMaxCount() @@ -107,12 +108,12 @@ HelperWidgets.ScrollView { Text { id: infoText text: { - if (!ContentLibraryBackend.effectsModel.bundleExists) - qsTr("No effects available.") - else if (!ContentLibraryBackend.rootView.isQt6Project) + if (!ContentLibraryBackend.rootView.isQt6Project) qsTr("Content Library effects are not supported in Qt5 projects.") else if (!ContentLibraryBackend.rootView.hasQuick3DImport) qsTr("To use Content Library, first add the QtQuick3D module in the Components view.") + else if (!ContentLibraryBackend.effectsModel.bundleExists) + qsTr("No effects available.") else if (!ContentLibraryBackend.effectsModel.hasRequiredQuick3DImport) qsTr("To use Content Library, version 6.4 or later of the QtQuick3D module is required.") else if (!ContentLibraryBackend.rootView.hasMaterialLibrary) diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryItem.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryItem.qml index e6e5cd05c30..4eb05141221 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryItem.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryItem.qml @@ -2,9 +2,8 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 import QtQuick -import QtQuick.Layouts -import HelperWidgets import QtQuick.Controls +import HelperWidgets as HelperWidgets import StudioTheme as StudioTheme import ContentLibraryBackend @@ -12,18 +11,20 @@ Item { id: root signal showContextMenu() + signal addToProject() visible: modelData.bundleItemVisible MouseArea { id: mouseArea + enabled: !ContentLibraryBackend.rootView.importerRunning hoverEnabled: true anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton onPressed: (mouse) => { - if (mouse.button === Qt.LeftButton && !ContentLibraryBackend.rootView.importerRunning) + if (mouse.button === Qt.LeftButton) ContentLibraryBackend.rootView.startDragItem(modelData, mapToGlobal(mouse.x, mouse.y)) else if (mouse.button === Qt.RightButton) root.showContextMenu() @@ -67,6 +68,26 @@ Item { hoverEnabled: true } } + + HelperWidgets.IconButton { + id: addToProjectButton + + icon: StudioTheme.Constants.plus + tooltip: qsTr("Add an instance to project") + buttonSize: 22 + property color c: "white" + normalColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .2) + hoverColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .3) + pressColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .4) + anchors.right: img.right + anchors.bottom: img.bottom + enabled: !ContentLibraryBackend.rootView.importerRunning + visible: containsMouse || mouseArea.containsMouse + + onClicked: { + root.addToProject() + } + } } Text { diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryItemContextMenu.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryItemContextMenu.qml index 6f505124300..6c1b3717326 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryItemContextMenu.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryItemContextMenu.qml @@ -10,7 +10,8 @@ StudioControls.Menu { id: root property var targetItem: null - property bool enableRemove: false // true: adds an option to remove targetItem + property bool showRemoveAction: false // true: adds an option to remove targetItem + property bool showImportAction: false // true: adds an option to import a bundle from file readonly property bool targetAvailable: targetItem && !ContentLibraryBackend.rootView.importerRunning @@ -18,12 +19,15 @@ StudioControls.Menu { signal addToProject() signal applyToSelected(bool add) signal removeFromContentLib() + signal importBundle() function popupMenu(item = null) { root.targetItem = item - let isMaterial = root.targetItem.itemType === "material" + let isMaterial = item && (root.targetItem.bundleId === "UserMaterials" + || root.targetItem.bundleId === "MaterialBundle" + || root.targetItem.bundleId === "Materials") applyToSelectedReplace.visible = isMaterial applyToSelectedAdd.visible = isMaterial @@ -64,8 +68,15 @@ StudioControls.Menu { StudioControls.MenuItem { text: qsTr("Remove from Content Library") - visible: root.enableRemove && root.targetAvailable + visible: root.showRemoveAction && root.targetAvailable height: visible ? implicitHeight : 0 onTriggered: root.removeFromContentLib() } + + StudioControls.MenuItem { + text: qsTr("Import bundle") + visible: root.showImportAction + height: visible ? implicitHeight : 0 + onTriggered: root.importBundle() + } } diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterial.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterial.qml index 20ba17d8041..1136f653eae 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterial.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterial.qml @@ -3,8 +3,7 @@ import QtQuick import QtQuick.Controls -import QtQuick.Layouts -import HelperWidgets +import HelperWidgets as HelperWidgets import StudioTheme as StudioTheme import ContentLibraryBackend import WebFetcher @@ -12,9 +11,9 @@ import WebFetcher Item { id: root - // Download states: "" (ie default, not downloaded), "unavailable", "downloading", "downloaded", - // "failed" - property string downloadState: modelData.isDownloaded() ? "downloaded" : "" + // Download states: "" (exists not downloaded), "unavailable", "downloading", "downloaded", "failed" + property string downloadState: ContentLibraryBackend.materialsModel.isMaterialDownloaded(modelData) + ? "downloaded" : "" signal showContextMenu() signal addToProject() @@ -24,18 +23,16 @@ Item { MouseArea { id: mouseArea - enabled: root.downloadState !== "downloading" + enabled: !ContentLibraryBackend.rootView.importerRunning && root.downloadState == "downloaded" hoverEnabled: true anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton onPressed: (mouse) => { - if (mouse.button === Qt.LeftButton && !ContentLibraryBackend.rootView.importerRunning) { - if (root.downloadState === "downloaded") - ContentLibraryBackend.rootView.startDragMaterial(modelData, mapToGlobal(mouse.x, mouse.y)) - } else if (mouse.button === Qt.RightButton && root.downloadState === "downloaded") { + if (mouse.button === Qt.LeftButton) + ContentLibraryBackend.rootView.startDragMaterial(modelData, mapToGlobal(mouse.x, mouse.y)) + else if (mouse.button === Qt.RightButton) root.showContextMenu() - } } } @@ -87,7 +84,7 @@ Item { } } - IconButton { + HelperWidgets.IconButton { icon: StudioTheme.Constants.plus tooltip: qsTr("Add an instance to project") buttonSize: 22 @@ -106,7 +103,7 @@ Item { } } - IconButton { + HelperWidgets.IconButton { id: downloadIcon icon: root.downloadState === "unavailable" ? StudioTheme.Constants.downloadUnavailable @@ -181,10 +178,10 @@ Item { MultiFileDownloader { id: downloader - baseUrl: modelData.bundleMaterialBaseWebUrl + baseUrl: ContentLibraryBackend.materialsModel.baseWebUrl files: modelData.bundleMaterialFiles - targetDirPath: modelData.bundleMaterialDirPath + targetDirPath: ContentLibraryBackend.materialsModel.bundlePath onDownloadStarting: { root.downloadState = "downloading" diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialsView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialsView.qml index e9fca319736..89860232867 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialsView.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialsView.qml @@ -113,9 +113,7 @@ HelperWidgets.ScrollView { Text { id: infoText text: { - if (!root.materialsModel.matBundleExists) - qsTr("No materials available. Make sure you have internet connection.") - else if (!ContentLibraryBackend.rootView.isQt6Project) + if (!ContentLibraryBackend.rootView.isQt6Project) qsTr("Content Library materials are not supported in Qt5 projects.") else if (!ContentLibraryBackend.rootView.hasQuick3DImport) qsTr("To use Content Library, first add the QtQuick3D module in the Components view.") @@ -123,6 +121,8 @@ HelperWidgets.ScrollView { qsTr("To use Content Library, version 6.3 or later of the QtQuick3D module is required.") else if (!ContentLibraryBackend.rootView.hasMaterialLibrary) qsTr("Content Library is disabled inside a non-visual component.") + else if (!root.materialsModel.matBundleExists) + qsTr("No materials available. Make sure you have internet connection.") else if (!searchBox.isEmpty()) qsTr("No match found.") else diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml index b1f690f10c9..3dba67243fe 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml @@ -12,7 +12,7 @@ StudioControls.Menu { property var targetTexture: null property bool hasSceneEnv: false - property bool enableRemove: false // true: adds an option to remove targetTexture + property bool showRemoveAction: false // true: adds an option to remove targetTexture property bool canUse3D: targetTexture && ContentLibraryBackend.rootView.hasQuick3DImport && ContentLibraryBackend.rootView.hasMaterialLibrary @@ -45,7 +45,7 @@ StudioControls.Menu { StudioControls.MenuItem { text: qsTr("Remove from Content Library") - visible: root.targetTexture && root.enableRemove + visible: root.targetTexture && root.showRemoveAction height: visible ? implicitHeight : 0 onTriggered: ContentLibraryBackend.userModel.removeTexture(root.targetTexture) } diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml index cced9e5f095..7d8c990052d 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryUserView.qml @@ -8,12 +8,10 @@ import StudioControls as StudioControls import StudioTheme as StudioTheme import ContentLibraryBackend -HelperWidgets.ScrollView { +Item { id: root - clip: true - interactive: !ctxMenuItem.opened && !ctxMenuTexture.opened - && !ContentLibraryBackend.rootView.isDragging && !HelperWidgets.Controller.contextMenuOpened + property alias adsFocus: scrollView.adsFocus property real cellWidth: 100 property real cellHeight: 120 @@ -46,125 +44,154 @@ HelperWidgets.ScrollView { } } - Column { - ContentLibraryItemContextMenu { - id: ctxMenuItem + ContentLibraryItemContextMenu { + id: ctxMenuItem - enableRemove: true + showRemoveAction: true + showImportAction: true - onApplyToSelected: (add) => ContentLibraryBackend.userModel.applyToSelected(ctxMenuItem.targetItem, add) + onApplyToSelected: (add) => ContentLibraryBackend.userModel.applyToSelected(ctxMenuItem.targetItem, add) - onUnimport: root.unimport(ctxMenuItem.targetItem) - onAddToProject: ContentLibraryBackend.userModel.addToProject(ctxMenuItem.targetItem) - onRemoveFromContentLib: root.removeFromContentLib(ctxMenuItem.targetItem) + onUnimport: root.unimport(ctxMenuItem.targetItem) + onAddToProject: ContentLibraryBackend.userModel.addToProject(ctxMenuItem.targetItem) + onRemoveFromContentLib: root.removeFromContentLib(ctxMenuItem.targetItem) + onImportBundle: ContentLibraryBackend.rootView.importBundle(); + } + + ContentLibraryTextureContextMenu { + id: ctxMenuTexture + + showRemoveAction: true + hasSceneEnv: ContentLibraryBackend.texturesModel.hasSceneEnv + } + + MouseArea { + id: rootMouseArea + + anchors.fill: parent + acceptedButtons: Qt.RightButton + enabled: ContentLibraryBackend.rootView.isQt6Project + && ContentLibraryBackend.rootView.hasQuick3DImport + && ContentLibraryBackend.rootView.hasMaterialLibrary + + onClicked: (mouse) => { + ctxMenuItem.popupMenu() } + } - ContentLibraryTextureContextMenu { - id: ctxMenuTexture + HelperWidgets.ScrollView { + id: scrollView + anchors.fill: parent - enableRemove: true - hasSceneEnv: ContentLibraryBackend.texturesModel.hasSceneEnv - } + clip: true + interactive: !ctxMenuItem.opened && !ctxMenuTexture.opened + && !ContentLibraryBackend.rootView.isDragging && !HelperWidgets.Controller.contextMenuOpened + hideHorizontalScrollBar: true - Repeater { - id: categoryRepeater + Column { + Repeater { + id: categoryRepeater - model: ContentLibraryBackend.userModel + model: ContentLibraryBackend.userModel - delegate: HelperWidgets.Section { - id: section + delegate: HelperWidgets.Section { + id: section - width: root.width - leftPadding: StudioTheme.Values.sectionPadding - rightPadding: StudioTheme.Values.sectionPadding - topPadding: StudioTheme.Values.sectionPadding - bottomPadding: StudioTheme.Values.sectionPadding + width: root.width + leftPadding: StudioTheme.Values.sectionPadding + rightPadding: StudioTheme.Values.sectionPadding + topPadding: StudioTheme.Values.sectionPadding + bottomPadding: StudioTheme.Values.sectionPadding - caption: categoryName - visible: categoryVisible && infoText.text === "" - category: "ContentLib_User" + caption: categoryTitle + visible: !categoryEmpty && infoText.text === "" + category: "ContentLib_User" - function expandSection() { - section.expanded = true - } + function expandSection() { + section.expanded = true + } - property alias count: repeater.count + property alias count: repeater.count - onCountChanged: root.assignMaxCount() + onCountChanged: root.assignMaxCount() - Grid { - width: section.width - section.leftPadding - section.rightPadding - spacing: StudioTheme.Values.sectionGridSpacing - columns: root.numColumns + Grid { + width: section.width - section.leftPadding - section.rightPadding + spacing: StudioTheme.Values.sectionGridSpacing + columns: root.numColumns - Repeater { - id: repeater - model: categoryItems + Repeater { + id: repeater + model: categoryItems - delegate: DelegateChooser { - role: "itemType" + delegate: DelegateChooser { + role: "bundleId" - DelegateChoice { - roleValue: "material" - ContentLibraryMaterial { - width: root.cellWidth - height: root.cellHeight + DelegateChoice { + roleValue: "UserMaterials" + ContentLibraryItem { + width: root.cellWidth + height: root.cellHeight - onShowContextMenu: ctxMenuItem.popupMenu(modelData) - onAddToProject: ContentLibraryBackend.userModel.addToProject(modelData) + onShowContextMenu: ctxMenuItem.popupMenu(modelData) + onAddToProject: ContentLibraryBackend.userModel.addToProject(modelData) + } + } + DelegateChoice { + roleValue: "UserTextures" + delegate: ContentLibraryTexture { + width: root.cellWidth + height: root.cellWidth // for textures use a square size since there is no name row + + onShowContextMenu: ctxMenuTexture.popupMenu(modelData) + } + } + DelegateChoice { + roleValue: "User3D" + delegate: ContentLibraryItem { + width: root.cellWidth + height: root.cellHeight + + onShowContextMenu: ctxMenuItem.popupMenu(modelData) + onAddToProject: ContentLibraryBackend.userModel.addToProject(modelData) + } } } - DelegateChoice { - roleValue: "texture" - delegate: ContentLibraryTexture { - width: root.cellWidth - height: root.cellWidth // for textures use a square size since there is no name row - onShowContextMenu: ctxMenuTexture.popupMenu(modelData) - } - } - DelegateChoice { - roleValue: "item" - delegate: ContentLibraryItem { - width: root.cellWidth - height: root.cellHeight - - onShowContextMenu: ctxMenuItem.popupMenu(modelData) - } - } + onCountChanged: root.assignMaxCount() } + } - onCountChanged: root.assignMaxCount() + Text { + text: qsTr("No match found."); + color: StudioTheme.Values.themeTextColor + font.pixelSize: StudioTheme.Values.baseFontSize + leftPadding: 10 + visible: infoText.text === "" && !searchBox.isEmpty() && categoryNoMatch } } + } - Text { - text: qsTr("No match found."); - color: StudioTheme.Values.themeTextColor - font.pixelSize: StudioTheme.Values.baseFontSize - leftPadding: 10 - visible: infoText.text === "" && !searchBox.isEmpty() && categoryNoMatch + Text { + id: infoText + text: { + if (!ContentLibraryBackend.rootView.isQt6Project) + qsTr("Content Library is not supported in Qt5 projects.") + else if (!ContentLibraryBackend.rootView.hasQuick3DImport) + qsTr("To use Content Library, first add the QtQuick3D module in the Components view.") + else if (!ContentLibraryBackend.rootView.hasMaterialLibrary) + qsTr("Content Library is disabled inside a non-visual component.") + else if (ContentLibraryBackend.userModel.isEmpty) + qsTr("There are no user assets in the Content Library.") + else + "" } + color: StudioTheme.Values.themeTextColor + font.pixelSize: StudioTheme.Values.baseFontSize + topPadding: 10 + leftPadding: 10 + visible: infoText.text !== "" } } - - Text { - id: infoText - text: { - if (!ContentLibraryBackend.rootView.isQt6Project) - qsTr("Content Library is not supported in Qt5 projects.") - else if (!ContentLibraryBackend.rootView.hasQuick3DImport) - qsTr("To use Content Library, first add the QtQuick3D module in the Components view.") - else if (!ContentLibraryBackend.rootView.hasMaterialLibrary) - qsTr("Content Library is disabled inside a non-visual component.") - else - "" - } - color: StudioTheme.Values.themeTextColor - font.pixelSize: StudioTheme.Values.baseFontSize - topPadding: 10 - leftPadding: 10 - visible: infoText.text !== "" - } } } diff --git a/share/qtcreator/qmldesigner/edit3dQmlSource/CameraSpeedConfigurationDialog.qml b/share/qtcreator/qmldesigner/edit3dQmlSource/CameraSpeedConfigurationDialog.qml index b51369ffa3f..a1fb4f9fe74 100644 --- a/share/qtcreator/qmldesigner/edit3dQmlSource/CameraSpeedConfigurationDialog.qml +++ b/share/qtcreator/qmldesigner/edit3dQmlSource/CameraSpeedConfigurationDialog.qml @@ -12,9 +12,10 @@ Rectangle { id: root property int toolTipDelay: 1000 + property bool qdsTrusted: isQDSTrusted() width: 260 - height: 150 + height: root.qdsTrusted ? 150 : 210 color: StudioTheme.Values.themePanelBackground border.color: StudioTheme.Values.themeControlOutline border.width: StudioTheme.Values.border @@ -151,6 +152,43 @@ Rectangle { onClicked: resetDefaults() } } + + Rectangle { + visible: !root.qdsTrusted + color: "transparent" + border.color: StudioTheme.Values.themeWarning + Layout.fillWidth: true + Layout.fillHeight: true + + RowLayout { + anchors.fill: parent + + HelperWidgets.IconLabel { + icon: StudioTheme.Constants.warning_medium + pixelSize: StudioTheme.Values.mediumIconFontSize + Layout.leftMargin: 10 + } + + Text { + text: qsTr('

    You only have partial control in fly mode. For full control, please + enable the Accessibility settings

    ') + + color: StudioTheme.Values.themeTextColor + wrapMode: Text.WordWrap + Layout.fillWidth: true + Layout.margins: 6 + textFormat: Text.RichText + + MouseArea { + anchors.fill: parent + onClicked: { + Qt.openUrlExternally("x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility") + accessibilityOpened() + } + } + } + } + } } } } diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml index 305bbc7925c..b327c1049d3 100644 --- a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml @@ -130,8 +130,8 @@ ColumnLayout { orientation: root.width > root.height ? Qt.Horizontal : Qt.Vertical handle: Rectangle { - implicitWidth: splitView.orientation === Qt.Horizontal ? 6 : splitView.width - implicitHeight: splitView.orientation === Qt.Horizontal ? splitView.height : 6 + implicitWidth: splitView.orientation === Qt.Horizontal ? StudioTheme.Values.splitterThickness : splitView.width + implicitHeight: splitView.orientation === Qt.Horizontal ? splitView.height : StudioTheme.Values.splitterThickness color: T.SplitHandle.pressed ? StudioTheme.Values.themeSliderHandleInteraction : (T.SplitHandle.hovered ? StudioTheme.Values.themeSliderHandleHover : "transparent") diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml index d84570b434f..987934e295f 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -273,15 +273,17 @@ Item { function ensureVisible(yPos, itemHeight) { let currentY = contentYBehavior.targetValue && scrollViewAnim.running ? contentYBehavior.targetValue : scrollView.contentY + let itemHeightAdj = (itemHeight - scrollView.height + 8) + let lessThanItemSpace = itemHeightAdj >= 0 - if (currentY > yPos) { + if (currentY > yPos || lessThanItemSpace) { if (yPos < itemHeight) scrollView.contentY = 0 else scrollView.contentY = yPos - return true + return !lessThanItemSpace } else { - let adjustedY = yPos + itemHeight - scrollView.height + 8 + let adjustedY = yPos + itemHeightAdj if (currentY < adjustedY) { if (scrollView.contentHeight - scrollView.height < adjustedY ) scrollView.contentY = scrollView.contentHeight - scrollView.height diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml index 248e07bf6c4..02ee76cd099 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml @@ -134,4 +134,17 @@ StudioControls.Menu { onTriggered: MaterialBrowserBackend.rootView.addMaterialToContentLibrary() } + + StudioControls.MenuItem { + text: qsTr("Import Material") + + onTriggered: MaterialBrowserBackend.rootView.importMaterial() + } + + StudioControls.MenuItem { + text: qsTr("Export Material") + enabled: !materialBrowserModel.selectedMaterialIsComponent // TODO: support component materials + + onTriggered: MaterialBrowserBackend.rootView.exportMaterial() + } } diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserItemName.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserItemName.qml index 18dbd3b1945..eb599fa0c3b 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserItemName.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserItemName.qml @@ -23,7 +23,7 @@ TextInput { selectedTextColor: StudioTheme.Values.themeTextSelectedTextColor // allow only alphanumeric characters, underscores, no space at start, and 1 space between words - validator: RegExpValidator { regExp: /^(\w+\s)*\w+$/ } + validator: RegularExpressionValidator { regularExpression: /^(\w+\s)*\w+$/ } signal renamed(string newName) signal clicked() diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml index 5ed132461b3..19f656e51e5 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml @@ -16,7 +16,7 @@ Item { signal showContextMenu() function forceFinishEditing() { - txtId.commitRename() + txtName.commitRename() } MouseArea { @@ -76,14 +76,14 @@ Item { } MaterialBrowserItemName { - id: txtId + id: txtName - text: textureId + text: textureName width: img.width anchors.horizontalCenter: parent.horizontalCenter - onRenamed: (newId) => { - MaterialBrowserBackend.materialBrowserTexturesModel.setTextureId(index, newId); + onRenamed: (newName) => { + MaterialBrowserBackend.materialBrowserTexturesModel.setTextureName(index, newName); mouseArea.forceActiveFocus() } diff --git a/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPane.qml b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPane.qml index 0ab7e59d01f..5010017f2b0 100644 --- a/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPane.qml +++ b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPane.qml @@ -2,11 +2,17 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 import QtQuick +import QtQuick.Controls +import QtCore import HelperWidgets +import StudioControls 1.0 as StudioControls Item { id: root + property string __previewEnv + property string __previewModel + width: 420 height: 420 @@ -15,23 +21,18 @@ Item { signal previewModelChanged(string model) // invoked from C++ to refresh material preview image - function refreshPreview() - { - itemPane.headerItem.refreshPreview() - } + signal refreshPreview() // Called from C++ to close context menu on focus out function closeContextMenu() { - itemPane.headerItem.closeContextMenu() Controller.closeContextMenu() } // Called from C++ to initialize preview menu checkmarks - function initPreviewData(env, model) - { - itemPane.headerItem.previewEnv = env - itemPane.headerItem.previewModel = model + function initPreviewData(env, model) { + root.__previewEnv = env + root.__previewModel = model } MaterialEditorToolBar { @@ -42,50 +43,109 @@ Item { onToolBarAction: (action) => root.toolBarAction(action) } - PropertyEditorPane { - id: itemPane + Settings { + id: settings + + property var topSection + property bool dockMode + } + + StudioControls.SplitView { + id: splitView + + readonly property bool isHorizontal: splitView.orientation == Qt.Horizontal anchors.top: toolbar.bottom anchors.bottom: parent.bottom width: parent.width - + orientation: splitView.width > 1000 ? Qt.Horizontal : Qt.Vertical clip: true - headerComponent: MaterialEditorTopSection { - onPreviewEnvChanged: root.previewEnvChanged(previewEnv) - onPreviewModelChanged: root.previewModelChanged(previewModel) - } - - DynamicPropertiesSection { - propertiesModel: MaterialEditorDynamicPropertiesModel {} - } - Loader { - id: specificsTwo + id: leftSideView - property string theSource: specificQmlData + SplitView.fillWidth: leftSideView.visible + SplitView.fillHeight: leftSideView.visible + SplitView.minimumWidth: leftSideView.visible ? 300 : 0 + SplitView.minimumHeight: leftSideView.visible ? 300 : 0 - width: parent.width - visible: specificsTwo.theSource !== "" - sourceComponent: specificQmlComponent + active: splitView.isHorizontal + visible: leftSideView.active && leftSideView.item - onTheSourceChanged: { - specificsTwo.active = false - specificsTwo.active = true + sourceComponent: PreviewComponent {} + } + + PropertyEditorPane { + id: itemPane + + clip: true + SplitView.fillWidth: !leftSideView.visible + SplitView.fillHeight: true + SplitView.minimumWidth: leftSideView.visible ? 400 : 0 + SplitView.maximumWidth: leftSideView.visible ? 800 : -1 + + headerDocked: !leftSideView.visible && settings.dockMode + + headerComponent: MaterialEditorTopSection { + id: topSection + + Component.onCompleted: topSection.restoreState(settings.topSection) + Component.onDestruction: settings.topSection = topSection.saveState() + previewComponent: PreviewComponent {} + showImage: !splitView.isHorizontal + } + + DynamicPropertiesSection { + propertiesModel: MaterialEditorDynamicPropertiesModel {} + } + + Loader { + id: specificsTwo + + property string theSource: specificQmlData + + width: itemPane.width + visible: specificsTwo.theSource !== "" + sourceComponent: specificQmlComponent + + onTheSourceChanged: { + specificsTwo.active = false + specificsTwo.active = true + } + } + + Item { // spacer + width: 1 + height: 10 + visible: specificsTwo.visible + } + + Loader { + id: specificsOne + width: itemPane.width + source: specificsUrl } } + } - Item { // spacer - width: 1 - height: 10 - visible: specificsTwo.visible - } + component PreviewComponent : MaterialEditorPreview { + id: previewItem - Loader { - id: specificsOne - anchors.left: parent.left - anchors.right: parent.right - source: specificsUrl + onPreviewEnvChanged: root.previewEnvChanged(previewEnv) + onPreviewModelChanged: root.previewModelChanged(previewModel) + + previewEnv: root.__previewEnv + previewModel: root.__previewModel + pinned: settings.dockMode + showPinButton: !leftSideView.visible + onPinnedChanged: settings.dockMode = previewItem.pinned + + Connections { + target: root + + function onRefreshPreview() { + previewItem.refreshPreview() + } } } } diff --git a/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPreview.qml b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPreview.qml new file mode 100644 index 00000000000..fe95e33d900 --- /dev/null +++ b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPreview.qml @@ -0,0 +1,185 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import HelperWidgets as HelperWidgets +import StudioControls as StudioControls +import StudioTheme as StudioTheme + +Rectangle { + id: root + + property string previewEnv + property string previewModel + property alias pinned: pinButton.checked + property alias showPinButton: pinButton.visible + + property StudioTheme.ControlStyle buttonStyle: StudioTheme.ViewBarButtonStyle { + // This is how you can override stuff from the control styles + baseIconFontSize: StudioTheme.Values.bigIconFontSize + } + + Connections { + target: HelperWidgets.Controller + + function onCloseContextMenu() { + root.closeContextMenu() + } + } + + implicitHeight: image.height + + clip: true + color: "#000000" + + // Called from C++ to close context menu on focus out + function closeContextMenu() + { + modelMenu.close() + envMenu.close() + } + + function refreshPreview() + { + image.source = "" + image.source = "image://materialEditor/preview" + } + + Image { + id: image + + anchors.fill: parent + fillMode: Image.PreserveAspectFit + + source: "image://materialEditor/preview" + cache: false + smooth: true + + sourceSize.width: image.width + sourceSize.height: image.height + + Rectangle { + id: toolbarRect + + radius: 10 + color: StudioTheme.Values.themeToolbarBackground + width: optionsToolbar.width + 2 * toolbarRect.radius + height: optionsToolbar.height + toolbarRect.radius + anchors.left: parent.left + anchors.leftMargin: -toolbarRect.radius + anchors.verticalCenter: parent.verticalCenter + + Column { + id: optionsToolbar + + spacing: 5 + anchors.centerIn: parent + anchors.horizontalCenterOffset: optionsToolbar.spacing + + HelperWidgets.AbstractButton { + id: pinButton + + style: root.buttonStyle + buttonIcon: pinButton.checked ? StudioTheme.Constants.pin : StudioTheme.Constants.unpin + checkable: true + } + + HelperWidgets.AbstractButton { + id: previewEnvMenuButton + + style: root.buttonStyle + buttonIcon: StudioTheme.Constants.textures_medium + tooltip: qsTr("Select preview environment.") + onClicked: envMenu.popup() + } + + HelperWidgets.AbstractButton { + id: previewModelMenuButton + + style: root.buttonStyle + buttonIcon: StudioTheme.Constants.cube_medium + tooltip: qsTr("Select preview model.") + onClicked: modelMenu.popup() + } + } + } + } + + StudioControls.Menu { + id: modelMenu + closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside + + ListModel { + id: modelMenuModel + ListElement { + modelName: qsTr("Cone") + modelStr: "#Cone" + } + ListElement { + modelName: qsTr("Cube") + modelStr: "#Cube" + } + ListElement { + modelName: qsTr("Cylinder") + modelStr: "#Cylinder" + } + ListElement { + modelName: qsTr("Sphere") + modelStr: "#Sphere" + } + } + + Repeater { + model: modelMenuModel + StudioControls.MenuItemWithIcon { + text: modelName + onClicked: { + // Force property change notifications to keep check mark when reselected + root.previewModel = "" + root.previewModel = modelStr + } + checkable: true + checked: root.previewModel === modelStr + } + } + } + + StudioControls.Menu { + id: envMenu + closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside + + ListModel { + id: envMenuModel + ListElement { + envName: qsTr("Basic") + envStr: "Basic" + } + ListElement { + envName: qsTr("Color") + envStr: "Color" + } + ListElement { + envName: qsTr("Studio") + envStr: "SkyBox=preview_studio" + } + ListElement { + envName: qsTr("Landscape") + envStr: "SkyBox=preview_landscape" + } + } + + Repeater { + model: envMenuModel + StudioControls.MenuItemWithIcon { + text: envName + onClicked: { + // Force property change notifications to keep check mark when reselected + root.previewEnv = "" + root.previewEnv = envStr + } + checkable: true + checked: root.previewEnv === envStr + } + } + } +} diff --git a/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorTopSection.qml b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorTopSection.qml index d60c98933b6..e4aa7515635 100644 --- a/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorTopSection.qml +++ b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorTopSection.qml @@ -8,184 +8,40 @@ import HelperWidgets as HelperWidgets import StudioControls as StudioControls import StudioTheme as StudioTheme -Column { +StudioControls.SplitView { id: root - property string previewEnv - property string previewModel + property alias showImage: previewLoader.active + property Component previewComponent: null - property real __horizontalSpacing: 5 + width: parent.width + implicitHeight: showImage ? previewLoader.implicitHeight + nameSection.implicitHeight : nameSection.implicitHeight - property StudioTheme.ControlStyle buttonStyle: StudioTheme.ViewBarButtonStyle { - //This is how you can override stuff from the control styles - controlSize: Qt.size(previewOptions.width, previewOptions.width) - baseIconFontSize: StudioTheme.Values.bigIconFontSize - } + orientation: Qt.Vertical - function refreshPreview() - { - materialPreview.source = "" - materialPreview.source = "image://materialEditor/preview" - } + Loader { + id: previewLoader - // Called from C++ to close context menu on focus out - function closeContextMenu() - { - modelMenu.close() - envMenu.close() - } + SplitView.fillWidth: true + SplitView.minimumWidth: 152 + SplitView.preferredHeight: previewLoader.visible ? Math.min(root.width * 0.75, 400) : 0 + SplitView.minimumHeight: previewLoader.visible ? 150 : 0 + SplitView.maximumHeight: previewLoader.visible ? 600 : 0 - anchors.left: parent.left - anchors.right: parent.right + visible: previewLoader.active && previewLoader.item - Item { width: 1; height: 5 } // spacer - - StudioControls.Menu { - id: modelMenu - closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside - - ListModel { - id: modelMenuModel - ListElement { - modelName: qsTr("Cone") - modelStr: "#Cone" - } - ListElement { - modelName: qsTr("Cube") - modelStr: "#Cube" - } - ListElement { - modelName: qsTr("Cylinder") - modelStr: "#Cylinder" - } - ListElement { - modelName: qsTr("Sphere") - modelStr: "#Sphere" - } - } - - Repeater { - model: modelMenuModel - StudioControls.MenuItemWithIcon { - text: modelName - onClicked: { - // Force property change notifications to keep check mark when reselected - root.previewModel = "" - root.previewModel = modelStr - } - checkable: true - checked: root.previewModel === modelStr - } - } - } - - StudioControls.Menu { - id: envMenu - closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside - - ListModel { - id: envMenuModel - ListElement { - envName: qsTr("Basic") - envStr: "Basic" - } - ListElement { - envName: qsTr("Color") - envStr: "Color" - } - ListElement { - envName: qsTr("Studio") - envStr: "SkyBox=preview_studio" - } - ListElement { - envName: qsTr("Landscape") - envStr: "SkyBox=preview_landscape" - } - } - - Repeater { - model: envMenuModel - StudioControls.MenuItemWithIcon { - text: envName - onClicked: { - // Force property change notifications to keep check mark when reselected - root.previewEnv = "" - root.previewEnv = envStr - } - checkable: true - checked: root.previewEnv === envStr - } - } - } - - Item { - anchors.horizontalCenter: parent.horizontalCenter - width: parent.width - height: previewRect.height - - StudioControls.AbstractButton { - id: pinButton - - x: root.__horizontalSpacing - - style: root.buttonStyle - iconSize: StudioTheme.Values.bigFont - buttonIcon: pinButton.checked ? StudioTheme.Constants.pin : StudioTheme.Constants.unpin - checkable: true - checked: itemPane.headerDocked - onCheckedChanged: itemPane.headerDocked = pinButton.checked - } - - Rectangle { - id: previewRect - anchors.horizontalCenter: parent.horizontalCenter - width: 152 - height: 152 - color: "#000000" - - Image { - id: materialPreview - width: 150 - height: 150 - anchors.centerIn: parent - source: "image://materialEditor/preview" - cache: false - smooth: true - } - } - - Item { - id: previewOptions - width: 40 - height: previewRect.height - anchors.top: previewRect.top - anchors.left: previewRect.right - anchors.leftMargin: root.__horizontalSpacing - - Column { - anchors.horizontalCenter: parent.horizontalCenter - - HelperWidgets.AbstractButton { - style: root.buttonStyle - buttonIcon: StudioTheme.Constants.textures_medium - tooltip: qsTr("Select preview environment.") - onClicked: envMenu.popup() - } - - HelperWidgets.AbstractButton { - style: root.buttonStyle - buttonIcon: StudioTheme.Constants.cube_medium - tooltip: qsTr("Select preview model.") - onClicked: modelMenu.popup() - } - } - } + sourceComponent: root.previewComponent } HelperWidgets.Section { + id: nameSection + // Section with hidden header is used so properties are aligned with the other sections' properties hideHeader: true - width: parent.width + SplitView.fillWidth: true + SplitView.preferredHeight: implicitHeight + SplitView.maximumHeight: implicitHeight + bottomPadding: StudioTheme.Values.sectionPadding * 2 collapsible: false HelperWidgets.SectionLayout { @@ -205,7 +61,7 @@ Column { showExtendedFunctionButton: false // allow only alphanumeric characters, underscores, no space at start, and 1 space between words - validator: HelperWidgets.RegExpValidator { regExp: /^(\w+\s)*\w+$/ } + validator: RegularExpressionValidator { regularExpression: /^(\w+\s)*\w+$/ } } HelperWidgets.ExpandingSpacer {} @@ -214,9 +70,9 @@ Column { HelperWidgets.PropertyLabel { text: qsTr("Type") } HelperWidgets.SecondColumnLayout { - HelperWidgets.Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth } + HelperWidgets.Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth } - HelperWidgets.ComboBox { + HelperWidgets.ComboBox { currentIndex: possibleTypeIndex model: possibleTypes showExtendedFunctionButton: false diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/EffectsSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/EffectsSection.qml index 3e9a79f8e04..59111572806 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/EffectsSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/EffectsSection.qml @@ -75,6 +75,8 @@ Section { root.invalidate() } } + + ExpandingSpacer {} } PropertyLabel { @@ -89,7 +91,7 @@ Section { CheckBox { implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - backendValue: root.effectNodeWrapper.properties.visible + backendValue: root.effectNodeWrapper?.properties.visible } ExpandingSpacer {} @@ -204,7 +206,7 @@ Section { CheckBox { implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - backendValue: root.effectNodeWrapper.properties.layerBlurVisible + backendValue: root.effectNodeWrapper?.properties.layerBlurVisible } ExpandingSpacer {} @@ -219,7 +221,7 @@ Section { SpinBox { implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - backendValue: root.effectNodeWrapper.properties.layerBlurRadius + backendValue: root.effectNodeWrapper?.properties.layerBlurRadius minimumValue: 0 maximumValue: 250 } @@ -250,7 +252,7 @@ Section { CheckBox { implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - backendValue: root.effectNodeWrapper.properties.backgroundBlurVisible + backendValue: root.effectNodeWrapper?.properties.backgroundBlurVisible } ExpandingSpacer {} @@ -267,7 +269,7 @@ Section { SpinBox { implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - backendValue: root.effectNodeWrapper.properties.backgroundBlurRadius + backendValue: root.effectNodeWrapper?.properties.backgroundBlurRadius minimumValue: 0 maximumValue: 250 } @@ -288,7 +290,7 @@ Section { + StudioTheme.Values.actionIndicatorWidth width: implicitWidth typeFilter: "QtQuick.Item" - backendValue: root.effectNodeWrapper.properties.backgroundLayer + backendValue: root.effectNodeWrapper?.properties.backgroundLayer } ExpandingSpacer {} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Layouts/ColumnLayoutSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Layouts/ColumnLayoutSpecifics.qml index aeaeacbd4ec..86a6c9079f2 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Layouts/ColumnLayoutSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Layouts/ColumnLayoutSpecifics.qml @@ -7,6 +7,7 @@ import HelperWidgets 2.0 import StudioTheme 1.0 as StudioTheme Section { + id: root anchors.left: parent.left anchors.right: parent.right caption: qsTr("Column Layout") @@ -50,9 +51,10 @@ Section { } PropertyLabel { - text: qsTr("Uniform cell size") + text: qsTr("Uniform cell sizes") tooltip: qsTr("Toggles all cells to have a uniform size.") visible: majorQtQuickVersion === 6 && minorQtQuickVersion >= 6 + blockedByTemplate: !backendValues.uniformCellSizes.isAvailable } SecondColumnLayout { @@ -61,6 +63,7 @@ Section { + StudioTheme.Values.actionIndicatorWidth backendValue: backendValues.uniformCellSizes visible: majorQtQuickVersion === 6 && minorQtQuickVersion >= 6 + enabled: backendValues.uniformCellSizes.isAvailable } ExpandingSpacer {} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Layouts/GridLayoutSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Layouts/GridLayoutSpecifics.qml index e6606ffe00f..f5e76108c1b 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Layouts/GridLayoutSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Layouts/GridLayoutSpecifics.qml @@ -7,6 +7,7 @@ import HelperWidgets 2.0 import StudioTheme 1.0 as StudioTheme Section { + id: root anchors.left: parent.left anchors.right: parent.right caption: qsTr("Grid Layout") @@ -131,6 +132,8 @@ Section { text: qsTr("Uniform cell sizes") tooltip: qsTr("Toggles all cells to have a uniform height or width.") visible: majorQtQuickVersion === 6 && minorQtQuickVersion >= 6 + blockedByTemplate: !(backendValues.uniformCellHeights.isAvailable + && backendValues.uniformCellWidths.isAvailable) } SecondColumnLayout { @@ -140,6 +143,7 @@ Section { + StudioTheme.Values.actionIndicatorWidth backendValue: backendValues.uniformCellHeights visible: majorQtQuickVersion === 6 && minorQtQuickVersion >= 6 + enabled: backendValues.uniformCellHeights.isAvailable } Spacer { implicitWidth: StudioTheme.Values.twoControlColumnGap } @@ -150,6 +154,7 @@ Section { + StudioTheme.Values.actionIndicatorWidth backendValue: backendValues.uniformCellWidths visible: majorQtQuickVersion === 6 && minorQtQuickVersion >= 6 + enabled: backendValues.uniformCellWidths.isAvailable } ExpandingSpacer {} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Layouts/RowLayoutSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Layouts/RowLayoutSpecifics.qml index 726b3783fbc..6f7431ad037 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Layouts/RowLayoutSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Layouts/RowLayoutSpecifics.qml @@ -7,6 +7,7 @@ import HelperWidgets 2.0 import StudioTheme 1.0 as StudioTheme Section { + id: root anchors.left: parent.left anchors.right: parent.right caption: qsTr("Row Layout") @@ -50,16 +51,19 @@ Section { } PropertyLabel { - text: qsTr("Uniform cell size") + text: qsTr("Uniform cell sizes") tooltip: qsTr("Toggles all cells to have a uniform size.") visible: majorQtQuickVersion === 6 && minorQtQuickVersion >= 6 + blockedByTemplate: !backendValues.uniformCellSizes.isAvailable } + SecondColumnLayout { CheckBox { implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth backendValue: backendValues.uniformCellSizes visible: majorQtQuickVersion === 6 && minorQtQuickVersion >= 6 + enabled: backendValues.uniformCellSizes.isAvailable } ExpandingSpacer {} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml index 41f2c433fa9..bced56a89dc 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml @@ -444,7 +444,7 @@ Column { Connections { target: root - onAboutToBeShown: { + function onAboutToBeShown() { colorPicker.aboutToBeShown() } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DynamicPropertiesSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DynamicPropertiesSection.qml index e0c70ff946b..9ddec119153 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DynamicPropertiesSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DynamicPropertiesSection.qml @@ -23,13 +23,13 @@ ** ****************************************************************************/ -import QtQuick 2.15 -import QtQuick.Controls 2.15 -import QtQuick.Layouts 1.15 -import HelperWidgets 2.0 -import QtQuick.Templates 2.15 as T -import StudioControls 1.0 as StudioControls -import StudioTheme 1.0 as StudioTheme +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import HelperWidgets +import QtQuick.Templates as T +import StudioControls as StudioControls +import StudioTheme as StudioTheme Section { id: root @@ -682,7 +682,7 @@ Section { IconIndicator { id: closeIndicator icon: StudioTheme.Constants.colorPopupClose - pixelSize: StudioTheme.Values.myIconFontSize * 1.4 + pixelSize: StudioTheme.Values.myIconFontSize onClicked: cePopup.close() Layout.alignment: Qt.AlignRight } @@ -699,7 +699,12 @@ Section { translationIndicatorVisible: false width: cePopup.itemWidth rightPadding: 8 - validator: RegExpValidator { regExp: /[a-z]+[0-9A-Za-z]*/ } + validator: PropertyNameValidator {} + + Binding { + when: !textField.acceptableInput && textField.text !== "" + textField.color: StudioTheme.Values.themeRedLight + } } } RowLayout { @@ -729,6 +734,7 @@ Section { buttonIcon: qsTr("Add Property") iconFont: StudioTheme.Constants.font width: cePopup.width / 3 + enabled: textField.acceptableInput onClicked: { root.propertiesModel.createProperty(textField.text, comboBox.currentText) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/EditableListView.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/EditableListView.qml index 1d007e0222a..b2f0498dc06 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/EditableListView.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/EditableListView.qml @@ -118,7 +118,10 @@ Item { onHoverChanged: root.delegateHover = delegateComboBox.hover } - Spacer { implicitWidth: extraButton.visible ? 5 : StudioTheme.Values.twoControlColumnGap } + Spacer { + implicitWidth: extraButton.visible ? StudioTheme.Values.controlLabelGap + : StudioTheme.Values.twoControlColumnGap + } IconIndicator { id: extraButton diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ItemFilterComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ItemFilterComboBox.qml index 316207e5f53..bb7d1307d81 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ItemFilterComboBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ItemFilterComboBox.qml @@ -11,27 +11,32 @@ HelperWidgets.ComboBox { manualMapping: true editable: true - model: comboBox.addDefaultItem(itemFilterModel.itemModel) + model: optionsList.model + valueRole: "id" + textRole: (comboBox.typeFilter === "QtQuick3D.Texture") ? "idAndName" : "id" validator: RegularExpressionValidator { regularExpression: /(^$|^[a-z_]\w*)/ } HelperWidgets.ItemFilterModel { id: itemFilterModel modelNodeBackendProperty: modelNodeBackend + onModelReset: optionsList.updateModel() + onRowsInserted: optionsList.updateModel() + onRowsRemoved: optionsList.updateModel() } property string defaultItem: qsTr("[None]") - property string textValue: comboBox.backendValue?.expression ?? "" + property string expressionValue: comboBox.backendValue?.expression ?? "" property bool block: false property bool dirty: true - onTextValueChanged: { + onExpressionValueChanged: { if (comboBox.block) return - comboBox.setCurrentText(comboBox.textValue) + comboBox.updateText() } - onModelChanged: comboBox.setCurrentText(comboBox.textValue) + onModelChanged: comboBox.updateText() onEditTextChanged: comboBox.dirty = true onFocusChanged: { if (comboBox.dirty) @@ -41,7 +46,18 @@ HelperWidgets.ComboBox { onCompressedActivated: function(index, reason) { comboBox.handleActivate(index) } onAccepted: comboBox.setCurrentText(comboBox.editText) - Component.onCompleted: comboBox.setCurrentText(comboBox.textValue) + Component.onCompleted: comboBox.updateText() + + function updateText() { + let idx = itemFilterModel.indexFromId(comboBox.expressionValue) + if (idx < 0) { + comboBox.setCurrentText(comboBox.defaultItem) + return + } + + let textValue = itemFilterModel.modelItemData(idx)[comboBox.textRole] + comboBox.setCurrentText(textValue) + } function handleActivate(index) { if (!comboBox.__isCompleted || comboBox.backendValue === undefined) @@ -69,18 +85,41 @@ HelperWidgets.ComboBox { comboBox.editText = comboBox.defaultItem } - if (comboBox.currentIndex === 0) { + if (comboBox.currentIndex < 1) { comboBox.backendValue.resetValue() } else { - if (comboBox.backendValue.expression !== comboBox.editText) - comboBox.backendValue.expression = comboBox.editText + let valueData = (comboBox.valueRole === "") + ? comboBox.editText + : itemFilterModel.modelItemData(comboBox.currentIndex - 1)[comboBox.valueRole] + + if (comboBox.backendValue.expression !== valueData) + comboBox.backendValue.expression = valueData } comboBox.dirty = false } - function addDefaultItem(arr) { - var copy = arr.slice() - copy.unshift(comboBox.defaultItem) - return copy + Repeater { + id: optionsList + + property var localModel: [] + + function updateModel() { + optionsList.localModel = [] + + if (comboBox.textRole !== "" && comboBox.valueRole !== "") { + let defaultItem = {} + defaultItem[comboBox.textRole] = comboBox.defaultItem + defaultItem[comboBox.valueRole] = "" + optionsList.localModel.push(defaultItem) + } else { + optionsList.localModel.push(comboBox.defaultItem) + } + + let rows = itemFilterModel.rowCount() + for (let i = 0; i < rows; ++i) + optionsList.localModel.push(itemFilterModel.modelItemData(i)) + + optionsList.model = optionsList.localModel // trigger on change handler + } } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/PropertyEditorPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/PropertyEditorPane.qml index 309d815d7aa..1df75525c51 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/PropertyEditorPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/PropertyEditorPane.qml @@ -57,6 +57,7 @@ Rectangle { bottom: itemPane.bottom left: itemPane.left right: itemPane.right + topMargin: dockedHeaderLoader.active ? 2 : 0 } interactive: !Controller.contextMenuOpened @@ -74,6 +75,7 @@ Rectangle { active: !itemPane.headerDocked sourceComponent: itemPane.headerComponent + visible: active HeaderBackground{} } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/TextInputSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/TextInputSection.qml index 737c742b33e..5a00babb353 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/TextInputSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/TextInputSection.qml @@ -14,30 +14,42 @@ Section { property bool isTextInput: false + function isBackendValueAvailable(name) { + if (backendValues[name] !== undefined) + return backendValues[name].isAvailable + + return false + } + SectionLayout { PropertyLabel { text: qsTr("Selection color") tooltip: qsTr("Sets the background color of selected text.") + blockedByTemplate: !root.isBackendValueAvailable("selectionColor") } ColorEditor { backendValue: backendValues.selectionColor supportGradient: false + enabled: root.isBackendValueAvailable("selectionColor") } PropertyLabel { text: qsTr("Selected text color") tooltip: qsTr("Sets the color of selected text.") + blockedByTemplate: !root.isBackendValueAvailable("selectedTextColor") } ColorEditor { backendValue: backendValues.selectedTextColor supportGradient: false + enabled: root.isBackendValueAvailable("selectedTextColor") } PropertyLabel { text: qsTr("Selection mode") tooltip: qsTr("Sets the way text is selected with the mouse.") + blockedByTemplate: !root.isBackendValueAvailable("mouseSelectionMode") } SecondColumnLayout { @@ -48,6 +60,7 @@ Section { backendValue: backendValues.mouseSelectionMode scope: root.isTextInput ? "TextInput" : "TextEdit" model: ["SelectCharacters", "SelectWords"] + enabled: root.isBackendValueAvailable("mouseSelectionMode") } ExpandingSpacer {} @@ -57,6 +70,7 @@ Section { visible: root.isTextInput text: qsTr("Input mask") tooltip: qsTr("Sets the allowed characters.") + blockedByTemplate: !root.isBackendValueAvailable("inputMask") } SecondColumnLayout { @@ -68,6 +82,7 @@ Section { + StudioTheme.Values.actionIndicatorWidth width: implicitWidth showTranslateCheckBox: false + enabled: root.isBackendValueAvailable("inputMask") } ExpandingSpacer {} @@ -77,6 +92,7 @@ Section { visible: root.isTextInput text: qsTr("Echo mode") tooltip: qsTr("Sets the visibility mode.") + blockedByTemplate: !root.isBackendValueAvailable("echoMode") } SecondColumnLayout { @@ -89,6 +105,7 @@ Section { backendValue: backendValues.echoMode scope: "TextInput" model: ["Normal", "Password", "PasswordEchoOnEdit", "NoEcho"] + enabled: root.isBackendValueAvailable("echoMode") } ExpandingSpacer {} @@ -98,6 +115,7 @@ Section { visible: root.isTextInput text: qsTr("Password character") tooltip: qsTr("Sets which character to display when passwords are entered.") + blockedByTemplate: !root.isBackendValueAvailable("passwordCharacter") } SecondColumnLayout { @@ -109,6 +127,7 @@ Section { + StudioTheme.Values.actionIndicatorWidth width: implicitWidth showTranslateCheckBox: false + enabled: root.isBackendValueAvailable("passwordCharacter") } ExpandingSpacer {} @@ -118,6 +137,7 @@ Section { visible: !root.isTextInput text: qsTr("Tab stop distance") tooltip: qsTr("Default distance between tab stops in device units.") + blockedByTemplate: !root.isBackendValueAvailable("tabStopDistance") } SecondColumnLayout { @@ -129,6 +149,7 @@ Section { backendValue: backendValues.tabStopDistance maximumValue: 200 minimumValue: 0 + enabled: root.isBackendValueAvailable("tabStopDistance") } Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } @@ -142,6 +163,7 @@ Section { visible: !root.isTextInput text: qsTr("Text margin") tooltip: qsTr("Margin around the text in the Text Edit in pixels.") + blockedByTemplate: !root.isBackendValueAvailable("textMargin") } SecondColumnLayout { @@ -153,6 +175,7 @@ Section { backendValue: backendValues.textMargin maximumValue: 200 minimumValue: -200 + enabled: root.isBackendValueAvailable("textMargin") } Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } @@ -166,6 +189,7 @@ Section { visible: root.isTextInput text: qsTr("Maximum length") tooltip: qsTr("Sets the maximum length of the text.") + blockedByTemplate: !root.isBackendValueAvailable("maximumLength") } SecondColumnLayout { @@ -177,6 +201,7 @@ Section { backendValue: backendValues.maximumLength minimumValue: 0 maximumValue: 32767 + enabled: root.isBackendValueAvailable("maximumLength") } ExpandingSpacer {} @@ -184,6 +209,7 @@ Section { component FlagItem : SecondColumnLayout { property alias backendValue: checkBox.backendValue + CheckBox { id: checkBox implicitWidth: StudioTheme.Values.twoControlColumnWidth @@ -197,64 +223,92 @@ Section { PropertyLabel { text: qsTr("Read only") tooltip: qsTr("Toggles if the text allows edits.") + blockedByTemplate: !root.isBackendValueAvailable("readOnly") } - FlagItem { backendValue: backendValues.readOnly } + FlagItem { + backendValue: backendValues.readOnly + enabled: root.isBackendValueAvailable("readOnly") + } PropertyLabel { text: qsTr("Cursor visible") tooltip: qsTr("Toggles if the cursor is visible.") + blockedByTemplate: !root.isBackendValueAvailable("cursorVisible") } - FlagItem { backendValue: backendValues.cursorVisible } + FlagItem { + backendValue: backendValues.cursorVisible + enabled: root.isBackendValueAvailable("cursorVisible") + } PropertyLabel { text: qsTr("Focus on press") tooltip: qsTr("Toggles if the text is focused on mouse click.") + blockedByTemplate: !root.isBackendValueAvailable("activeFocusOnPress") } - FlagItem { backendValue: backendValues.activeFocusOnPress } + FlagItem { + backendValue: backendValues.activeFocusOnPress + enabled: root.isBackendValueAvailable("activeFocusOnPress") + } PropertyLabel { visible: root.isTextInput text: qsTr("Auto scroll") tooltip: qsTr("Toggles if the text scrolls when it exceeds its boundary.") + blockedByTemplate: !root.isBackendValueAvailable("autoScroll") } FlagItem { visible: root.isTextInput backendValue: backendValues.autoScroll + enabled: root.isBackendValueAvailable("autoScroll") } PropertyLabel { text: qsTr("Overwrite mode") tooltip: qsTr("Toggles if overwriting text is allowed.") + blockedByTemplate: !root.isBackendValueAvailable("overwriteMode") } - FlagItem { backendValue: backendValues.overwriteMode } + FlagItem { + backendValue: backendValues.overwriteMode + enabled: root.isBackendValueAvailable("overwriteMode") + } PropertyLabel { text: qsTr("Persistent selection") tooltip: qsTr("Toggles if the text should remain selected after moving the focus elsewhere.") + blockedByTemplate: !root.isBackendValueAvailable("persistentSelection") } - FlagItem { backendValue: backendValues.persistentSelection } + FlagItem { + backendValue: backendValues.persistentSelection + enabled: root.isBackendValueAvailable("persistentSelection") + } PropertyLabel { text: qsTr("Select by mouse") tooltip: qsTr("Toggles if the text can be selected with the mouse.") + blockedByTemplate: !root.isBackendValueAvailable("selectByMouse") } - FlagItem { backendValue: backendValues.selectByMouse } + FlagItem { + backendValue: backendValues.selectByMouse + enabled: root.isBackendValueAvailable("selectByMouse") + } PropertyLabel { visible: !root.isTextInput text: qsTr("Select by keyboard") + blockedByTemplate: !root.isBackendValueAvailable("selectByKeyboard") } FlagItem { visible: !root.isTextInput backendValue: backendValues.selectByKeyboard + enabled: root.isBackendValueAvailable("selectByKeyboard") } } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml index 8dadd1db2c2..c47f5156780 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml @@ -143,7 +143,7 @@ Row { property ListModel listModel: ListModel {} - hasActiveDrag: activeDragSuffix !== "" && root.filter.includes(activeDragSuffix) + hasActiveDrag: typeof(activeDragSuffix) !== "undefined" && activeDragSuffix !== "" && root.filter.includes(activeDragSuffix) implicitWidth: StudioTheme.Values.singleControlColumnWidth + StudioTheme.Values.actionIndicatorWidth width: implicitWidth diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SplitView.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SplitView.qml new file mode 100644 index 00000000000..4c7fb5af0d5 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SplitView.qml @@ -0,0 +1,20 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Controls as QuickControls +import StudioTheme 1.0 as StudioTheme + +QuickControls.SplitView { + id: control + + property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle + + handle: Rectangle { + implicitWidth: control.orientation === Qt.Horizontal ? StudioTheme.Values.splitterThickness : control.width + implicitHeight: control.orientation === Qt.Horizontal ? control.height : StudioTheme.Values.splitterThickness + color: QuickControls.SplitHandle.pressed ? control.style.slider.handleInteraction + : (QuickControls.SplitHandle.hovered ? control.style.slider.handleHover + : "transparent") + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml index 58bd9c37d2e..b383d996b6a 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml @@ -47,7 +47,6 @@ T.TextField { readOnly: false selectByMouse: true persistentSelection: contextMenu.visible || control.focus - clip: true width: control.style.controlSize.width height: control.style.controlSize.height diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir index e93f6f59ded..4266910554f 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir @@ -51,6 +51,7 @@ SortFilterModel 1.0 SortFilterModel.qml SpinBox 1.0 SpinBox.qml SpinBoxIndicator 1.0 SpinBoxIndicator.qml SpinBoxInput 1.0 SpinBoxInput.qml +SplitView 1.0 SplitView.qml Switch 1.0 Switch.qml TabBar 1.0 TabBar.qml TabButton 1.0 TabButton.qml diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml index 69803cf3208..32a078b8d6d 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml @@ -126,6 +126,7 @@ QtObject { property real controlGap: 5 // TODO different name property real splitterMargin: 5 + property real splitterThickness: 6 property real twoControlColumnGap: values.controlLabelGap + values.controlLabelWidth + values.controlGap @@ -172,7 +173,7 @@ QtObject { property real controlColumnWithoutControlsWidth: 2 * (values.actionIndicatorWidth + values.twoControlColumnGap) - + values.linkControlWidth // there could be an issue here with the new style + + values.iconAreaWidth // there could be an issue here with the new style property real controlColumnWidth: values.controlColumnWithoutControlsWidth + 2 * values.twoControlColumnWidth @@ -193,18 +194,21 @@ QtObject { property real dialogScreenMargin: Math.round(160 * values.scaleFactor) function responsiveResize(width) { + // Subtract all layout gaps/spaces var tmpWidth = width - values.sectionColumnSpacing - values.sectionLeftPadding - values.sectionLayoutRightPadding var labelColumnWidth = Math.round(tmpWidth * values.columnFactor) labelColumnWidth = Math.max(Math.min(values.propertyLabelWidthMax, labelColumnWidth), values.propertyLabelWidthMin) - + // Rest width when label width is substracted var controlColumnWidth = tmpWidth - labelColumnWidth - var controlWidth = Math.round((controlColumnWidth - values.controlColumnWithoutControlsWidth) * 0.5) + var controlWidth = Math.floor((controlColumnWidth - values.controlColumnWithoutControlsWidth) * 0.5) controlWidth = Math.max(Math.min(values.twoControlColumnWidthMax, controlWidth), values.twoControlColumnWidthMin) - - values.propertyLabelWidth = labelColumnWidth + // When both label and controls are at max width, calculate the remaining space + var rest = tmpWidth - (controlWidth * 2 + values.controlColumnWithoutControlsWidth + labelColumnWidth) + // Add the remaining space to the label width in order to improve readability of long labels + values.propertyLabelWidth = labelColumnWidth + rest values.twoControlColumnWidth = controlWidth } diff --git a/share/qtcreator/qmldesigner/qt4mcu/metadata.qml b/share/qtcreator/qmldesigner/qt4mcu/metadata.qml index 2df700e72ac..59193147814 100644 --- a/share/qtcreator/qmldesigner/qt4mcu/metadata.qml +++ b/share/qtcreator/qmldesigner/qt4mcu/metadata.qml @@ -5,7 +5,7 @@ Metadata { id: metadataFile - defaultVersion: v27 + defaultVersion: v28 VersionData { id: v14 @@ -78,4 +78,10 @@ Metadata { name: "Qt for MCUs 2.7" path: "qul-27.qml" } + + VersionData { + id: v28 + name: "Qt for MCUs 2.8" + path: "qul-28.qml" + } } diff --git a/share/qtcreator/qmldesigner/qt4mcu/qul-28.qml b/share/qtcreator/qmldesigner/qt4mcu/qul-28.qml new file mode 100644 index 00000000000..281f4f08263 --- /dev/null +++ b/share/qtcreator/qmldesigner/qt4mcu/qul-28.qml @@ -0,0 +1,264 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +// new import: QtQuick.Layout +// new types: TextInput, Layouts + +VersionData { + name: "Qt for MCUs 2.8" + + bannedItems: [ + "QtQuick.AnimatedImage", + "QtQuick.Flow", + "QtQuick.FocusScope", + "QtQuick.Grid", + "QtQuick.GridView", + "QtQuick.PathView", + "QtQuick.TextEdit", + "QtQuick.Controls", + "QtQuick.Controls.BusyIndicator", + "QtQuick.Controls.ButtonGroup", + "QtQuick.Controls.CheckDelegate", + "QtQuick.Controls.ComboBox", + "QtQuick.Controls.Container", + "QtQuick.Controls.DelayButton", + "QtQuick.Controls.Frame", + "QtQuick.Controls.GroupBox", + "QtQuick.Controls.ItemDelegate", + "QtQuick.Controls.Label", + "QtQuick.Controls.Page", + "QtQuick.Controls.PageIndicator", + "QtQuick.Controls.Pane", + "QtQuick.Controls.RadioDelegate", + "QtQuick.Controls.RangeSlider", + "QtQuick.Controls.RoundButton", + "QtQuick.Controls.ScrollView", + "QtQuick.Controls.SpinBox", + "QtQuick.Controls.StackView", + "QtQuick.Controls.SwipeDelegate", + "QtQuick.Controls.SwitchDelegate", + "QtQuick.Controls.TabBar", + "QtQuick.Controls.TabButton", + "QtQuick.Controls.TextArea", + "QtQuick.Controls.TextField", + "QtQuick.Controls.ToolBar", + "QtQuick.Controls.ToolButton", + "QtQuick.Controls.ToolSeparator", + "QtQuick.Controls.Tumbler", + "QtQuick.Layouts.LayoutItemProxy", + "QtQuick.Layouts.StackLayout", + "QtQuick.Shapes.ConicalGradient", + "QtQuick.Shapes.RadialGradient" + ] + + allowedImports: [ + "QtQuick", + "QtQuick.Controls", + "QtQuick.Layouts", + "QtQuick.Shapes", + "QtQuick.Timeline", + "QtQuickUltralite.Extras", + "QtQuickUltralite.Layers", + "QtQuickUltralite.Profiling", + "QtQuickUltralite.Studio.Components" + ] + + bannedImports: [ + "FlowView", + "SimulinkConnector" + ] + + //ComplexProperty is not a type, it's just a way to handle bigger props + ComplexProperty { + prefix: "font" + bannedProperties: ["wordSpacing", "letterSpacing", "hintingPreference", + "kerning", "preferShaping", "capitalization", + "strikeout", "underline", "styleName"] + } + + QtQml.Timer { + bannedProperties: ["triggeredOnStart"] + } + + QtQuick.Item { + bannedProperties: ["layer", "opacity", "smooth", "antialiasing", + "baselineOffset", "focus", "activeFocusOnTab", + "rotation", "scale", "transformOrigin"] + } + + QtQuick.Rectangle { + bannedProperties: ["border"] + } + + QtQuick.Flickable { + bannedProperties: ["boundsMovement", "flickDeceleration", + "leftMargin", "rightMargin", "bottomMargin", "topMargin", + "originX", "originY", "pixelAligned", "pressDelay", "synchronousDrag"] + } + + QtQuick.MouseArea { + bannedProperties: ["propagateComposedEvents", "preventStealing", "cursorShape", + "scrollGestureEnabled", "drag", "acceptedButtons", "hoverEnabled"] + } + + QtQuick.Image { + allowChildren: false + allowedProperties: ["rotation", "scale", "transformOrigin"] + bannedProperties: ["mirror", "mipmap", "cache", "autoTransform", "asynchronous", + "sourceSize", "smooth"] + } + + QtQuick.BorderImage { + bannedProperties: ["asynchronous", "cache", "currentFrame", "frameCount", + "horizontalTileMode", "mirror", "progress", "smooth", "sourceSize", + "status", "verticalTileMode"] + } + + QtQuick.Text { + allowChildren: false + allowedProperties: ["rotation", "scale", "transformOrigin"] + bannedProperties: ["lineHeight", "lineHeightMode", "style", + "styleColor", "minimumPointSize", "minimumPixelSize", + "fontSizeMode", "renderType", "renderTypeQuality", "maximumLineCount"] + } + + QtQuick.TextInput { + bannedProperties: ["acceptableInput", "autoScroll", "bottomPadding", "canPaste", + "canRedo", "canUndo", "contentHeight", "contentWidth", "cursorDelegate", + "cursorPosition", "cursorRectangle", "cursorVisible", "displayText", "echoMode", + "effectiveHorizontalAlignment", "horizontalAlignment", "inputMask", + "inputMethodComposing", "leftPadding", "length", "maximumLength", + "mouseSelectionMode", "overwriteMode", "padding", "passwordCharacter", + "passwordMaskDelay", "persistentSelection", "preeditText", "readOnly", + "renderType", "rightPadding", "selectByMouse", "selectedText", + "selectedTextColor", "selectionColor", "selectionEnd", "selectionStart", + "topPadding", "validator", "verticalAlignment", "wrapMode"] + } + + QtQuick.Loader { + bannedProperties: ["asynchronous", "progress", "status"] + } + + //Padding is not an actual item, but rather set of properties in Text + Padding { + bannedProperties: ["bottomPadding", "topPadding", "leftPadding", "rightPadding"] + } + + QtQuick.Column { + bannedProperties: ["bottomPadding", "leftPadding", "rightPadding", "topPadding"] + } + + QtQuick.Row { + bannedProperties: ["bottomPadding", "leftPadding", "rightPadding", "topPadding", + "effectiveLayoutDirection", "layoutDirection"] + } + + QtQuick.ListView { + bannedProperties: ["cacheBuffer", "highlightRangeMode", "highlightMoveDuration", + "highlightResizeDuration", "preferredHighlightBegin", "layoutDirection", + "preferredHighlightEnd", "highlightFollowsCurrentItem", "keyNavigationWraps", + "snapMode", "highlightMoveVelocity", "highlightResizeVelocity"] + } + + QtQuick.Animation { + bannedProperties: ["paused"] + } + + QtQuick.AnimatedSprite { + allowedProperties: ["currentFrame", "frameCount", "paused"] + bannedProperties: ["finishBehavior", "frameRate", "frameSync", + "frameX", "frameY", "interpolate", "reverse"] + } + + //Quick Controls2 Items and properties: + + QtQuick.Controls.Control { + bannedProperties: ["focusPolicy", "hoverEnabled", "wheelEnabled"] + } + + QtQuick.Controls.AbstractButton { + bannedProperties: ["display", "autoExclusive", "icon"] + } + + QtQuick.Controls.ProgressBar { + bannedProperties: ["indeterminate"] + } + + QtQuick.Controls.Slider { + bannedProperties: ["live", "snapMode", "touchDragThreshold"] + } + + ComplexProperty { + prefix: "Layout" + bannedProperties: ["horizontalStretchFactor", "verticalStretchFactor"] + } + + QtQuick.Layouts.Layout { + bannedProperties: ["horizontalStretchFactor", "verticalStretchFactor"] + } + + QtQuick.Layouts.ColumnLayout { + allowedProperties: ["layoutDirection"] + bannedProperties: ["uniformCellSizes"] + } + + QtQuick.Layouts.RowLayout { + allowedProperties: ["layoutDirection"] + bannedProperties: ["uniformCellSizes"] + } + + QtQuick.Layouts.GridLayout { + allowedProperties: ["layoutDirection"] + bannedProperties: ["uniformCellHeights", "uniformCellWidths"] + } + + //Path and Shapes related: + + QtQuick.Path { + bannedProperties: ["scale", "pathElements"] + } + + QtQuick.PathArc { + bannedProperties: ["relativeX", "relativeY"] + } + + QtQuick.PathLine { + bannedProperties: ["relativeX", "relativeY"] + } + + QtQuick.PathMove { + bannedProperties: ["relativeX", "relativeY"] + } + + QtQuick.PathQuad { + bannedProperties: ["relativeX", "relativeY", + "relativeControlX", "relativeControlY"] + } + + QtQuick.PathCubic { + bannedProperties: ["relativeX", "relativeY", + "relativeControl1X", "relativeControl1Y", + "relativeControl2X", "relativeControl2Y"] + } + + QtQuick.PathElement { + //nothing + } + + QtQuick.PathSvg { + //nothing + } + + QtQuick.Shapes.Shape { + bannedProperties: ["asynchronous", "containsMode", "data", + "renderType", "status", "vendorExtensionsEnabled"] + } + + QtQuick.Shapes.ShapePath { + bannedProperties: ["dashOffset", "dashPattern", "strokeStyle"] + } + + QtQuickUltralite.Extras.ItemBuffer { + allowedProperties: ["rotation", "scale", "transformOrigin"] + } +} diff --git a/share/qtcreator/qmldesigner/stateseditor/Main.qml b/share/qtcreator/qmldesigner/stateseditor/Main.qml index 8774f3a02b2..9184c870ac7 100644 --- a/share/qtcreator/qmldesigner/stateseditor/Main.qml +++ b/share/qtcreator/qmldesigner/stateseditor/Main.qml @@ -562,6 +562,7 @@ Rectangle { isChecked: root.currentStateInternalId === 0 thumbnailImageSource: StatesEditorBackend.statesEditorModel.baseState.stateImageSource ?? "" // TODO Get rid of the QVariantMap isTiny: root.tinyMode + backgroundColor: StatesEditorBackend.statesEditorModel.backgroundColor onFocusSignal: root.currentStateInternalId = 0 onDefaultClicked: StatesEditorBackend.statesEditorModel.resetDefaultState() @@ -830,6 +831,7 @@ Rectangle { visualIndex: delegateRoot.visualIndex internalNodeId: delegateRoot.internalNodeId isTiny: root.tinyMode + backgroundColor: StatesEditorBackend.statesEditorModel.backgroundColor hasExtend: delegateRoot.hasExtend extendString: delegateRoot.extendString diff --git a/share/qtcreator/qmldesigner/stateseditor/StateThumbnail.qml b/share/qtcreator/qmldesigner/stateseditor/StateThumbnail.qml index 781ddc4601f..703bc3e7ed0 100644 --- a/share/qtcreator/qmldesigner/stateseditor/StateThumbnail.qml +++ b/share/qtcreator/qmldesigner/stateseditor/StateThumbnail.qml @@ -65,6 +65,8 @@ Item { property int internalNodeId + property color backgroundColor: "transparent" + signal focusSignal signal defaultClicked signal clone @@ -241,7 +243,7 @@ Item { (stateBackground.innerHeight - thumbnailImage.paintedHeight) / 2) - StudioTheme.Values.border width: Math.round(thumbnailImage.paintedWidth) + 2 * StudioTheme.Values.border height: Math.round(thumbnailImage.paintedHeight) + 2 * StudioTheme.Values.border - color: "transparent" + color: root.backgroundColor border.width: StudioTheme.Values.border border.color: StudioTheme.Values.themeStatePreviewOutline } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json index a897fa421ae..bbdb40dcd22 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json @@ -10,6 +10,7 @@ "fontIconName": "wizardsGeneric", "enabled": "%{JS: [ %{Plugins} ].indexOf('QmlProjectManager') >= 0}", "platformIndependent": true, + "featuresRequired": [ "QmlDesigner.Wizards.FullQDS" ], "options": [ @@ -288,6 +289,14 @@ 'TargetQuickVersion': '6.7', 'TargetQuick3DVersion': '6.7' })" + }, + { + "trKey": "Qt 6.8", + "value": + "({ + 'TargetQuickVersion': '6.8', + 'TargetQuick3DVersion': '6.8' + })" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/wizard.json index ccd522f7c84..d328dedb779 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/wizard.json @@ -10,6 +10,7 @@ "fontIconName": "wizardsGeneric", "enabled": "%{JS: [ %{Plugins} ].indexOf('QmlProjectManager') >= 0}", "platformIndependent": true, + "featuresRequired": [ "QmlDesigner.Wizards.FullQDS" ], "options": [ @@ -264,6 +265,14 @@ 'TargetQuickVersion': '6.7', 'TargetQuick3DVersion': '6.7' })" + }, + { + "trKey": "Qt 6.8", + "value": + "({ + 'TargetQuickVersion': '6.8', + 'TargetQuick3DVersion': '6.8' + })" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Screen01.ui.qml.tpl index 4a16e2c6b1c..1a038a047a2 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Screen01.ui.qml.tpl @@ -9,11 +9,13 @@ import QtQuick import Constants Rectangle { + id: root width: Constants.width height: Constants.height color: Constants.backgroundColor Text { + id: textLabel text: qsTr("Hello %{ProjectName}") anchors.centerIn: parent } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/app_mcu.qmlproject.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/app_mcu.qmlproject.tpl index 7c4453752a6..6ea0b215fad 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/app_mcu.qmlproject.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/app_mcu.qmlproject.tpl @@ -19,6 +19,14 @@ Project { directory: "." } + ImageFiles { + directory: "images" + } + + ImageFiles { + directory: "assets" + } + Files { filter: "*.conf" files: ["qtquickcontrols2.conf"] @@ -33,6 +41,10 @@ Project { filter: "*.ttf;*.otf" } + FontFiles { + directory: "fonts" + } + ModuleFiles { files: [ "imports/Constants/constants_module.qmlproject" @@ -44,7 +56,8 @@ Project { "Timeline", "Shapes", "Profiling", - "StudioComponents" + "StudioComponents", + "Layouts" ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/assets.txt b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/assets.txt new file mode 100644 index 00000000000..d43160aeb4b --- /dev/null +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/assets.txt @@ -0,0 +1 @@ +Image assets generated by Bridge in this folder are loaded automatically. diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/images.txt b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/images.txt new file mode 100644 index 00000000000..38ad142bc42 --- /dev/null +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/images.txt @@ -0,0 +1 @@ +Images in this folder are loaded automatically. diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/qmldir b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/qmldir.tpl similarity index 100% rename from share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/qmldir rename to share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/qmldir.tpl diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/wizard.json index 01baa5f9760..82815caa35d 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/wizard.json @@ -153,7 +153,7 @@ "target": "%{ProjectDirectory}/%{MainQmlFileName}" }, { - "source": "qmldir", + "source": "qmldir.tpl", "target": "%{ProjectDirectory}/imports/Constants/qmldir" }, { @@ -174,9 +174,17 @@ "target": "%{ProjectDirectory}/CMakeLists.txt" }, { - "source": "../fonts.txt", + "source": "../common/fonts.txt", "target": "%{ProjectDirectory}/fonts/fonts.txt" }, + { + "source": "images.txt", + "target": "%{ProjectDirectory}/images/images.txt" + }, + { + "source": "assets.txt", + "target": "%{ProjectDirectory}/assets/assets.txt" + }, { "source": "mcuqtquickcontrols2.conf", "target": "%{ProjectDirectory}/qtquickcontrols2.conf" diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json index f0f98c33315..168ab5b66de 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json @@ -289,6 +289,13 @@ "({ 'TargetQuickVersion': '6.7' })" + }, + { + "trKey": "Qt 6.8", + "value": + "({ + 'TargetQuickVersion': '6.8' + })" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/defaults/qmlapplication-project-page.json b/share/qtcreator/qmldesigner/studio_templates/projects/defaults/qmlapplication-project-page.json index d23e1ecdc13..c213ae89236 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/defaults/qmlapplication-project-page.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/defaults/qmlapplication-project-page.json @@ -3,7 +3,7 @@ "trShortTitle": "Location", "typeId": "Project", "data": { - "projectNameValidator": "^(?!(import))(?!(QtQml))(?!(QtQuick))(?:[A-Z][a-zA-Z0-9-_]*)$", - "trProjectNameValidatorUserMessage": "Project name must start with a capital letter. It cannot start with QtQml or QtQuick. Use only letters and digits separated by `_` or `-`" + "projectNameValidator": "^(?!(import))(?!(QtQml))(?!(QtQuick))(?:[A-Z][a-zA-Z0-9_]*)$", + "trProjectNameValidatorUserMessage": "Project name must start with a capital letter. It cannot start with QtQml or QtQuick. Use only letters and digits separated by `_`." } } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json index c15d4dbf744..4ddc07a83a6 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json @@ -280,6 +280,20 @@ "({ 'TargetQuickVersion': '6.6' })" + }, + { + "trKey": "Qt 6.7", + "value": + "({ + 'TargetQuickVersion': '6.7' + })" + }, + { + "trKey": "Qt 6.8", + "value": + "({ + 'TargetQuickVersion': '6.8' + })" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json index d9e4b979083..7828254ea61 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json @@ -246,6 +246,13 @@ "({ 'TargetQuickVersion': '6.7' })" + }, + { + "trKey": "Qt 6.8", + "value": + "({ + 'TargetQuickVersion': '6.8' + })" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json index 910c32a42cf..988d3a6575d 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json @@ -244,6 +244,13 @@ "({ 'TargetQuickVersion': '6.7' })" + }, + { + "trKey": "Qt 6.8", + "value": + "({ + 'TargetQuickVersion': '6.8' + })" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json index 1f5be300e16..daa20961b76 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json @@ -244,6 +244,13 @@ "({ 'TargetQuickVersion': '6.7' })" + }, + { + "trKey": "Qt 6.8", + "value": + "({ + 'TargetQuickVersion': '6.8' + })" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/Constants.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/Constants.qml.tpl index 35aa48896bd..2d0b96dd04b 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/Constants.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/Constants.qml.tpl @@ -26,7 +26,7 @@ QtObject { @if %{IsQt6Project} property StudioApplication application: StudioApplication { - fontPath: Qt.resolvedUrl("../../%{ContentDir}/" + relativeFontDirectory) + fontPath: Qt.resolvedUrl("../%{ContentDir}/" + relativeFontDirectory) } @else property DirectoryFontLoader directoryFontLoader: DirectoryFontLoader { diff --git a/share/qtcreator/qmldesigner/toolbar/Main.qml b/share/qtcreator/qmldesigner/toolbar/Main.qml index 88a9bd744a2..5cdc2f4d516 100644 --- a/share/qtcreator/qmldesigner/toolbar/Main.qml +++ b/share/qtcreator/qmldesigner/toolbar/Main.qml @@ -282,7 +282,7 @@ Rectangle { ToolbarButton { id: enterComponent anchors.verticalCenter: parent.verticalCenter - anchors.right: lockWorkspace.left + anchors.right: backend.isLiteModeEnabled ? shareButton.left : lockWorkspace.left anchors.rightMargin: 10 enabled: goIntoComponentBackend.available tooltip: goIntoComponentBackend.tooltip @@ -305,7 +305,7 @@ Rectangle { tooltip: qsTr("Sets the visible Views to immovable across the Workspaces.") buttonIcon: backend.lockWorkspace ? StudioTheme.Constants.lockOn : StudioTheme.Constants.lockOff - visible: !root.flyoutEnabled + visible: !root.flyoutEnabled && !backend.isLiteModeEnabled checkable: true checked: backend.lockWorkspace checkedInverted: true @@ -318,9 +318,9 @@ Rectangle { style: StudioTheme.Values.toolbarStyle width: 210 anchors.verticalCenter: parent.verticalCenter - anchors.right: annotations.left + anchors.right: shareButton.left anchors.rightMargin: 10 - visible: !root.flyoutEnabled + visible: !root.flyoutEnabled && !backend.isLiteModeEnabled model: WorkspaceModel { id: workspaceModel } textRole: "displayName" valueRole: "fileName" @@ -333,20 +333,6 @@ Rectangle { onCountChanged: workspaces.currentIndex = workspaces.indexOfValue(backend.currentWorkspace) } - ToolbarButton { - id: annotations - visible: false - enabled: backend.isInDesignMode - anchors.verticalCenter: parent.verticalCenter - anchors.right: shareButton.left - anchors.rightMargin: 10 - width: 0 - tooltip: qsTr("Edit Annotations") - buttonIcon: StudioTheme.Constants.annotations_large - - onClicked: backend.editGlobalAnnoation() - } - ToolbarButton { id: shareButton style: StudioTheme.Values.primaryToolbarStyle @@ -394,7 +380,8 @@ Rectangle { readonly property int padding: 6 width: row.width + window.padding * 2 - height: row.height + workspacesFlyout.height + 3 * window.padding + height: row.height + (backend.isLiteModeEnabled ? 0 : workspacesFlyout.height) + + (backend.isLiteModeEnabled ? 2 : 3) * window.padding + (workspacesFlyout.popup.opened ? workspacesFlyout.popup.height : 0) visible: false flags: Qt.FramelessWindowHint | Qt.Dialog | Qt.NoDropShadowWindowHint @@ -470,6 +457,7 @@ Rectangle { : StudioTheme.Constants.lockOff checkable: true checked: backend.lockWorkspace + visible: !backend.isLiteModeEnabled onClicked: backend.setLockWorkspace(lockWorkspaceFlyout.checked) } @@ -498,6 +486,7 @@ Rectangle { textRole: "displayName" valueRole: "fileName" currentIndex: workspacesFlyout.indexOfValue(backend.currentWorkspace) + visible: !backend.isLiteModeEnabled onCompressedActivated: backend.setCurrentWorkspace(workspacesFlyout.currentValue) onCountChanged: workspacesFlyout.currentIndex = workspacesFlyout.indexOfValue(backend.currentWorkspace) diff --git a/share/qtcreator/qmldesigner/welcomepage/CustomGrid.qml b/share/qtcreator/qmldesigner/welcomepage/CustomGrid.qml index bc7c4faf4ab..127c4b48efe 100644 --- a/share/qtcreator/qmldesigner/welcomepage/CustomGrid.qml +++ b/share/qtcreator/qmldesigner/welcomepage/CustomGrid.qml @@ -36,6 +36,7 @@ Item { model: ExamplesModel {} delegate: ThumbnailDelegate {} + cacheBuffer: 65536 } } } diff --git a/share/qtcreator/qmldesigner/welcomepage/MainScreen.qml b/share/qtcreator/qmldesigner/welcomepage/MainScreen.qml index b2e09d43081..7b2417e6dd9 100644 --- a/share/qtcreator/qmldesigner/welcomepage/MainScreen.qml +++ b/share/qtcreator/qmldesigner/welcomepage/MainScreen.qml @@ -103,6 +103,7 @@ Rectangle { anchors.rightMargin: 20 anchors.leftMargin: 20 spacing: 15 + visible: !Constants.projectModel.liteDesignerEnabled CheckButton { id: recentProjects diff --git a/share/qtcreator/qmldesigner/workspacePresets/Lite-QML-Designer.wrk b/share/qtcreator/qmldesigner/workspacePresets/Lite-QML-Designer.wrk new file mode 100644 index 00000000000..34012f8937c --- /dev/null +++ b/share/qtcreator/qmldesigner/workspacePresets/Lite-QML-Designer.wrk @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + 336 657 0 + + + + + + + + + + + + + + 994 0 0 + + + + + + + + + 994 0 + + 384 1150 384 + + + diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 8e19bacc680..293a7546fa8 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -10,7 +10,9 @@ endif() configure_file(app_logo.qrc.cmakein app_logo_cmake.qrc) add_qtc_executable(qtcreator - DEFINES IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\" + DEFINES + IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\" + IDE_APP_ID=\"${IDE_APP_ID}\" DEPENDS Aggregation ExtensionSystem Qt::Core Qt::Widgets Utils shared_qtsingleapplication app_version SOURCES main.cpp @@ -156,7 +158,7 @@ if ((NOT WIN32) AND (NOT APPLE)) # install logo foreach(size 16 24 32 48 64 128 256 512) install( - FILES ${IDE_LOGO_PATH}/images/logo/${size}/QtProject-qtcreator.png + FILES ${IDE_LOGO_PATH}/images/logo/${size}/QtProject-${IDE_ID}.png DESTINATION share/icons/hicolor/${size}x${size}/apps ) endforeach() diff --git a/src/app/app_logo.qrc.cmakein b/src/app/app_logo.qrc.cmakein index f595e107031..c3c865c034d 100644 --- a/src/app/app_logo.qrc.cmakein +++ b/src/app/app_logo.qrc.cmakein @@ -1,6 +1,6 @@ - ${IDE_LOGO_PATH}/images/logo/128/QtProject-qtcreator.png - ${IDE_LOGO_PATH}/images/logo/256/QtProject-qtcreator.png + ${IDE_LOGO_PATH}/images/logo/128/QtProject-${IDE_ID}.png + ${IDE_LOGO_PATH}/images/logo/256/QtProject-${IDE_ID}.png diff --git a/src/app/main.cpp b/src/app/main.cpp index caa780f1206..de53ed51d20 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -799,7 +799,7 @@ int main(int argc, char **argv) if (!overrideCodecForLocale.isEmpty()) QTextCodec::setCodecForLocale(QTextCodec::codecForName(overrideCodecForLocale)); - app.setDesktopFileName("org.qt-project.qtcreator"); + app.setDesktopFileName(IDE_APP_ID); // Make sure we honor the system's proxy settings QNetworkProxyFactory::setUseSystemConfiguration(true); diff --git a/src/libs/3rdparty/zlib/LICENSE b/src/libs/3rdparty/zlib/LICENSE new file mode 100644 index 00000000000..9c57e18006e --- /dev/null +++ b/src/libs/3rdparty/zlib/LICENSE @@ -0,0 +1,28 @@ + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. + diff --git a/src/libs/3rdparty/zlib/import_from_zlib_tarball.sh b/src/libs/3rdparty/zlib/import_from_zlib_tarball.sh new file mode 100644 index 00000000000..0f81f052f3b --- /dev/null +++ b/src/libs/3rdparty/zlib/import_from_zlib_tarball.sh @@ -0,0 +1,93 @@ +#! /bin/sh + +# Copyright (C) 2017 André Klitzing +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only +# +# This is a small script to copy the required files from a zlib tarball +# into 3rdparty/zlib/ + +if [ $# -ne 2 ]; then + echo "Usage: $0 zlib_tarball_dir/ \$QTDIR/src/3rdparty/zlib/" + exit 1 +fi + +# Name the arguments, omitting trailing slashes as we'll add where needed. +ZLIB_DIR="${1%/}" +TARGET_DIR="${2%/}" + +if [ ! -d "$ZLIB_DIR" -o ! -r "$ZLIB_DIR" -o ! -d "$TARGET_DIR" -o ! -w "$TARGET_DIR" ]; then + echo "Either the zlib source dir or the target dir do not exist," + echo "are not directories or have the wrong permissions." + exit 2 +fi + +# with 1 argument, copies ZLIB_DIR/$1 to TARGET_DIR/$1 +# with 2 arguments, copies ZLIB_DIR/$1 to TARGET_DIR/$2 +copy_file() { + if [ $# -lt 1 -o $# -gt 2 ]; then + echo "Wrong number of arguments to copy_file" + exit 3 + fi + + SOURCE_FILE=$1 + if [ -n "$2" ]; then + DEST_FILE=$2 + else + DEST_FILE=$1 + fi + + mkdir -p "$TARGET_DIR/$(dirname "$SOURCE_FILE")" + cp -v "$ZLIB_DIR/$SOURCE_FILE" "$TARGET_DIR/$DEST_FILE" +} + +FILES=" + README + ChangeLog + + adler32.c + compress.c + crc32.c + crc32.h + deflate.c + deflate.h + gzclose.c + gzguts.h + gzlib.c + gzread.c + gzwrite.c + infback.c + inffast.c + inffast.h + inffixed.h + inflate.c + inflate.h + inftrees.c + inftrees.h + trees.c + trees.h + uncompr.c + zconf.h + zlib.h + zutil.c + zutil.h + +" + +for i in $FILES; do + copy_file "$i" "src/$i" +done + +cat << EOF + +Please do not forget to patch qtpatches.diff +The usual routine after this script is: + 1. Create commit to clean staging + 2. Apply qtpatches.diff with: + patch -p1 < qtpatches.diff + 3. Update the version in: ChangeLog and src/zlib.h + 4. Validate all changes and create new qtpatches.diff with: + git diff --relative > qtpatches.diff + 5. Add changed files and amend the commit with these files. + +If you want to revert the diff use: patch -p1 -Ri qtpatches.diff +EOF diff --git a/src/libs/3rdparty/zlib/qt_attribution.json b/src/libs/3rdparty/zlib/qt_attribution.json new file mode 100644 index 00000000000..88ed202db14 --- /dev/null +++ b/src/libs/3rdparty/zlib/qt_attribution.json @@ -0,0 +1,17 @@ +{ + "Id": "zlib", + "Name": "Data Compression Library (zlib)", + "QDocModule": "qtcore", + "QtUsage": "Optionally used in Qt Core and development tools. Configure with -system-zlib to avoid.", + "SecurityCritical": true, + + "Description": "zlib is a general purpose data compression library.", + "Homepage": "https://zlib.net/", + "Version": "1.3.1", + "DownloadLocation": "https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz", + + "License": "zlib License", + "LicenseId": "Zlib", + "LicenseFile": "LICENSE", + "Copyright": "(C) 1995-2024 Jean-loup Gailly and Mark Adler" +} diff --git a/src/libs/3rdparty/zlib/qtpatches.diff b/src/libs/3rdparty/zlib/qtpatches.diff new file mode 100644 index 00000000000..28be579dc9d --- /dev/null +++ b/src/libs/3rdparty/zlib/qtpatches.diff @@ -0,0 +1,124 @@ +diff --git a/src/ChangeLog b/src/ChangeLog +index b801a1031ec..686283a2aec 100644 +--- a/src/ChangeLog ++++ b/src/ChangeLog +@@ -1,6 +1,10 @@ + + ChangeLog file for zlib + ++Changes in 1.3.1 (Qt) (23 Jan 2024) ++- This is a stripped down copy of zlib that contains patches to ++ make it compile as part of Qt. See also "qtpatches.diff". ++ + Changes in 1.3.1 (22 Jan 2024) + - Reject overflows of zip header fields in minizip + - Fix bug in inflateSync() for data held in bit buffer +diff --git a/src/README b/src/README +index c5f917540b6..af6b4f32bf5 100644 +--- a/src/README ++++ b/src/README +@@ -6,6 +6,9 @@ thread safe. The data format used by the zlib library is described by RFCs + http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and + rfc1952 (gzip format). + ++This is a stripped down copy of zlib that contains patches to make it compile ++as part of Qt. See also "qtpatches.diff". ++ + All functions of the compression library are documented in the file zlib.h + (volunteer to write man pages welcome, contact zlib@gzip.org). A usage example + of the library is given in the file test/example.c which also tests that +diff --git a/src/gzguts.h b/src/gzguts.h +index eba72085bb7..5bf6b7d4813 100644 +--- a/src/gzguts.h ++++ b/src/gzguts.h +@@ -3,6 +3,12 @@ + * For conditions of distribution and use, see copyright notice in zlib.h + */ + ++#include ++ ++#ifdef QT_VISIBILITY_AVAILABLE ++#define HAVE_HIDDEN ++#endif ++ + #ifdef _LARGEFILE64_SOURCE + # ifndef _LARGEFILE_SOURCE + # define _LARGEFILE_SOURCE 1 +diff --git a/src/zconf.h b/src/zconf.h +index 62adc8d8431..4e14507a22d 100644 +--- a/src/zconf.h ++++ b/src/zconf.h +@@ -8,6 +8,9 @@ + #ifndef ZCONF_H + #define ZCONF_H + ++/* Since Qt Core must export these symbols, define Z_PREFIX to avoid clashes system zlib */ ++#define Z_PREFIX ++ + /* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. +@@ -139,6 +142,7 @@ + # endif + # define zlibCompileFlags z_zlibCompileFlags + # define zlibVersion z_zlibVersion ++# define z_errmsg z_z_errmsg + + /* all zlib typedefs in zlib.h and zconf.h */ + # define Byte z_Byte +@@ -433,7 +437,7 @@ typedef uLong FAR uLongf; + typedef unsigned long z_crc_t; + #endif + +-#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ ++#if defined(HAVE_UNISTD_H) || !defined(WIN32) + # define Z_HAVE_UNISTD_H + #endif + +diff --git a/src/zlib.h b/src/zlib.h +index 8d4b932eaf6..2cff72ee865 100644 +--- a/src/zlib.h ++++ b/src/zlib.h +@@ -33,11 +33,15 @@ + + #include "zconf.h" + ++#include ++#undef ZEXTERN ++#define ZEXTERN Q_CORE_EXPORT ++ + #ifdef __cplusplus + extern "C" { + #endif + +-#define ZLIB_VERSION "1.3.1" ++#define ZLIB_VERSION "1.3.1 (Qt)" + #define ZLIB_VERNUM 0x1310 + #define ZLIB_VER_MAJOR 1 + #define ZLIB_VER_MINOR 3 +diff --git a/src/zutil.h b/src/zutil.h +index 48dd7febae6..71dd616ab8d 100644 +--- a/src/zutil.h ++++ b/src/zutil.h +@@ -13,6 +13,12 @@ + #ifndef ZUTIL_H + #define ZUTIL_H + ++#include ++ ++#ifdef QT_VISIBILITY_AVAILABLE ++#define HAVE_HIDDEN ++#endif ++ + #ifdef HAVE_HIDDEN + # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) + #else +@@ -157,7 +163,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ + # define OS_CODE 18 + #endif + +-#ifdef __APPLE__ ++#if defined(__APPLE__) && !defined(OS_CODE) + # define OS_CODE 19 + #endif + diff --git a/src/libs/3rdparty/zlib/src/ChangeLog b/src/libs/3rdparty/zlib/src/ChangeLog new file mode 100644 index 00000000000..26541ea7928 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/ChangeLog @@ -0,0 +1,1622 @@ + + ChangeLog file for zlib + +Changes in 1.3.1 (Qt) (23 Jan 2024) +- This is a stripped down copy of zlib that contains patches to + make it compile as part of Qt. See also "qtpatches.diff". + +Changes in 1.3.1 (22 Jan 2024) +- Reject overflows of zip header fields in minizip +- Fix bug in inflateSync() for data held in bit buffer +- Add LIT_MEM define to use more memory for a small deflate speedup +- Fix decision on the emission of Zip64 end records in minizip +- Add bounds checking to ERR_MSG() macro, used by zError() +- Neutralize zip file traversal attacks in miniunz +- Fix a bug in ZLIB_DEBUG compiles in check_match() +- Various portability and appearance improvements + +Changes in 1.3 (18 Aug 2023) +- Remove K&R function definitions and zlib2ansi +- Fix bug in deflateBound() for level 0 and memLevel 9 +- Fix bug when gzungetc() is used immediately after gzopen() +- Fix bug when using gzflush() with a very small buffer +- Fix crash when gzsetparams() attempted for transparent write +- Fix test/example.c to work with FORCE_STORED +- Rewrite of zran in examples (see zran.c version history) +- Fix minizip to allow it to open an empty zip file +- Fix reading disk number start on zip64 files in minizip +- Fix logic error in minizip argument processing +- Add minizip testing to Makefile +- Read multiple bytes instead of byte-by-byte in minizip unzip.c +- Add memory sanitizer to configure (--memory) +- Various portability improvements +- Various documentation improvements +- Various spelling and typo corrections + +Changes in 1.2.13 (13 Oct 2022) +- Fix configure issue that discarded provided CC definition +- Correct incorrect inputs provided to the CRC functions +- Repair prototypes and exporting of new CRC functions +- Fix inflateBack to detect invalid input with distances too far +- Have infback() deliver all of the available output up to any error +- Fix a bug when getting a gzip header extra field with inflate() +- Fix bug in block type selection when Z_FIXED used +- Tighten deflateBound bounds +- Remove deleted assembler code references +- Various portability and appearance improvements + +Changes in 1.2.12 (27 Mar 2022) +- Cygwin does not have _wopen(), so do not create gzopen_w() there +- Permit a deflateParams() parameter change as soon as possible +- Limit hash table inserts after switch from stored deflate +- Fix bug when window full in deflate_stored() +- Fix CLEAR_HASH macro to be usable as a single statement +- Avoid a conversion error in gzseek when off_t type too small +- Have Makefile return non-zero error code on test failure +- Avoid some conversion warnings in gzread.c and gzwrite.c +- Update use of errno for newer Windows CE versions +- Small speedup to inflate [psumbera] +- Return an error if the gzputs string length can't fit in an int +- Add address checking in clang to -w option of configure +- Don't compute check value for raw inflate if asked to validate +- Handle case where inflateSync used when header never processed +- Avoid the use of ptrdiff_t +- Avoid an undefined behavior of memcpy() in gzappend() +- Avoid undefined behaviors of memcpy() in gz*printf() +- Avoid an undefined behavior of memcpy() in _tr_stored_block() +- Make the names in functions declarations identical to definitions +- Remove old assembler code in which bugs have manifested +- Fix deflateEnd() to not report an error at start of raw deflate +- Add legal disclaimer to README +- Emphasize the need to continue decompressing gzip members +- Correct the initialization requirements for deflateInit2() +- Fix a bug that can crash deflate on some input when using Z_FIXED +- Assure that the number of bits for deflatePrime() is valid +- Use a structure to make globals in enough.c evident +- Use a macro for the printf format of big_t in enough.c +- Clean up code style in enough.c, update version +- Use inline function instead of macro for index in enough.c +- Clarify that prefix codes are counted in enough.c +- Show all the codes for the maximum tables size in enough.c +- Add gznorm.c example, which normalizes gzip files +- Fix the zran.c example to work on a multiple-member gzip file +- Add tables for crc32_combine(), to speed it up by a factor of 200 +- Add crc32_combine_gen() and crc32_combine_op() for fast combines +- Speed up software CRC-32 computation by a factor of 1.5 to 3 +- Use atomic test and set, if available, for dynamic CRC tables +- Don't bother computing check value after successful inflateSync() +- Correct comment in crc32.c +- Add use of the ARMv8 crc32 instructions when requested +- Use ARM crc32 instructions if the ARM architecture has them +- Explicitly note that the 32-bit check values are 32 bits +- Avoid adding empty gzip member after gzflush with Z_FINISH +- Fix memory leak on error in gzlog.c +- Fix error in comment on the polynomial representation of a byte +- Clarify gz* function interfaces, referring to parameter names +- Change macro name in inflate.c to avoid collision in VxWorks +- Correct typo in blast.c +- Improve portability of contrib/minizip +- Fix indentation in minizip's zip.c +- Replace black/white with allow/block. (theresa-m) +- minizip warning fix if MAXU32 already defined. (gvollant) +- Fix unztell64() in minizip to work past 4GB. (Daniël Hörchner) +- Clean up minizip to reduce warnings for testing +- Add fallthrough comments for gcc +- Eliminate use of ULL constants +- Separate out address sanitizing from warnings in configure +- Remove destructive aspects of make distclean +- Check for cc masquerading as gcc or clang in configure +- Fix crc32.c to compile local functions only if used + +Changes in 1.2.11 (15 Jan 2017) +- Fix deflate stored bug when pulling last block from window +- Permit immediate deflateParams changes before any deflate input + +Changes in 1.2.10 (2 Jan 2017) +- Avoid warnings on snprintf() return value +- Fix bug in deflate_stored() for zero-length input +- Fix bug in gzwrite.c that produced corrupt gzip files +- Remove files to be installed before copying them in Makefile.in +- Add warnings when compiling with assembler code + +Changes in 1.2.9 (31 Dec 2016) +- Fix contrib/minizip to permit unzipping with desktop API [Zouzou] +- Improve contrib/blast to return unused bytes +- Assure that gzoffset() is correct when appending +- Improve compress() and uncompress() to support large lengths +- Fix bug in test/example.c where error code not saved +- Remedy Coverity warning [Randers-Pehrson] +- Improve speed of gzprintf() in transparent mode +- Fix inflateInit2() bug when windowBits is 16 or 32 +- Change DEBUG macro to ZLIB_DEBUG +- Avoid uninitialized access by gzclose_w() +- Allow building zlib outside of the source directory +- Fix bug that accepted invalid zlib header when windowBits is zero +- Fix gzseek() problem on MinGW due to buggy _lseeki64 there +- Loop on write() calls in gzwrite.c in case of non-blocking I/O +- Add --warn (-w) option to ./configure for more compiler warnings +- Reject a window size of 256 bytes if not using the zlib wrapper +- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE +- Add --debug (-d) option to ./configure to define ZLIB_DEBUG +- Fix bugs in creating a very large gzip header +- Add uncompress2() function, which returns the input size used +- Assure that deflateParams() will not switch functions mid-block +- Dramatically speed up deflation for level 0 (storing) +- Add gzfread(), duplicating the interface of fread() +- Add gzfwrite(), duplicating the interface of fwrite() +- Add deflateGetDictionary() function +- Use snprintf() for later versions of Microsoft C +- Fix *Init macros to use z_ prefix when requested +- Replace as400 with os400 for OS/400 support [Monnerat] +- Add crc32_z() and adler32_z() functions with size_t lengths +- Update Visual Studio project files [AraHaan] + +Changes in 1.2.8 (28 Apr 2013) +- Update contrib/minizip/iowin32.c for Windows RT [Vollant] +- Do not force Z_CONST for C++ +- Clean up contrib/vstudio [Roß] +- Correct spelling error in zlib.h +- Fix mixed line endings in contrib/vstudio + +Changes in 1.2.7.3 (13 Apr 2013) +- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc + +Changes in 1.2.7.2 (13 Apr 2013) +- Change check for a four-byte type back to hexadecimal +- Fix typo in win32/Makefile.msc +- Add casts in gzwrite.c for pointer differences + +Changes in 1.2.7.1 (24 Mar 2013) +- Replace use of unsafe string functions with snprintf if available +- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink] +- Fix gzgetc undefine when Z_PREFIX set [Turk] +- Eliminate use of mktemp in Makefile (not always available) +- Fix bug in 'F' mode for gzopen() +- Add inflateGetDictionary() function +- Correct comment in deflate.h +- Use _snprintf for snprintf in Microsoft C +- On Darwin, only use /usr/bin/libtool if libtool is not Apple +- Delete "--version" file if created by "ar --version" [Richard G.] +- Fix configure check for veracity of compiler error return codes +- Fix CMake compilation of static lib for MSVC2010 x64 +- Remove unused variable in infback9.c +- Fix argument checks in gzlog_compress() and gzlog_write() +- Clean up the usage of z_const and respect const usage within zlib +- Clean up examples/gzlog.[ch] comparisons of different types +- Avoid shift equal to bits in type (caused endless loop) +- Fix uninitialized value bug in gzputc() introduced by const patches +- Fix memory allocation error in examples/zran.c [Nor] +- Fix bug where gzopen(), gzclose() would write an empty file +- Fix bug in gzclose() when gzwrite() runs out of memory +- Check for input buffer malloc failure in examples/gzappend.c +- Add note to contrib/blast to use binary mode in stdio +- Fix comparisons of differently signed integers in contrib/blast +- Check for invalid code length codes in contrib/puff +- Fix serious but very rare decompression bug in inftrees.c +- Update inflateBack() comments, since inflate() can be faster +- Use underscored I/O function names for WINAPI_FAMILY +- Add _tr_flush_bits to the external symbols prefixed by --zprefix +- Add contrib/vstudio/vc10 pre-build step for static only +- Quote --version-script argument in CMakeLists.txt +- Don't specify --version-script on Apple platforms in CMakeLists.txt +- Fix casting error in contrib/testzlib/testzlib.c +- Fix types in contrib/minizip to match result of get_crc_table() +- Simplify contrib/vstudio/vc10 with 'd' suffix +- Add TOP support to win32/Makefile.msc +- Support i686 and amd64 assembler builds in CMakeLists.txt +- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h +- Add vc11 and vc12 build files to contrib/vstudio +- Add gzvprintf() as an undocumented function in zlib +- Fix configure for Sun shell +- Remove runtime check in configure for four-byte integer type +- Add casts and consts to ease user conversion to C++ +- Add man pages for minizip and miniunzip +- In Makefile uninstall, don't rm if preceding cd fails +- Do not return Z_BUF_ERROR if deflateParam() has nothing to write + +Changes in 1.2.7 (2 May 2012) +- Replace use of memmove() with a simple copy for portability +- Test for existence of strerror +- Restore gzgetc_ for backward compatibility with 1.2.6 +- Fix build with non-GNU make on Solaris +- Require gcc 4.0 or later on Mac OS X to use the hidden attribute +- Include unistd.h for Watcom C +- Use __WATCOMC__ instead of __WATCOM__ +- Do not use the visibility attribute if NO_VIZ defined +- Improve the detection of no hidden visibility attribute +- Avoid using __int64 for gcc or solo compilation +- Cast to char * in gzprintf to avoid warnings [Zinser] +- Fix make_vms.com for VAX [Zinser] +- Don't use library or built-in byte swaps +- Simplify test and use of gcc hidden attribute +- Fix bug in gzclose_w() when gzwrite() fails to allocate memory +- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen() +- Fix bug in test/minigzip.c for configure --solo +- Fix contrib/vstudio project link errors [Mohanathas] +- Add ability to choose the builder in make_vms.com [Schweda] +- Add DESTDIR support to mingw32 win32/Makefile.gcc +- Fix comments in win32/Makefile.gcc for proper usage +- Allow overriding the default install locations for cmake +- Generate and install the pkg-config file with cmake +- Build both a static and a shared version of zlib with cmake +- Include version symbols for cmake builds +- If using cmake with MSVC, add the source directory to the includes +- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta] +- Move obsolete emx makefile to old [Truta] +- Allow the use of -Wundef when compiling or using zlib +- Avoid the use of the -u option with mktemp +- Improve inflate() documentation on the use of Z_FINISH +- Recognize clang as gcc +- Add gzopen_w() in Windows for wide character path names +- Rename zconf.h in CMakeLists.txt to move it out of the way +- Add source directory in CMakeLists.txt for building examples +- Look in build directory for zlib.pc in CMakeLists.txt +- Remove gzflags from zlibvc.def in vc9 and vc10 +- Fix contrib/minizip compilation in the MinGW environment +- Update ./configure for Solaris, support --64 [Mooney] +- Remove -R. from Solaris shared build (possible security issue) +- Avoid race condition for parallel make (-j) running example +- Fix type mismatch between get_crc_table() and crc_table +- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler] +- Fix the path to zlib.map in CMakeLists.txt +- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe] +- Add instructions to win32/Makefile.gcc for shared install [Torri] + +Changes in 1.2.6.1 (12 Feb 2012) +- Avoid the use of the Objective-C reserved name "id" +- Include io.h in gzguts.h for Microsoft compilers +- Fix problem with ./configure --prefix and gzgetc macro +- Include gz_header definition when compiling zlib solo +- Put gzflags() functionality back in zutil.c +- Avoid library header include in crc32.c for Z_SOLO +- Use name in GCC_CLASSIC as C compiler for coverage testing, if set +- Minor cleanup in contrib/minizip/zip.c [Vollant] +- Update make_vms.com [Zinser] +- Remove unnecessary gzgetc_ function +- Use optimized byte swap operations for Microsoft and GNU [Snyder] +- Fix minor typo in zlib.h comments [Rzesniowiecki] + +Changes in 1.2.6 (29 Jan 2012) +- Update the Pascal interface in contrib/pascal +- Fix function numbers for gzgetc_ in zlibvc.def files +- Fix configure.ac for contrib/minizip [Schiffer] +- Fix large-entry detection in minizip on 64-bit systems [Schiffer] +- Have ./configure use the compiler return code for error indication +- Fix CMakeLists.txt for cross compilation [McClure] +- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes] +- Fix compilation of contrib/minizip on FreeBSD [Marquez] +- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath] +- Include io.h for Turbo C / Borland C on all platforms [Truta] +- Make version explicit in contrib/minizip/configure.ac [Bosmans] +- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant] +- Minor cleanup up contrib/minizip/unzip.c [Vollant] +- Fix bug when compiling minizip with C++ [Vollant] +- Protect for long name and extra fields in contrib/minizip [Vollant] +- Avoid some warnings in contrib/minizip [Vollant] +- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip +- Add missing libs to minizip linker command +- Add support for VPATH builds in contrib/minizip +- Add an --enable-demos option to contrib/minizip/configure +- Add the generation of configure.log by ./configure +- Exit when required parameters not provided to win32/Makefile.gcc +- Have gzputc return the character written instead of the argument +- Use the -m option on ldconfig for BSD systems [Tobias] +- Correct in zlib.map when deflateResetKeep was added + +Changes in 1.2.5.3 (15 Jan 2012) +- Restore gzgetc function for binary compatibility +- Do not use _lseeki64 under Borland C++ [Truta] +- Update win32/Makefile.msc to build test/*.c [Truta] +- Remove old/visualc6 given CMakefile and other alternatives +- Update AS400 build files and documentation [Monnerat] +- Update win32/Makefile.gcc to build test/*.c [Truta] +- Permit stronger flushes after Z_BLOCK flushes +- Avoid extraneous empty blocks when doing empty flushes +- Permit Z_NULL arguments to deflatePending +- Allow deflatePrime() to insert bits in the middle of a stream +- Remove second empty static block for Z_PARTIAL_FLUSH +- Write out all of the available bits when using Z_BLOCK +- Insert the first two strings in the hash table after a flush + +Changes in 1.2.5.2 (17 Dec 2011) +- fix ld error: unable to find version dependency 'ZLIB_1.2.5' +- use relative symlinks for shared libs +- Avoid searching past window for Z_RLE strategy +- Assure that high-water mark initialization is always applied in deflate +- Add assertions to fill_window() in deflate.c to match comments +- Update python link in README +- Correct spelling error in gzread.c +- Fix bug in gzgets() for a concatenated empty gzip stream +- Correct error in comment for gz_make() +- Change gzread() and related to ignore junk after gzip streams +- Allow gzread() and related to continue after gzclearerr() +- Allow gzrewind() and gzseek() after a premature end-of-file +- Simplify gzseek() now that raw after gzip is ignored +- Change gzgetc() to a macro for speed (~40% speedup in testing) +- Fix gzclose() to return the actual error last encountered +- Always add large file support for windows +- Include zconf.h for windows large file support +- Include zconf.h.cmakein for windows large file support +- Update zconf.h.cmakein on make distclean +- Merge vestigial vsnprintf determination from zutil.h to gzguts.h +- Clarify how gzopen() appends in zlib.h comments +- Correct documentation of gzdirect() since junk at end now ignored +- Add a transparent write mode to gzopen() when 'T' is in the mode +- Update python link in zlib man page +- Get inffixed.h and MAKEFIXED result to match +- Add a ./config --solo option to make zlib subset with no library use +- Add undocumented inflateResetKeep() function for CAB file decoding +- Add --cover option to ./configure for gcc coverage testing +- Add #define ZLIB_CONST option to use const in the z_stream interface +- Add comment to gzdopen() in zlib.h to use dup() when using fileno() +- Note behavior of uncompress() to provide as much data as it can +- Add files in contrib/minizip to aid in building libminizip +- Split off AR options in Makefile.in and configure +- Change ON macro to Z_ARG to avoid application conflicts +- Facilitate compilation with Borland C++ for pragmas and vsnprintf +- Include io.h for Turbo C / Borland C++ +- Move example.c and minigzip.c to test/ +- Simplify incomplete code table filling in inflate_table() +- Remove code from inflate.c and infback.c that is impossible to execute +- Test the inflate code with full coverage +- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw) +- Add deflateResetKeep and fix inflateResetKeep to retain dictionary +- Fix gzwrite.c to accommodate reduced memory zlib compilation +- Have inflate() with Z_FINISH avoid the allocation of a window +- Do not set strm->adler when doing raw inflate +- Fix gzeof() to behave just like feof() when read is not past end of file +- Fix bug in gzread.c when end-of-file is reached +- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF +- Document gzread() capability to read concurrently written files +- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo] + +Changes in 1.2.5.1 (10 Sep 2011) +- Update FAQ entry on shared builds (#13) +- Avoid symbolic argument to chmod in Makefile.in +- Fix bug and add consts in contrib/puff [Oberhumer] +- Update contrib/puff/zeros.raw test file to have all block types +- Add full coverage test for puff in contrib/puff/Makefile +- Fix static-only-build install in Makefile.in +- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno] +- Add libz.a dependency to shared in Makefile.in for parallel builds +- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out +- Replace $(...) with `...` in configure for non-bash sh [Bowler] +- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen] +- Add solaris* to Linux* in configure to allow gcc use [Groffen] +- Add *bsd* to Linux* case in configure [Bar-Lev] +- Add inffast.obj to dependencies in win32/Makefile.msc +- Correct spelling error in deflate.h [Kohler] +- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc +- Add test to configure for GNU C looking for gcc in output of $cc -v +- Add zlib.pc generation to win32/Makefile.gcc [Weigelt] +- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not +- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense +- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser) +- Make stronger test in zconf.h to include unistd.h for LFS +- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack] +- Fix zlib.h LFS support when Z_PREFIX used +- Add updated as400 support (removed from old) [Monnerat] +- Avoid deflate sensitivity to volatile input data +- Avoid division in adler32_combine for NO_DIVIDE +- Clarify the use of Z_FINISH with deflateBound() amount of space +- Set binary for output file in puff.c +- Use u4 type for crc_table to avoid conversion warnings +- Apply casts in zlib.h to avoid conversion warnings +- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] +- Improve inflateSync() documentation to note indeterminacy +- Add deflatePending() function to return the amount of pending output +- Correct the spelling of "specification" in FAQ [Randers-Pehrson] +- Add a check in configure for stdarg.h, use for gzprintf() +- Check that pointers fit in ints when gzprint() compiled old style +- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] +- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] +- Add debug records in assembler code [Londer] +- Update RFC references to use http://tools.ietf.org/html/... [Li] +- Add --archs option, use of libtool to configure for Mac OS X [Borstel] + +Changes in 1.2.5 (19 Apr 2010) +- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] +- Default to libdir as sharedlibdir in configure [Nieder] +- Update copyright dates on modified source files +- Update trees.c to be able to generate modified trees.h +- Exit configure for MinGW, suggesting win32/Makefile.gcc +- Check for NULL path in gz_open [Homurlu] + +Changes in 1.2.4.5 (18 Apr 2010) +- Set sharedlibdir in configure [Torok] +- Set LDFLAGS in Makefile.in [Bar-Lev] +- Avoid mkdir objs race condition in Makefile.in [Bowler] +- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays +- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C +- Don't use hidden attribute when it is a warning generator (e.g. Solaris) + +Changes in 1.2.4.4 (18 Apr 2010) +- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] +- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty +- Try to use bash or ksh regardless of functionality of /bin/sh +- Fix configure incompatibility with NetBSD sh +- Remove attempt to run under bash or ksh since have better NetBSD fix +- Fix win32/Makefile.gcc for MinGW [Bar-Lev] +- Add diagnostic messages when using CROSS_PREFIX in configure +- Added --sharedlibdir option to configure [Weigelt] +- Use hidden visibility attribute when available [Frysinger] + +Changes in 1.2.4.3 (10 Apr 2010) +- Only use CROSS_PREFIX in configure for ar and ranlib if they exist +- Use CROSS_PREFIX for nm [Bar-Lev] +- Assume _LARGEFILE64_SOURCE defined is equivalent to true +- Avoid use of undefined symbols in #if with && and || +- Make *64 prototypes in gzguts.h consistent with functions +- Add -shared load option for MinGW in configure [Bowler] +- Move z_off64_t to public interface, use instead of off64_t +- Remove ! from shell test in configure (not portable to Solaris) +- Change +0 macro tests to -0 for possibly increased portability + +Changes in 1.2.4.2 (9 Apr 2010) +- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 +- Really provide prototypes for *64 functions when building without LFS +- Only define unlink() in minigzip.c if unistd.h not included +- Update README to point to contrib/vstudio project files +- Move projects/vc6 to old/ and remove projects/ +- Include stdlib.h in minigzip.c for setmode() definition under WinCE +- Clean up assembler builds in win32/Makefile.msc [Rowe] +- Include sys/types.h for Microsoft for off_t definition +- Fix memory leak on error in gz_open() +- Symbolize nm as $NM in configure [Weigelt] +- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] +- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined +- Fix bug in gzeof() to take into account unused input data +- Avoid initialization of structures with variables in puff.c +- Updated win32/README-WIN32.txt [Rowe] + +Changes in 1.2.4.1 (28 Mar 2010) +- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] +- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] +- Restore "for debugging" comment on sprintf() in gzlib.c +- Remove fdopen for MVS from gzguts.h +- Put new README-WIN32.txt in win32 [Rowe] +- Add check for shell to configure and invoke another shell if needed +- Fix big fat stinking bug in gzseek() on uncompressed files +- Remove vestigial F_OPEN64 define in zutil.h +- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE +- Avoid errors on non-LFS systems when applications define LFS macros +- Set EXE to ".exe" in configure for MINGW [Kahle] +- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] +- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] +- Add DLL install in win32/makefile.gcc [Bar-Lev] +- Allow Linux* or linux* from uname in configure [Bar-Lev] +- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] +- Add cross-compilation prefixes to configure [Bar-Lev] +- Match type exactly in gz_load() invocation in gzread.c +- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func +- Provide prototypes for *64 functions when building zlib without LFS +- Don't use -lc when linking shared library on MinGW +- Remove errno.h check in configure and vestigial errno code in zutil.h + +Changes in 1.2.4 (14 Mar 2010) +- Fix VER3 extraction in configure for no fourth subversion +- Update zlib.3, add docs to Makefile.in to make .pdf out of it +- Add zlib.3.pdf to distribution +- Don't set error code in gzerror() if passed pointer is NULL +- Apply destination directory fixes to CMakeLists.txt [Lowman] +- Move #cmakedefine's to a new zconf.in.cmakein +- Restore zconf.h for builds that don't use configure or cmake +- Add distclean to dummy Makefile for convenience +- Update and improve INDEX, README, and FAQ +- Update CMakeLists.txt for the return of zconf.h [Lowman] +- Update contrib/vstudio/vc9 and vc10 [Vollant] +- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc +- Apply license and readme changes to contrib/asm686 [Raiter] +- Check file name lengths and add -c option in minigzip.c [Li] +- Update contrib/amd64 and contrib/masmx86/ [Vollant] +- Avoid use of "eof" parameter in trees.c to not shadow library variable +- Update make_vms.com for removal of zlibdefs.h [Zinser] +- Update assembler code and vstudio projects in contrib [Vollant] +- Remove outdated assembler code contrib/masm686 and contrib/asm586 +- Remove old vc7 and vc8 from contrib/vstudio +- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] +- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() +- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] +- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) +- Fix bug in void-returning vsprintf() case in gzwrite.c +- Fix name change from inflate.h in contrib/inflate86/inffas86.c +- Check if temporary file exists before removing in make_vms.com [Zinser] +- Fix make install and uninstall for --static option +- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] +- Update readme.txt in contrib/masmx64 and masmx86 to assemble + +Changes in 1.2.3.9 (21 Feb 2010) +- Expunge gzio.c +- Move as400 build information to old +- Fix updates in contrib/minizip and contrib/vstudio +- Add const to vsnprintf test in configure to avoid warnings [Weigelt] +- Delete zconf.h (made by configure) [Weigelt] +- Change zconf.in.h to zconf.h.in per convention [Weigelt] +- Check for NULL buf in gzgets() +- Return empty string for gzgets() with len == 1 (like fgets()) +- Fix description of gzgets() in zlib.h for end-of-file, NULL return +- Update minizip to 1.1 [Vollant] +- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c +- Note in zlib.h that gzerror() should be used to distinguish from EOF +- Remove use of snprintf() from gzlib.c +- Fix bug in gzseek() +- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] +- Fix zconf.h generation in CMakeLists.txt [Lowman] +- Improve comments in zconf.h where modified by configure + +Changes in 1.2.3.8 (13 Feb 2010) +- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] +- Use z_off64_t in gz_zero() and gz_skip() to match state->skip +- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) +- Revert to Makefile.in from 1.2.3.6 (live with the clutter) +- Fix missing error return in gzflush(), add zlib.h note +- Add *64 functions to zlib.map [Levin] +- Fix signed/unsigned comparison in gz_comp() +- Use SFLAGS when testing shared linking in configure +- Add --64 option to ./configure to use -m64 with gcc +- Fix ./configure --help to correctly name options +- Have make fail if a test fails [Levin] +- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] +- Remove assembler object files from contrib + +Changes in 1.2.3.7 (24 Jan 2010) +- Always gzopen() with O_LARGEFILE if available +- Fix gzdirect() to work immediately after gzopen() or gzdopen() +- Make gzdirect() more precise when the state changes while reading +- Improve zlib.h documentation in many places +- Catch memory allocation failure in gz_open() +- Complete close operation if seek forward in gzclose_w() fails +- Return Z_ERRNO from gzclose_r() if close() fails +- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL +- Return zero for gzwrite() errors to match zlib.h description +- Return -1 on gzputs() error to match zlib.h description +- Add zconf.in.h to allow recovery from configure modification [Weigelt] +- Fix static library permissions in Makefile.in [Weigelt] +- Avoid warnings in configure tests that hide functionality [Weigelt] +- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] +- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] +- Avoid access of uninitialized data for first inflateReset2 call [Gomes] +- Keep object files in subdirectories to reduce the clutter somewhat +- Remove default Makefile and zlibdefs.h, add dummy Makefile +- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ +- Remove zlibdefs.h completely -- modify zconf.h instead + +Changes in 1.2.3.6 (17 Jan 2010) +- Avoid void * arithmetic in gzread.c and gzwrite.c +- Make compilers happier with const char * for gz_error message +- Avoid unused parameter warning in inflate.c +- Avoid signed-unsigned comparison warning in inflate.c +- Indent #pragma's for traditional C +- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() +- Correct email address in configure for system options +- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] +- Update zlib.map [Brown] +- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] +- Apply various fixes to CMakeLists.txt [Lowman] +- Add checks on len in gzread() and gzwrite() +- Add error message for no more room for gzungetc() +- Remove zlib version check in gzwrite() +- Defer compression of gzprintf() result until need to +- Use snprintf() in gzdopen() if available +- Remove USE_MMAP configuration determination (only used by minigzip) +- Remove examples/pigz.c (available separately) +- Update examples/gun.c to 1.6 + +Changes in 1.2.3.5 (8 Jan 2010) +- Add space after #if in zutil.h for some compilers +- Fix relatively harmless bug in deflate_fast() [Exarevsky] +- Fix same problem in deflate_slow() +- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] +- Add deflate_rle() for faster Z_RLE strategy run-length encoding +- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding +- Change name of "write" variable in inffast.c to avoid library collisions +- Fix premature EOF from gzread() in gzio.c [Brown] +- Use zlib header window size if windowBits is 0 in inflateInit2() +- Remove compressBound() call in deflate.c to avoid linking compress.o +- Replace use of errno in gz* with functions, support WinCE [Alves] +- Provide alternative to perror() in minigzip.c for WinCE [Alves] +- Don't use _vsnprintf on later versions of MSVC [Lowman] +- Add CMake build script and input file [Lowman] +- Update contrib/minizip to 1.1 [Svensson, Vollant] +- Moved nintendods directory from contrib to root +- Replace gzio.c with a new set of routines with the same functionality +- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above +- Update contrib/minizip to 1.1b +- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h + +Changes in 1.2.3.4 (21 Dec 2009) +- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility +- Update comments in configure and Makefile.in for default --shared +- Fix test -z's in configure [Marquess] +- Build examplesh and minigzipsh when not testing +- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h +- Import LDFLAGS from the environment in configure +- Fix configure to populate SFLAGS with discovered CFLAGS options +- Adapt make_vms.com to the new Makefile.in [Zinser] +- Add zlib2ansi script for C++ compilation [Marquess] +- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) +- Add AMD64 assembler code for longest match to contrib [Teterin] +- Include options from $SFLAGS when doing $LDSHARED +- Simplify 64-bit file support by introducing z_off64_t type +- Make shared object files in objs directory to work around old Sun cc +- Use only three-part version number for Darwin shared compiles +- Add rc option to ar in Makefile.in for when ./configure not run +- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* +- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile +- Protect against _FILE_OFFSET_BITS being defined when compiling zlib +- Rename Makefile.in targets allstatic to static and allshared to shared +- Fix static and shared Makefile.in targets to be independent +- Correct error return bug in gz_open() by setting state [Brown] +- Put spaces before ;;'s in configure for better sh compatibility +- Add pigz.c (parallel implementation of gzip) to examples/ +- Correct constant in crc32.c to UL [Leventhal] +- Reject negative lengths in crc32_combine() +- Add inflateReset2() function to work like inflateEnd()/inflateInit2() +- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] +- Correct typo in doc/algorithm.txt [Janik] +- Fix bug in adler32_combine() [Zhu] +- Catch missing-end-of-block-code error in all inflates and in puff + Assures that random input to inflate eventually results in an error +- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ +- Update ENOUGH and its usage to reflect discovered bounds +- Fix gzerror() error report on empty input file [Brown] +- Add ush casts in trees.c to avoid pedantic runtime errors +- Fix typo in zlib.h uncompress() description [Reiss] +- Correct inflate() comments with regard to automatic header detection +- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) +- Put new version of gzlog (2.0) in examples with interruption recovery +- Add puff compile option to permit invalid distance-too-far streams +- Add puff TEST command options, ability to read piped input +- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but + _LARGEFILE64_SOURCE not defined +- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart +- Fix deflateSetDictionary() to use all 32K for output consistency +- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) +- Clear bytes after deflate lookahead to avoid use of uninitialized data +- Change a limit in inftrees.c to be more transparent to Coverity Prevent +- Update win32/zlib.def with exported symbols from zlib.h +- Correct spelling errors in zlib.h [Willem, Sobrado] +- Allow Z_BLOCK for deflate() to force a new block +- Allow negative bits in inflatePrime() to delete existing bit buffer +- Add Z_TREES flush option to inflate() to return at end of trees +- Add inflateMark() to return current state information for random access +- Add Makefile for NintendoDS to contrib [Costa] +- Add -w in configure compile tests to avoid spurious warnings [Beucler] +- Fix typos in zlib.h comments for deflateSetDictionary() +- Fix EOF detection in transparent gzread() [Maier] + +Changes in 1.2.3.3 (2 October 2006) +- Make --shared the default for configure, add a --static option +- Add compile option to permit invalid distance-too-far streams +- Add inflateUndermine() function which is required to enable above +- Remove use of "this" variable name for C++ compatibility [Marquess] +- Add testing of shared library in make test, if shared library built +- Use ftello() and fseeko() if available instead of ftell() and fseek() +- Provide two versions of all functions that use the z_off_t type for + binary compatibility -- a normal version and a 64-bit offset version, + per the Large File Support Extension when _LARGEFILE64_SOURCE is + defined; use the 64-bit versions by default when _FILE_OFFSET_BITS + is defined to be 64 +- Add a --uname= option to configure to perhaps help with cross-compiling + +Changes in 1.2.3.2 (3 September 2006) +- Turn off silly Borland warnings [Hay] +- Use off64_t and define _LARGEFILE64_SOURCE when present +- Fix missing dependency on inffixed.h in Makefile.in +- Rig configure --shared to build both shared and static [Teredesai, Truta] +- Remove zconf.in.h and instead create a new zlibdefs.h file +- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] +- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] + +Changes in 1.2.3.1 (16 August 2006) +- Add watcom directory with OpenWatcom make files [Daniel] +- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] +- Update make_vms.com [Zinser] +- Use -fPIC for shared build in configure [Teredesai, Nicholson] +- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] +- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck] +- Add some FAQ entries about the contrib directory +- Update the MVS question in the FAQ +- Avoid extraneous reads after EOF in gzio.c [Brown] +- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] +- Add comments to zlib.h about gzerror() usage [Brown] +- Set extra flags in gzip header in gzopen() like deflate() does +- Make configure options more compatible with double-dash conventions + [Weigelt] +- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] +- Fix uninstall target in Makefile.in [Truta] +- Add pkgconfig support [Weigelt] +- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] +- Replace set_data_type() with a more accurate detect_data_type() in + trees.c, according to the txtvsbin.txt document [Truta] +- Swap the order of #include and #include "zlib.h" in + gzio.c, example.c and minigzip.c [Truta] +- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, + Truta] (where?) +- Fix target "clean" from win32/Makefile.bor [Truta] +- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] +- Update zlib www home address in win32/DLL_FAQ.txt [Truta] +- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] +- Enable browse info in the "Debug" and "ASM Debug" configurations in + the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] +- Add pkgconfig support [Weigelt] +- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, + for use in win32/zlib1.rc [Polushin, Rowe, Truta] +- Add a document that explains the new text detection scheme to + doc/txtvsbin.txt [Truta] +- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] +- Move algorithm.txt into doc/ [Truta] +- Synchronize FAQ with website +- Fix compressBound(), was low for some pathological cases [Fearnley] +- Take into account wrapper variations in deflateBound() +- Set examples/zpipe.c input and output to binary mode for Windows +- Update examples/zlib_how.html with new zpipe.c (also web site) +- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems + that gcc became pickier in 4.0) +- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain + un-versioned, the patch adds versioning only for symbols introduced in + zlib-1.2.0 or later. It also declares as local those symbols which are + not designed to be exported." [Levin] +- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure +- Do not initialize global static by default in trees.c, add a response + NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] +- Don't use strerror() in gzio.c under WinCE [Yakimov] +- Don't use errno.h in zutil.h under WinCE [Yakimov] +- Move arguments for AR to its usage to allow replacing ar [Marot] +- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] +- Improve inflateInit() and inflateInit2() documentation +- Fix structure size comment in inflate.h +- Change configure help option from --h* to --help [Santos] + +Changes in 1.2.3 (18 July 2005) +- Apply security vulnerability fixes to contrib/infback9 as well +- Clean up some text files (carriage returns, trailing space) +- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] + +Changes in 1.2.2.4 (11 July 2005) +- Add inflatePrime() function for starting inflation at bit boundary +- Avoid some Visual C warnings in deflate.c +- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit + compile +- Fix some spelling errors in comments [Betts] +- Correct inflateInit2() error return documentation in zlib.h +- Add zran.c example of compressed data random access to examples + directory, shows use of inflatePrime() +- Fix cast for assignments to strm->state in inflate.c and infback.c +- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] +- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] +- Add cast in trees.c t avoid a warning [Oberhumer] +- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] +- Update make_vms.com [Zinser] +- Initialize state->write in inflateReset() since copied in inflate_fast() +- Be more strict on incomplete code sets in inflate_table() and increase + ENOUGH and MAXD -- this repairs a possible security vulnerability for + invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for + discovering the vulnerability and providing test cases +- Add ia64 support to configure for HP-UX [Smith] +- Add error return to gzread() for format or i/o error [Levin] +- Use malloc.h for OS/2 [Necasek] + +Changes in 1.2.2.3 (27 May 2005) +- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile +- Typecast fread() return values in gzio.c [Vollant] +- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) +- Fix crc check bug in gzread() after gzungetc() [Heiner] +- Add the deflateTune() function to adjust internal compression parameters +- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) +- Remove an incorrect assertion in examples/zpipe.c +- Add C++ wrapper in infback9.h [Donais] +- Fix bug in inflateCopy() when decoding fixed codes +- Note in zlib.h how much deflateSetDictionary() actually uses +- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) +- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] +- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] +- Add gzdirect() function to indicate transparent reads +- Update contrib/minizip [Vollant] +- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] +- Add casts in crc32.c to avoid warnings [Oberhumer] +- Add contrib/masmx64 [Vollant] +- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] + +Changes in 1.2.2.2 (30 December 2004) +- Replace structure assignments in deflate.c and inflate.c with zmemcpy to + avoid implicit memcpy calls (portability for no-library compilation) +- Increase sprintf() buffer size in gzdopen() to allow for large numbers +- Add INFLATE_STRICT to check distances against zlib header +- Improve WinCE errno handling and comments [Chang] +- Remove comment about no gzip header processing in FAQ +- Add Z_FIXED strategy option to deflateInit2() to force fixed trees +- Add updated make_vms.com [Coghlan], update README +- Create a new "examples" directory, move gzappend.c there, add zpipe.c, + fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html +- Add FAQ entry and comments in deflate.c on uninitialized memory access +- Add Solaris 9 make options in configure [Gilbert] +- Allow strerror() usage in gzio.c for STDC +- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] +- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] +- Use z_off_t for adler32_combine() and crc32_combine() lengths +- Make adler32() much faster for small len +- Use OS_CODE in deflate() default gzip header + +Changes in 1.2.2.1 (31 October 2004) +- Allow inflateSetDictionary() call for raw inflate +- Fix inflate header crc check bug for file names and comments +- Add deflateSetHeader() and gz_header structure for custom gzip headers +- Add inflateGetheader() to retrieve gzip headers +- Add crc32_combine() and adler32_combine() functions +- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list +- Use zstreamp consistently in zlib.h (inflate_back functions) +- Remove GUNZIP condition from definition of inflate_mode in inflate.h + and in contrib/inflate86/inffast.S [Truta, Anderson] +- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] +- Update projects/README.projects and projects/visualc6 [Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] +- Deprecate Z_ASCII; use Z_TEXT instead [Truta] +- Use a new algorithm for setting strm->data_type in trees.c [Truta] +- Do not define an exit() prototype in zutil.c unless DEBUG defined +- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] +- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() +- Fix Darwin build version identification [Peterson] + +Changes in 1.2.2 (3 October 2004) +- Update zlib.h comments on gzip in-memory processing +- Set adler to 1 in inflateReset() to support Java test suite [Walles] +- Add contrib/dotzlib [Ravn] +- Update win32/DLL_FAQ.txt [Truta] +- Update contrib/minizip [Vollant] +- Move contrib/visual-basic.txt to old/ [Truta] +- Fix assembler builds in projects/visualc6/ [Truta] + +Changes in 1.2.1.2 (9 September 2004) +- Update INDEX file +- Fix trees.c to update strm->data_type (no one ever noticed!) +- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] +- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) +- Add limited multitasking protection to DYNAMIC_CRC_TABLE +- Add NO_vsnprintf for VMS in zutil.h [Mozilla] +- Don't declare strerror() under VMS [Mozilla] +- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize +- Update contrib/ada [Anisimkov] +- Update contrib/minizip [Vollant] +- Fix configure to not hardcode directories for Darwin [Peterson] +- Fix gzio.c to not return error on empty files [Brown] +- Fix indentation; update version in contrib/delphi/ZLib.pas and + contrib/pascal/zlibpas.pas [Truta] +- Update mkasm.bat in contrib/masmx86 [Truta] +- Update contrib/untgz [Truta] +- Add projects/README.projects [Truta] +- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] +- Remove an unnecessary assignment to curr in inftrees.c [Truta] +- Add OS/2 to exe builds in configure [Poltorak] +- Remove err dummy parameter in zlib.h [Kientzle] + +Changes in 1.2.1.1 (9 January 2004) +- Update email address in README +- Several FAQ updates +- Fix a big fat bug in inftrees.c that prevented decoding valid + dynamic blocks with only literals and no distance codes -- + Thanks to "Hot Emu" for the bug report and sample file +- Add a note to puff.c on no distance codes case + +Changes in 1.2.1 (17 November 2003) +- Remove a tab in contrib/gzappend/gzappend.c +- Update some interfaces in contrib for new zlib functions +- Update zlib version number in some contrib entries +- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] +- Support shared libraries on Hurd and KFreeBSD [Brown] +- Fix error in NO_DIVIDE option of adler32.c + +Changes in 1.2.0.8 (4 November 2003) +- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas +- Add experimental NO_DIVIDE #define in adler32.c + - Possibly faster on some processors (let me know if it is) +- Correct Z_BLOCK to not return on first inflate call if no wrap +- Fix strm->data_type on inflate() return to correctly indicate EOB +- Add deflatePrime() function for appending in the middle of a byte +- Add contrib/gzappend for an example of appending to a stream +- Update win32/DLL_FAQ.txt [Truta] +- Delete Turbo C comment in README [Truta] +- Improve some indentation in zconf.h [Truta] +- Fix infinite loop on bad input in configure script [Church] +- Fix gzeof() for concatenated gzip files [Johnson] +- Add example to contrib/visual-basic.txt [Michael B.] +- Add -p to mkdir's in Makefile.in [vda] +- Fix configure to properly detect presence or lack of printf functions +- Add AS400 support [Monnerat] +- Add a little Cygwin support [Wilson] + +Changes in 1.2.0.7 (21 September 2003) +- Correct some debug formats in contrib/infback9 +- Cast a type in a debug statement in trees.c +- Change search and replace delimiter in configure from % to # [Beebe] +- Update contrib/untgz to 0.2 with various fixes [Truta] +- Add build support for Amiga [Nikl] +- Remove some directories in old that have been updated to 1.2 +- Add dylib building for Mac OS X in configure and Makefile.in +- Remove old distribution stuff from Makefile +- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X +- Update links in README + +Changes in 1.2.0.6 (13 September 2003) +- Minor FAQ updates +- Update contrib/minizip to 1.00 [Vollant] +- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] +- Update POSTINC comment for 68060 [Nikl] +- Add contrib/infback9 with deflate64 decoding (unsupported) +- For MVS define NO_vsnprintf and undefine FAR [van Burik] +- Add pragma for fdopen on MVS [van Burik] + +Changes in 1.2.0.5 (8 September 2003) +- Add OF to inflateBackEnd() declaration in zlib.h +- Remember start when using gzdopen in the middle of a file +- Use internal off_t counters in gz* functions to properly handle seeks +- Perform more rigorous check for distance-too-far in inffast.c +- Add Z_BLOCK flush option to return from inflate at block boundary +- Set strm->data_type on return from inflate + - Indicate bits unused, if at block boundary, and if in last block +- Replace size_t with ptrdiff_t in crc32.c, and check for correct size +- Add condition so old NO_DEFLATE define still works for compatibility +- FAQ update regarding the Windows DLL [Truta] +- INDEX update: add qnx entry, remove aix entry [Truta] +- Install zlib.3 into mandir [Wilson] +- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] +- Adapt the zlib interface to the new DLL convention guidelines [Truta] +- Introduce ZLIB_WINAPI macro to allow the export of functions using + the WINAPI calling convention, for Visual Basic [Vollant, Truta] +- Update msdos and win32 scripts and makefiles [Truta] +- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] +- Add contrib/ada [Anisimkov] +- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] +- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] +- Add contrib/masm686 [Truta] +- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm + [Truta, Vollant] +- Update contrib/delphi; rename to contrib/pascal; add example [Truta] +- Remove contrib/delphi2; add a new contrib/delphi [Truta] +- Avoid inclusion of the nonstandard in contrib/iostream, + and fix some method prototypes [Truta] +- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip + [Truta] +- Avoid the use of backslash (\) in contrib/minizip [Vollant] +- Fix file time handling in contrib/untgz; update makefiles [Truta] +- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines + [Vollant] +- Remove contrib/vstudio/vc15_16 [Vollant] +- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] +- Update README.contrib [Truta] +- Invert the assignment order of match_head and s->prev[...] in + INSERT_STRING [Truta] +- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings + [Truta] +- Compare function pointers with 0, not with NULL or Z_NULL [Truta] +- Fix prototype of syncsearch in inflate.c [Truta] +- Introduce ASMINF macro to be enabled when using an ASM implementation + of inflate_fast [Truta] +- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] +- Modify test_gzio in example.c to take a single file name as a + parameter [Truta] +- Exit the example.c program if gzopen fails [Truta] +- Add type casts around strlen in example.c [Truta] +- Remove casting to sizeof in minigzip.c; give a proper type + to the variable compared with SUFFIX_LEN [Truta] +- Update definitions of STDC and STDC99 in zconf.h [Truta] +- Synchronize zconf.h with the new Windows DLL interface [Truta] +- Use SYS16BIT instead of __32BIT__ to distinguish between + 16- and 32-bit platforms [Truta] +- Use far memory allocators in small 16-bit memory models for + Turbo C [Truta] +- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in + zlibCompileFlags [Truta] +- Cygwin has vsnprintf [Wilson] +- In Windows16, OS_CODE is 0, as in MSDOS [Truta] +- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] + +Changes in 1.2.0.4 (10 August 2003) +- Minor FAQ updates +- Be more strict when checking inflateInit2's windowBits parameter +- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well +- Add gzip wrapper option to deflateInit2 using windowBits +- Add updated QNX rule in configure and qnx directory [Bonnefoy] +- Make inflate distance-too-far checks more rigorous +- Clean up FAR usage in inflate +- Add casting to sizeof() in gzio.c and minigzip.c + +Changes in 1.2.0.3 (19 July 2003) +- Fix silly error in gzungetc() implementation [Vollant] +- Update contrib/minizip and contrib/vstudio [Vollant] +- Fix printf format in example.c +- Correct cdecl support in zconf.in.h [Anisimkov] +- Minor FAQ updates + +Changes in 1.2.0.2 (13 July 2003) +- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons +- Attempt to avoid warnings in crc32.c for pointer-int conversion +- Add AIX to configure, remove aix directory [Bakker] +- Add some casts to minigzip.c +- Improve checking after insecure sprintf() or vsprintf() calls +- Remove #elif's from crc32.c +- Change leave label to inf_leave in inflate.c and infback.c to avoid + library conflicts +- Remove inflate gzip decoding by default--only enable gzip decoding by + special request for stricter backward compatibility +- Add zlibCompileFlags() function to return compilation information +- More typecasting in deflate.c to avoid warnings +- Remove leading underscore from _Capital #defines [Truta] +- Fix configure to link shared library when testing +- Add some Windows CE target adjustments [Mai] +- Remove #define ZLIB_DLL in zconf.h [Vollant] +- Add zlib.3 [Rodgers] +- Update RFC URL in deflate.c and algorithm.txt [Mai] +- Add zlib_dll_FAQ.txt to contrib [Truta] +- Add UL to some constants [Truta] +- Update minizip and vstudio [Vollant] +- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h +- Expand use of NO_DUMMY_DECL to avoid all dummy structures +- Added iostream3 to contrib [Schwardt] +- Replace rewind() with fseek() for WinCE [Truta] +- Improve setting of zlib format compression level flags + - Report 0 for huffman and rle strategies and for level == 0 or 1 + - Report 2 only for level == 6 +- Only deal with 64K limit when necessary at compile time [Truta] +- Allow TOO_FAR check to be turned off at compile time [Truta] +- Add gzclearerr() function [Souza] +- Add gzungetc() function + +Changes in 1.2.0.1 (17 March 2003) +- Add Z_RLE strategy for run-length encoding [Truta] + - When Z_RLE requested, restrict matches to distance one + - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE +- Correct FASTEST compilation to allow level == 0 +- Clean up what gets compiled for FASTEST +- Incorporate changes to zconf.in.h [Vollant] + - Refine detection of Turbo C need for dummy returns + - Refine ZLIB_DLL compilation + - Include additional header file on VMS for off_t typedef +- Try to use _vsnprintf where it supplants vsprintf [Vollant] +- Add some casts in inffast.c +- Enhance comments in zlib.h on what happens if gzprintf() tries to + write more than 4095 bytes before compression +- Remove unused state from inflateBackEnd() +- Remove exit(0) from minigzip.c, example.c +- Get rid of all those darn tabs +- Add "check" target to Makefile.in that does the same thing as "test" +- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in +- Update contrib/inflate86 [Anderson] +- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] +- Add msdos and win32 directories with makefiles [Truta] +- More additions and improvements to the FAQ + +Changes in 1.2.0 (9 March 2003) +- New and improved inflate code + - About 20% faster + - Does not allocate 32K window unless and until needed + - Automatically detects and decompresses gzip streams + - Raw inflate no longer needs an extra dummy byte at end + - Added inflateBack functions using a callback interface--even faster + than inflate, useful for file utilities (gzip, zip) + - Added inflateCopy() function to record state for random access on + externally generated deflate streams (e.g. in gzip files) + - More readable code (I hope) +- New and improved crc32() + - About 50% faster, thanks to suggestions from Rodney Brown +- Add deflateBound() and compressBound() functions +- Fix memory leak in deflateInit2() +- Permit setting dictionary for raw deflate (for parallel deflate) +- Fix const declaration for gzwrite() +- Check for some malloc() failures in gzio.c +- Fix bug in gzopen() on single-byte file 0x1f +- Fix bug in gzread() on concatenated file with 0x1f at end of buffer + and next buffer doesn't start with 0x8b +- Fix uncompress() to return Z_DATA_ERROR on truncated input +- Free memory at end of example.c +- Remove MAX #define in trees.c (conflicted with some libraries) +- Fix static const's in deflate.c, gzio.c, and zutil.[ch] +- Declare malloc() and free() in gzio.c if STDC not defined +- Use malloc() instead of calloc() in zutil.c if int big enough +- Define STDC for AIX +- Add aix/ with approach for compiling shared library on AIX +- Add HP-UX support for shared libraries in configure +- Add OpenUNIX support for shared libraries in configure +- Use $cc instead of gcc to build shared library +- Make prefix directory if needed when installing +- Correct Macintosh avoidance of typedef Byte in zconf.h +- Correct Turbo C memory allocation when under Linux +- Use libz.a instead of -lz in Makefile (assure use of compiled library) +- Update configure to check for snprintf or vsnprintf functions and their + return value, warn during make if using an insecure function +- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that + is lost when library is used--resolution is to build new zconf.h +- Documentation improvements (in zlib.h): + - Document raw deflate and inflate + - Update RFCs URL + - Point out that zlib and gzip formats are different + - Note that Z_BUF_ERROR is not fatal + - Document string limit for gzprintf() and possible buffer overflow + - Note requirement on avail_out when flushing + - Note permitted values of flush parameter of inflate() +- Add some FAQs (and even answers) to the FAQ +- Add contrib/inflate86/ for x86 faster inflate +- Add contrib/blast/ for PKWare Data Compression Library decompression +- Add contrib/puff/ simple inflate for deflate format description + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5) + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles Vollant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test" +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occurring only with compression level 0 (thanks to + Andy Buckler for finding this one) +- In minigzip, pass transparently also the first byte for .Z files +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match() + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code +- Use default memcpy for Symantec MSDOS compiler +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch) +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generate bad compressed data +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc. +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count) +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?) +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions) +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h) +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model) + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model + +Changes in 0.7 (14 April 95) +- Added full inflate support +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose) +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking +- renamed the 'filter' parameter of deflateInit2 as 'strategy' + Added Z_FILTERED and Z_HUFFMAN_ONLY constants + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8 +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2 +- added inflateInit2 +- simplified considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2 + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/src/libs/3rdparty/zlib/src/README b/src/libs/3rdparty/zlib/src/README new file mode 100644 index 00000000000..af6b4f32bf5 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/README @@ -0,0 +1,120 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.3.1 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and +rfc1952 (gzip format). + +This is a stripped down copy of zlib that contains patches to make it compile +as part of Qt. See also "qtpatches.diff". + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file test/example.c which also tests that +the library is working correctly. Another example is given in the file +test/minigzip.c. The compression library itself is composed of all source +files in the root directory. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile.in. In short "./configure; make test", and if that goes +well, "make install" should work for most flavors of Unix. For Windows, use +one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. + +PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available at +https://marknelson.us/posts/1997/01/01/zlib-engine.html . + +The changes made in version 1.3.1 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory contrib/ . + +zlib is available in Java using the java.util.zip package. Follow the API +Documentation link at: https://docs.oracle.com/search/?q=java.util.zip . + +A Perl interface to zlib and bzip2 written by Paul Marquess +can be found at https://github.com/pmqs/IO-Compress . + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +http://docs.python.org/library/zlib.html . + +zlib is built into tcl: http://wiki.tcl.tk/4610 . + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formerly OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS or BEOS. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate and + zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; they + are too numerous to cite here. + +Copyright notice: + + (C) 1995-2024 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. We make all +contributions to and distributions of this project solely in our personal +capacity, and are not conveying any rights to any intellectual property of +any third parties. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/src/libs/3rdparty/zlib/src/adler32.c b/src/libs/3rdparty/zlib/src/adler32.c new file mode 100644 index 00000000000..04b81d29bad --- /dev/null +++ b/src/libs/3rdparty/zlib/src/adler32.c @@ -0,0 +1,164 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#define BASE 65521U /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware -- + try it both ways to see which is faster */ +#ifdef NO_DIVIDE +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 + (thank you to John Reiser for pointing this out) */ +# define CHOP(a) \ + do { \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +# define MOD28(a) \ + do { \ + CHOP(a); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD(a) \ + do { \ + CHOP(a); \ + MOD28(a); \ + } while (0) +# define MOD63(a) \ + do { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD28(a) a %= BASE +# define MOD63(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) { + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD28(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) { + return adler32_z(adler, buf, len); +} + +/* ========================================================================= */ +local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) { + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffffUL; + + /* the derivation of this formula is left as an exercise for the reader */ + MOD63(len2); /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) { + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) { + return adler32_combine_(adler1, adler2, len2); +} diff --git a/src/libs/3rdparty/zlib/src/compress.c b/src/libs/3rdparty/zlib/src/compress.c new file mode 100644 index 00000000000..f43bacf7ab9 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/compress.c @@ -0,0 +1,75 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen, int level) { + z_stream stream; + int err; + const uInt max = (uInt)-1; + uLong left; + + left = *destLen; + *destLen = 0; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + stream.next_out = dest; + stream.avail_out = 0; + stream.next_in = (z_const Bytef *)source; + stream.avail_in = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (uLong)max ? max : (uInt)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; + sourceLen -= stream.avail_in; + } + err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); + } while (err == Z_OK); + + *destLen = stream.total_out; + deflateEnd(&stream); + return err == Z_STREAM_END ? Z_OK : err; +} + +/* =========================================================================== + */ +int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen) { + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound(uLong sourceLen) { + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; +} diff --git a/src/libs/3rdparty/zlib/src/crc32.c b/src/libs/3rdparty/zlib/src/crc32.c new file mode 100644 index 00000000000..6c38f5c04c6 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/crc32.c @@ -0,0 +1,1049 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * This interleaved implementation of a CRC makes use of pipelined multiple + * arithmetic-logic units, commonly found in modern CPU cores. It is due to + * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + + MAKECRCH can be #defined to write out crc32.h. A main() routine is also + produced, so that this one source file can be compiled to an executable. + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ + + /* + A CRC of a message is computed on N braids of words in the message, where + each word consists of W bytes (4 or 8). If N is 3, for example, then three + running sparse CRCs are calculated respectively on each braid, at these + indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... + This is done starting at a word boundary, and continues until as many blocks + of N * W bytes as are available have been processed. The results are combined + into a single CRC at the end. For this code, N must be in the range 1..6 and + W must be 4 or 8. The upper limit on N can be increased if desired by adding + more #if blocks, extending the patterns apparent in the code. In addition, + crc32.h would need to be regenerated, if the maximum N value is increased. + + N and W are chosen empirically by benchmarking the execution time on a given + processor. The choices for N and W below were based on testing on Intel Kaby + Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 + Octeon II processors. The Intel, AMD, and ARM processors were all fastest + with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. + They were all tested with either gcc or clang, all using the -O3 optimization + level. Your mileage may vary. + */ + +/* Define N */ +#ifdef Z_TESTN +# define N Z_TESTN +#else +# define N 5 +#endif +#if N < 1 || N > 6 +# error N must be in 1..6 +#endif + +/* + z_crc_t must be at least 32 bits. z_word_t must be at least as long as + z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and + that bytes are eight bits. + */ + +/* + Define W and the associated z_word_t type. If W is not defined, then a + braided calculation is not used, and the associated tables and code are not + compiled. + */ +#ifdef Z_TESTW +# if Z_TESTW-1 != -1 +# define W Z_TESTW +# endif +#else +# ifdef MAKECRCH +# define W 8 /* required for MAKECRCH */ +# else +# if defined(__x86_64__) || defined(__aarch64__) +# define W 8 +# else +# define W 4 +# endif +# endif +#endif +#ifdef W +# if W == 8 && defined(Z_U8) + typedef Z_U8 z_word_t; +# elif defined(Z_U4) +# undef W +# define W 4 + typedef Z_U4 z_word_t; +# else +# undef W +# endif +#endif + +/* If available, use the ARM processor CRC32 instruction. */ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 +# define ARMCRC32 +#endif + +#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) +/* + Swap the bytes in a z_word_t to convert between little and big endian. Any + self-respecting compiler will optimize this to a single machine byte-swap + instruction, if one is available. This assumes that word_t is either 32 bits + or 64 bits. + */ +local z_word_t byte_swap(z_word_t word) { +# if W == 8 + return + (word & 0xff00000000000000) >> 56 | + (word & 0xff000000000000) >> 40 | + (word & 0xff0000000000) >> 24 | + (word & 0xff00000000) >> 8 | + (word & 0xff000000) << 8 | + (word & 0xff0000) << 24 | + (word & 0xff00) << 40 | + (word & 0xff) << 56; +# else /* W == 4 */ + return + (word & 0xff000000) >> 24 | + (word & 0xff0000) >> 8 | + (word & 0xff00) << 8 | + (word & 0xff) << 24; +# endif +} +#endif + +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Table of powers of x for combining CRC-32s, filled in by make_crc_table() + * below. + */ + local z_crc_t FAR x2n_table[32]; +#else +/* ========================================================================= + * Tables for byte-wise and braided CRC-32 calculations, and a table of powers + * of x for combining CRC-32s, all made by make_crc_table(). + */ +# include "crc32.h" +#endif + +/* CRC polynomial. */ +#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ + +/* + Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, + reflected. For speed, this requires that a not be zero. + */ +local z_crc_t multmodp(z_crc_t a, z_crc_t b) { + z_crc_t m, p; + + m = (z_crc_t)1 << 31; + p = 0; + for (;;) { + if (a & m) { + p ^= b; + if ((a & (m - 1)) == 0) + break; + } + m >>= 1; + b = b & 1 ? (b >> 1) ^ POLY : b >> 1; + } + return p; +} + +/* + Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been + initialized. + */ +local z_crc_t x2nmodp(z_off64_t n, unsigned k) { + z_crc_t p; + + p = (z_crc_t)1 << 31; /* x^0 == 1 */ + while (n) { + if (n & 1) + p = multmodp(x2n_table[k & 31], p); + n >>= 1; + k++; + } + return p; +} + +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Build the tables for byte-wise and braided CRC-32 calculations, and a table + * of powers of x for combining CRC-32s. + */ +local z_crc_t FAR crc_table[256]; +#ifdef W + local z_word_t FAR crc_big_table[256]; + local z_crc_t FAR crc_braid_table[W][256]; + local z_word_t FAR crc_braid_big_table[W][256]; + local void braid(z_crc_t [][256], z_word_t [][256], int, int); +#endif +#ifdef MAKECRCH + local void write_table(FILE *, const z_crc_t FAR *, int); + local void write_table32hi(FILE *, const z_word_t FAR *, int); + local void write_table64(FILE *, const z_word_t FAR *, int); +#endif /* MAKECRCH */ + +/* + Define a once() function depending on the availability of atomics. If this is + compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in + multiple threads, and if atomics are not available, then get_crc_table() must + be called to initialize the tables and must return before any threads are + allowed to compute or combine CRCs. + */ + +/* Definition of once functionality. */ +typedef struct once_s once_t; + +/* Check for the availability of atomics. */ +#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ + !defined(__STDC_NO_ATOMICS__) + +#include + +/* Structure for once(), which must be initialized with ONCE_INIT. */ +struct once_s { + atomic_flag begun; + atomic_int done; +}; +#define ONCE_INIT {ATOMIC_FLAG_INIT, 0} + +/* + Run the provided init() function exactly once, even if multiple threads + invoke once() at the same time. The state must be a once_t initialized with + ONCE_INIT. + */ +local void once(once_t *state, void (*init)(void)) { + if (!atomic_load(&state->done)) { + if (atomic_flag_test_and_set(&state->begun)) + while (!atomic_load(&state->done)) + ; + else { + init(); + atomic_store(&state->done, 1); + } + } +} + +#else /* no atomics */ + +/* Structure for once(), which must be initialized with ONCE_INIT. */ +struct once_s { + volatile int begun; + volatile int done; +}; +#define ONCE_INIT {0, 0} + +/* Test and set. Alas, not atomic, but tries to minimize the period of + vulnerability. */ +local int test_and_set(int volatile *flag) { + int was; + + was = *flag; + *flag = 1; + return was; +} + +/* Run the provided init() function once. This is not thread-safe. */ +local void once(once_t *state, void (*init)(void)) { + if (!state->done) { + if (test_and_set(&state->begun)) + while (!state->done) + ; + else { + init(); + state->done = 1; + } + } +} + +#endif + +/* State for once(). */ +local once_t made = ONCE_INIT; + +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x + (which is shifting right by one and adding x^32 mod p if the bit shifted out + is a one). We start with the highest power (least significant bit) of q and + repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all the + information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. + */ + +local void make_crc_table(void) { + unsigned i, j, n; + z_crc_t p; + + /* initialize the CRC of bytes tables */ + for (i = 0; i < 256; i++) { + p = i; + for (j = 0; j < 8; j++) + p = p & 1 ? (p >> 1) ^ POLY : p >> 1; + crc_table[i] = p; +#ifdef W + crc_big_table[i] = byte_swap(p); +#endif + } + + /* initialize the x^2^n mod p(x) table */ + p = (z_crc_t)1 << 30; /* x^1 */ + x2n_table[0] = p; + for (n = 1; n < 32; n++) + x2n_table[n] = p = multmodp(p, p); + +#ifdef W + /* initialize the braiding tables -- needs x2n_table[] */ + braid(crc_braid_table, crc_braid_big_table, N, W); +#endif + +#ifdef MAKECRCH + { + /* + The crc32.h header file contains tables for both 32-bit and 64-bit + z_word_t's, and so requires a 64-bit type be available. In that case, + z_word_t must be defined to be 64-bits. This code then also generates + and writes out the tables for the case that z_word_t is 32 bits. + */ +#if !defined(W) || W != 8 +# error Need a 64-bit integer type in order to generate crc32.h. +#endif + FILE *out; + int k, n; + z_crc_t ltl[8][256]; + z_word_t big[8][256]; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + + /* write out little-endian CRC table to crc32.h */ + fprintf(out, + "/* crc32.h -- tables for rapid CRC calculation\n" + " * Generated automatically by crc32.c\n */\n" + "\n" + "local const z_crc_t FAR crc_table[] = {\n" + " "); + write_table(out, crc_table, 256); + fprintf(out, + "};\n"); + + /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#ifdef W\n" + "\n" + "#if W == 8\n" + "\n" + "local const z_word_t FAR crc_big_table[] = {\n" + " "); + write_table64(out, crc_big_table, 256); + fprintf(out, + "};\n"); + + /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#else /* W == 4 */\n" + "\n" + "local const z_word_t FAR crc_big_table[] = {\n" + " "); + write_table32hi(out, crc_big_table, 256); + fprintf(out, + "};\n" + "\n" + "#endif\n"); + + /* write out braid tables for each value of N */ + for (n = 1; n <= 6; n++) { + fprintf(out, + "\n" + "#if N == %d\n", n); + + /* compute braid tables for this N and 64-bit word_t */ + braid(ltl, big, n, 8); + + /* write out braid tables for 64-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#if W == 8\n" + "\n" + "local const z_crc_t FAR crc_braid_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + fprintf(out, " {"); + write_table(out, ltl[k], 256); + fprintf(out, "}%s", k < 7 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + fprintf(out, " {"); + write_table64(out, big[k], 256); + fprintf(out, "}%s", k < 7 ? ",\n" : ""); + } + fprintf(out, + "};\n"); + + /* compute braid tables for this N and 32-bit word_t */ + braid(ltl, big, n, 4); + + /* write out braid tables for 32-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#else /* W == 4 */\n" + "\n" + "local const z_crc_t FAR crc_braid_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + fprintf(out, " {"); + write_table(out, ltl[k], 256); + fprintf(out, "}%s", k < 3 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + fprintf(out, " {"); + write_table32hi(out, big[k], 256); + fprintf(out, "}%s", k < 3 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "#endif\n" + "\n" + "#endif\n"); + } + fprintf(out, + "\n" + "#endif\n"); + + /* write out zeros operator table to crc32.h */ + fprintf(out, + "\n" + "local const z_crc_t FAR x2n_table[] = {\n" + " "); + write_table(out, x2n_table, 32); + fprintf(out, + "};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH + +/* + Write the 32-bit values in table[0..k-1] to out, five per line in + hexadecimal separated by commas. + */ +local void write_table(FILE *out, const z_crc_t FAR *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", + (unsigned long)(table[n]), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the high 32-bits of each value in table[0..k-1] to out, five per line + in hexadecimal separated by commas. + */ +local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", + (unsigned long)(table[n] >> 32), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the 64-bit values in table[0..k-1] to out, three per line in + hexadecimal separated by commas. This assumes that if there is a 64-bit + type, then there is also a long long integer type, and it is at least 64 + bits. If not, then the type cast and format string can be adjusted + accordingly. + */ +local void write_table64(FILE *out, const z_word_t FAR *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : " ", + (unsigned long long)(table[n]), + n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); +} + +/* Actually do the deed. */ +int main(void) { + make_crc_table(); + return 0; +} + +#endif /* MAKECRCH */ + +#ifdef W +/* + Generate the little and big-endian braid tables for the given n and z_word_t + size w. Each array must have room for w blocks of 256 elements. + */ +local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) { + int k; + z_crc_t i, p, q; + for (k = 0; k < w; k++) { + p = x2nmodp((n * w + 3 - k) << 3, 0); + ltl[k][0] = 0; + big[w - 1 - k][0] = 0; + for (i = 1; i < 256; i++) { + ltl[k][i] = q = multmodp(i << 24, p); + big[w - 1 - k][i] = byte_swap(q); + } + } +} +#endif + +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32(), and to force the + * generation of the CRC tables in a threaded application. + */ +const z_crc_t FAR * ZEXPORT get_crc_table(void) { +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + return (const z_crc_t FAR *)crc_table; +} + +/* ========================================================================= + * Use ARM machine instructions if available. This will compute the CRC about + * ten times faster than the braided calculation. This code does not check for + * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will + * only be defined if the compilation specifies an ARM processor architecture + * that has the instructions. For example, compiling with -march=armv8.1-a or + * -march=armv8-a+crc, or -march=native if the compile machine has the crc32 + * instructions. + */ +#ifdef ARMCRC32 + +/* + Constants empirically determined to maximize speed. These values are from + measurements on a Cortex-A57. Your mileage may vary. + */ +#define Z_BATCH 3990 /* number of words in a batch */ +#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ +#define Z_BATCH_MIN 800 /* fewest words in a final batch */ + +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { + z_crc_t val; + z_word_t crc1, crc2; + const z_word_t *word; + z_word_t val0, val1, val2; + z_size_t last, last2, i; + z_size_t num; + + /* Return initial CRC, if requested. */ + if (buf == Z_NULL) return 0; + +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + + /* Pre-condition the CRC */ + crc = (~crc) & 0xffffffff; + + /* Compute the CRC up to a word boundary. */ + while (len && ((z_size_t)buf & 7) != 0) { + len--; + val = *buf++; + __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); + } + + /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */ + word = (z_word_t const *)buf; + num = len >> 3; + len &= 7; + + /* Do three interleaved CRCs to realize the throughput of one crc32x + instruction per cycle. Each CRC is calculated on Z_BATCH words. The + three CRCs are combined into a single CRC after each set of batches. */ + while (num >= 3 * Z_BATCH) { + crc1 = 0; + crc2 = 0; + for (i = 0; i < Z_BATCH; i++) { + val0 = word[i]; + val1 = word[i + Z_BATCH]; + val2 = word[i + 2 * Z_BATCH]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); + } + word += 3 * Z_BATCH; + num -= 3 * Z_BATCH; + crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1; + crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2; + } + + /* Do one last smaller batch with the remaining words, if there are enough + to pay for the combination of CRCs. */ + last = num / 3; + if (last >= Z_BATCH_MIN) { + last2 = last << 1; + crc1 = 0; + crc2 = 0; + for (i = 0; i < last; i++) { + val0 = word[i]; + val1 = word[i + last]; + val2 = word[i + last2]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); + } + word += 3 * last; + num -= 3 * last; + val = x2nmodp(last, 6); + crc = multmodp(val, crc) ^ crc1; + crc = multmodp(val, crc) ^ crc2; + } + + /* Compute the CRC on any remaining words. */ + for (i = 0; i < num; i++) { + val0 = word[i]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + } + word += num; + + /* Complete the CRC on any remaining bytes. */ + buf = (const unsigned char FAR *)word; + while (len) { + len--; + val = *buf++; + __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); + } + + /* Return the CRC, post-conditioned. */ + return crc ^ 0xffffffff; +} + +#else + +#ifdef W + +/* + Return the CRC of the W bytes in the word_t data, taking the + least-significant byte of the word as the first byte of data, without any pre + or post conditioning. This is used to combine the CRCs of each braid. + */ +local z_crc_t crc_word(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data >> 8) ^ crc_table[data & 0xff]; + return (z_crc_t)data; +} + +local z_word_t crc_word_big(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data << 8) ^ + crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; + return data; +} + +#endif + +/* ========================================================================= */ +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { + /* Return initial CRC, if requested. */ + if (buf == Z_NULL) return 0; + +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + + /* Pre-condition the CRC */ + crc = (~crc) & 0xffffffff; + +#ifdef W + + /* If provided enough bytes, do a braided CRC calculation. */ + if (len >= N * W + W - 1) { + z_size_t blks; + z_word_t const *words; + unsigned endian; + int k; + + /* Compute the CRC up to a z_word_t boundary. */ + while (len && ((z_size_t)buf & (W - 1)) != 0) { + len--; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + } + + /* Compute the CRC on as many N z_word_t blocks as are available. */ + blks = len / (N * W); + len -= blks * N * W; + words = (z_word_t const *)buf; + + /* Do endian check at execution time instead of compile time, since ARM + processors can change the endianness at execution time. If the + compiler knows what the endianness will be, it can optimize out the + check and the unused branch. */ + endian = 1; + if (*(unsigned char *)&endian) { + /* Little endian. */ + + z_crc_t crc0; + z_word_t word0; +#if N > 1 + z_crc_t crc1; + z_word_t word1; +#if N > 2 + z_crc_t crc2; + z_word_t word2; +#if N > 3 + z_crc_t crc3; + z_word_t word3; +#if N > 4 + z_crc_t crc4; + z_word_t word4; +#if N > 5 + z_crc_t crc5; + z_word_t word5; +#endif +#endif +#endif +#endif +#endif + + /* Initialize the CRC for each braid. */ + crc0 = crc; +#if N > 1 + crc1 = 0; +#if N > 2 + crc2 = 0; +#if N > 3 + crc3 = 0; +#if N > 4 + crc4 = 0; +#if N > 5 + crc5 = 0; +#endif +#endif +#endif +#endif +#endif + + /* + Process the first blks-1 blocks, computing the CRCs on each braid + independently. + */ + while (--blks) { + /* Load the word for each braid into registers. */ + word0 = crc0 ^ words[0]; +#if N > 1 + word1 = crc1 ^ words[1]; +#if N > 2 + word2 = crc2 ^ words[2]; +#if N > 3 + word3 = crc3 ^ words[3]; +#if N > 4 + word4 = crc4 ^ words[4]; +#if N > 5 + word5 = crc5 ^ words[5]; +#endif +#endif +#endif +#endif +#endif + words += N; + + /* Compute and update the CRC for each word. The loop should + get unrolled. */ + crc0 = crc_braid_table[0][word0 & 0xff]; +#if N > 1 + crc1 = crc_braid_table[0][word1 & 0xff]; +#if N > 2 + crc2 = crc_braid_table[0][word2 & 0xff]; +#if N > 3 + crc3 = crc_braid_table[0][word3 & 0xff]; +#if N > 4 + crc4 = crc_braid_table[0][word4 & 0xff]; +#if N > 5 + crc5 = crc_braid_table[0][word5 & 0xff]; +#endif +#endif +#endif +#endif +#endif + for (k = 1; k < W; k++) { + crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff]; +#if N > 1 + crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff]; +#if N > 2 + crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff]; +#if N > 3 + crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff]; +#if N > 4 + crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff]; +#if N > 5 + crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff]; +#endif +#endif +#endif +#endif +#endif + } + } + + /* + Process the last block, combining the CRCs of the N braids at the + same time. + */ + crc = crc_word(crc0 ^ words[0]); +#if N > 1 + crc = crc_word(crc1 ^ words[1] ^ crc); +#if N > 2 + crc = crc_word(crc2 ^ words[2] ^ crc); +#if N > 3 + crc = crc_word(crc3 ^ words[3] ^ crc); +#if N > 4 + crc = crc_word(crc4 ^ words[4] ^ crc); +#if N > 5 + crc = crc_word(crc5 ^ words[5] ^ crc); +#endif +#endif +#endif +#endif +#endif + words += N; + } + else { + /* Big endian. */ + + z_word_t crc0, word0, comb; +#if N > 1 + z_word_t crc1, word1; +#if N > 2 + z_word_t crc2, word2; +#if N > 3 + z_word_t crc3, word3; +#if N > 4 + z_word_t crc4, word4; +#if N > 5 + z_word_t crc5, word5; +#endif +#endif +#endif +#endif +#endif + + /* Initialize the CRC for each braid. */ + crc0 = byte_swap(crc); +#if N > 1 + crc1 = 0; +#if N > 2 + crc2 = 0; +#if N > 3 + crc3 = 0; +#if N > 4 + crc4 = 0; +#if N > 5 + crc5 = 0; +#endif +#endif +#endif +#endif +#endif + + /* + Process the first blks-1 blocks, computing the CRCs on each braid + independently. + */ + while (--blks) { + /* Load the word for each braid into registers. */ + word0 = crc0 ^ words[0]; +#if N > 1 + word1 = crc1 ^ words[1]; +#if N > 2 + word2 = crc2 ^ words[2]; +#if N > 3 + word3 = crc3 ^ words[3]; +#if N > 4 + word4 = crc4 ^ words[4]; +#if N > 5 + word5 = crc5 ^ words[5]; +#endif +#endif +#endif +#endif +#endif + words += N; + + /* Compute and update the CRC for each word. The loop should + get unrolled. */ + crc0 = crc_braid_big_table[0][word0 & 0xff]; +#if N > 1 + crc1 = crc_braid_big_table[0][word1 & 0xff]; +#if N > 2 + crc2 = crc_braid_big_table[0][word2 & 0xff]; +#if N > 3 + crc3 = crc_braid_big_table[0][word3 & 0xff]; +#if N > 4 + crc4 = crc_braid_big_table[0][word4 & 0xff]; +#if N > 5 + crc5 = crc_braid_big_table[0][word5 & 0xff]; +#endif +#endif +#endif +#endif +#endif + for (k = 1; k < W; k++) { + crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff]; +#if N > 1 + crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff]; +#if N > 2 + crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff]; +#if N > 3 + crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff]; +#if N > 4 + crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff]; +#if N > 5 + crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff]; +#endif +#endif +#endif +#endif +#endif + } + } + + /* + Process the last block, combining the CRCs of the N braids at the + same time. + */ + comb = crc_word_big(crc0 ^ words[0]); +#if N > 1 + comb = crc_word_big(crc1 ^ words[1] ^ comb); +#if N > 2 + comb = crc_word_big(crc2 ^ words[2] ^ comb); +#if N > 3 + comb = crc_word_big(crc3 ^ words[3] ^ comb); +#if N > 4 + comb = crc_word_big(crc4 ^ words[4] ^ comb); +#if N > 5 + comb = crc_word_big(crc5 ^ words[5] ^ comb); +#endif +#endif +#endif +#endif +#endif + words += N; + crc = byte_swap(comb); + } + + /* + Update the pointer to the remaining bytes to process. + */ + buf = (unsigned char const *)words; + } + +#endif /* W */ + + /* Complete the computation of the CRC on any remaining bytes. */ + while (len >= 8) { + len -= 8; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + } + while (len) { + len--; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + } + + /* Return the CRC, post-conditioned. */ + return crc ^ 0xffffffff; +} + +#endif + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, + uInt len) { + return crc32_z(crc, buf, len); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { + return crc32_combine64(crc1, crc2, (z_off64_t)len2); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + return x2nmodp(len2, 3); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine_gen(z_off_t len2) { + return crc32_combine_gen64((z_off64_t)len2); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { + return multmodp(op, crc1) ^ (crc2 & 0xffffffff); +} diff --git a/src/libs/3rdparty/zlib/src/crc32.h b/src/libs/3rdparty/zlib/src/crc32.h new file mode 100644 index 00000000000..137df68d616 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/crc32.h @@ -0,0 +1,9446 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const z_crc_t FAR crc_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}; + +#ifdef W + +#if W == 8 + +local const z_word_t FAR crc_big_table[] = { + 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}; + +#else /* W == 4 */ + +local const z_word_t FAR crc_big_table[] = { + 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}; + +#endif + +#if N == 1 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}, + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}, + {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000, + 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000, + 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000, + 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000, + 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000, + 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000, + 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000, + 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000, + 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000, + 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000, + 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000, + 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000, + 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000, + 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000, + 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000, + 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000, + 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000, + 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000, + 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000, + 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000, + 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000, + 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000, + 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000, + 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000, + 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000, + 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000, + 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000, + 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000, + 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000, + 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000, + 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000, + 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000, + 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000, + 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000, + 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000, + 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000, + 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000, + 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000, + 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000, + 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000, + 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000, + 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000, + 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000, + 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000, + 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000, + 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000, + 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000, + 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000, + 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000, + 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000, + 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000, + 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000, + 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000, + 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000, + 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000, + 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000, + 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000, + 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000, + 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000, + 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000, + 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000, + 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000, + 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000, + 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000, + 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000, + 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000, + 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000, + 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000, + 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000, + 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000, + 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000, + 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000, + 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000, + 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000, + 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000, + 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000, + 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000, + 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000, + 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000, + 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000, + 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000, + 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000, + 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000, + 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000, + 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000, + 0x72fd249300000000}, + {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000, + 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000, + 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000, + 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000, + 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000, + 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000, + 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000, + 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000, + 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000, + 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000, + 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000, + 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000, + 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000, + 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000, + 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000, + 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000, + 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000, + 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000, + 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000, + 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000, + 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000, + 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000, + 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000, + 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000, + 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000, + 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000, + 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000, + 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000, + 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000, + 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000, + 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000, + 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000, + 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000, + 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000, + 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000, + 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000, + 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000, + 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000, + 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000, + 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000, + 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000, + 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000, + 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000, + 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000, + 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000, + 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000, + 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000, + 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000, + 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000, + 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000, + 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000, + 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000, + 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000, + 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000, + 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000, + 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000, + 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000, + 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000, + 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000, + 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000, + 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000, + 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000, + 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000, + 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000, + 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000, + 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000, + 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000, + 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000, + 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000, + 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000, + 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000, + 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000, + 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000, + 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000, + 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000, + 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000, + 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000, + 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000, + 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000, + 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000, + 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000, + 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000, + 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000, + 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000, + 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000, + 0xed3498be00000000}, + {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000, + 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000, + 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000, + 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000, + 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000, + 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000, + 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000, + 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000, + 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000, + 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000, + 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000, + 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000, + 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000, + 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000, + 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000, + 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000, + 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000, + 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000, + 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000, + 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000, + 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000, + 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000, + 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000, + 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000, + 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000, + 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000, + 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000, + 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000, + 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000, + 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000, + 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000, + 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000, + 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000, + 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000, + 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000, + 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000, + 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000, + 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000, + 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000, + 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000, + 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000, + 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000, + 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000, + 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000, + 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000, + 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000, + 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000, + 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000, + 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000, + 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000, + 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000, + 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000, + 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000, + 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000, + 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000, + 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000, + 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000, + 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000, + 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000, + 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000, + 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000, + 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000, + 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000, + 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000, + 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000, + 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000, + 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000, + 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000, + 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000, + 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000, + 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000, + 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000, + 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000, + 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000, + 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000, + 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000, + 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000, + 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000, + 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000, + 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000, + 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000, + 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000, + 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000, + 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000, + 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000, + 0xf10605de00000000}, + {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000, + 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000, + 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000, + 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000, + 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000, + 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000, + 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000, + 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000, + 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000, + 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000, + 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000, + 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000, + 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000, + 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000, + 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000, + 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000, + 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000, + 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000, + 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000, + 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000, + 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000, + 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000, + 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000, + 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000, + 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000, + 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000, + 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000, + 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000, + 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000, + 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000, + 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000, + 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000, + 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000, + 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000, + 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000, + 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000, + 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000, + 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000, + 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000, + 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000, + 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000, + 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000, + 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000, + 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000, + 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000, + 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000, + 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000, + 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000, + 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000, + 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000, + 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000, + 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000, + 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000, + 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000, + 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000, + 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000, + 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000, + 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000, + 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000, + 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000, + 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000, + 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000, + 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000, + 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000, + 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000, + 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000, + 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000, + 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000, + 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000, + 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000, + 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000, + 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000, + 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000, + 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000, + 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000, + 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000, + 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000, + 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000, + 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000, + 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000, + 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000, + 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000, + 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000, + 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000, + 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000, + 0x8cc764ca00000000}, + {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000, + 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000, + 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000, + 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000, + 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000, + 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000, + 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000, + 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000, + 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000, + 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000, + 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000, + 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000, + 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000, + 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000, + 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000, + 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000, + 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000, + 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000, + 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000, + 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000, + 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000, + 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000, + 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000, + 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000, + 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000, + 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000, + 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000, + 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000, + 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000, + 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000, + 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000, + 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000, + 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000, + 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000, + 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000, + 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000, + 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000, + 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000, + 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000, + 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000, + 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000, + 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000, + 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000, + 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000, + 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000, + 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000, + 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000, + 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000, + 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000, + 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000, + 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000, + 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000, + 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000, + 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000, + 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000, + 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000, + 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000, + 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000, + 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000, + 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000, + 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000, + 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000, + 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000, + 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000, + 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000, + 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000, + 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000, + 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000, + 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000, + 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000, + 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000, + 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000, + 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000, + 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000, + 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000, + 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000, + 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000, + 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000, + 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000, + 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000, + 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000, + 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000, + 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000, + 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000, + 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000, + 0xccabc4e400000000}, + {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000, + 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000, + 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000, + 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000, + 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000, + 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000, + 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000, + 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000, + 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000, + 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000, + 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000, + 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000, + 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000, + 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000, + 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000, + 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000, + 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000, + 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000, + 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000, + 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000, + 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000, + 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000, + 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000, + 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000, + 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000, + 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000, + 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000, + 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000, + 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000, + 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000, + 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000, + 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000, + 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000, + 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000, + 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000, + 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000, + 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000, + 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000, + 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000, + 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000, + 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000, + 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000, + 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000, + 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000, + 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000, + 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000, + 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000, + 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000, + 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000, + 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000, + 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000, + 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000, + 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000, + 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000, + 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000, + 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000, + 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000, + 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000, + 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000, + 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000, + 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000, + 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000, + 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000, + 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000, + 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000, + 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000, + 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000, + 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000, + 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000, + 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000, + 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000, + 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000, + 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000, + 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000, + 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000, + 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000, + 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000, + 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000, + 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000, + 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000, + 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000, + 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000, + 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000, + 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000, + 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000, + 0x304a369200000000}, + {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000, + 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000, + 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000, + 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000, + 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000, + 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000, + 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000, + 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000, + 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000, + 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000, + 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000, + 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000, + 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000, + 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000, + 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000, + 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000, + 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000, + 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000, + 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000, + 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000, + 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000, + 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000, + 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000, + 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000, + 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000, + 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000, + 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000, + 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000, + 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000, + 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000, + 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000, + 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000, + 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000, + 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000, + 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000, + 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000, + 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000, + 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000, + 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000, + 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000, + 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000, + 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000, + 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000, + 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000, + 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000, + 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000, + 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000, + 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000, + 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000, + 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000, + 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000, + 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000, + 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000, + 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000, + 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000, + 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000, + 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000, + 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000, + 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000, + 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000, + 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000, + 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000, + 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000, + 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000, + 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000, + 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000, + 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000, + 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000, + 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000, + 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000, + 0x6171384400000000, 0xff71928800000000, 0xe678578200000000, + 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000, + 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000, + 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000, + 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000, + 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000, + 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000, + 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000, + 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000, + 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000, + 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000, + 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000, + 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000, + 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000, + 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000, + 0xe6064b2600000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}, + {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, + 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, + 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, + 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, + 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, + 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, + 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, + 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, + 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, + 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, + 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, + 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, + 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, + 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, + 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, + 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, + 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, + 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, + 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, + 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, + 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, + 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, + 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, + 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, + 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, + 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, + 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, + 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, + 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, + 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, + 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, + 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, + 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, + 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, + 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, + 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, + 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, + 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, + 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, + 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, + 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, + 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, + 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, + 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, + 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, + 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, + 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, + 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, + 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, + 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, + 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, + 0x72fd2493}, + {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, + 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, + 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, + 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, + 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, + 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, + 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, + 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, + 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, + 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, + 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, + 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, + 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, + 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, + 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, + 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, + 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, + 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, + 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, + 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, + 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, + 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, + 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, + 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, + 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, + 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, + 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, + 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, + 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, + 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, + 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, + 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, + 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, + 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, + 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, + 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, + 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, + 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, + 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, + 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, + 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, + 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, + 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, + 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, + 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, + 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, + 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, + 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, + 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, + 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, + 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, + 0xed3498be}, + {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, + 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, + 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, + 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, + 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, + 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, + 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, + 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, + 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, + 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, + 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, + 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, + 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, + 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, + 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, + 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, + 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, + 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, + 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, + 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, + 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, + 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, + 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, + 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, + 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, + 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, + 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, + 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, + 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, + 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, + 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, + 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, + 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, + 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, + 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, + 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, + 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, + 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, + 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, + 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, + 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, + 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, + 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, + 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, + 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, + 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, + 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, + 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, + 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, + 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, + 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, + 0xf10605de}}; + +#endif + +#endif + +#if N == 2 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}, + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000, + 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000, + 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000, + 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000, + 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000, + 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000, + 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000, + 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000, + 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000, + 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000, + 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000, + 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000, + 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000, + 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000, + 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000, + 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000, + 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000, + 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000, + 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000, + 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000, + 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000, + 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000, + 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000, + 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000, + 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000, + 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000, + 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000, + 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000, + 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000, + 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000, + 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000, + 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000, + 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000, + 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000, + 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000, + 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000, + 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000, + 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000, + 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000, + 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000, + 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000, + 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000, + 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000, + 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000, + 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000, + 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000, + 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000, + 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000, + 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000, + 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000, + 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000, + 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000, + 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000, + 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000, + 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000, + 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000, + 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000, + 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000, + 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000, + 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000, + 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000, + 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000, + 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000, + 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000, + 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000, + 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000, + 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000, + 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000, + 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000, + 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000, + 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000, + 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000, + 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000, + 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000, + 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000, + 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000, + 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000, + 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000, + 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000, + 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000, + 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000, + 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000, + 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000, + 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000, + 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000, + 0x4b0c4f4900000000}, + {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000, + 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000, + 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000, + 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000, + 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000, + 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000, + 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000, + 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000, + 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000, + 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000, + 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000, + 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000, + 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000, + 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000, + 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000, + 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000, + 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000, + 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000, + 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000, + 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000, + 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000, + 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000, + 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000, + 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000, + 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000, + 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000, + 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000, + 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000, + 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000, + 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000, + 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000, + 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000, + 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000, + 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000, + 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000, + 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000, + 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000, + 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000, + 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000, + 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000, + 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000, + 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000, + 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000, + 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000, + 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000, + 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000, + 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000, + 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000, + 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000, + 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000, + 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000, + 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000, + 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000, + 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000, + 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000, + 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000, + 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000, + 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000, + 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000, + 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000, + 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000, + 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000, + 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000, + 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000, + 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000, + 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000, + 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000, + 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000, + 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000, + 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000, + 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000, + 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000, + 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000, + 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000, + 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000, + 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000, + 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000, + 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000, + 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000, + 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000, + 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000, + 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000, + 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000, + 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000, + 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000, + 0x14d747e100000000}, + {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000, + 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000, + 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000, + 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000, + 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000, + 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000, + 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000, + 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000, + 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000, + 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000, + 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000, + 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000, + 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000, + 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000, + 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000, + 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000, + 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000, + 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000, + 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000, + 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000, + 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000, + 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000, + 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000, + 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000, + 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000, + 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000, + 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000, + 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000, + 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000, + 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000, + 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000, + 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000, + 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000, + 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000, + 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000, + 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000, + 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000, + 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000, + 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000, + 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000, + 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000, + 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000, + 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000, + 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000, + 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000, + 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000, + 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000, + 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000, + 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000, + 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000, + 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000, + 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000, + 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000, + 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000, + 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000, + 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000, + 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000, + 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000, + 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000, + 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000, + 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000, + 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000, + 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000, + 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000, + 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000, + 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000, + 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000, + 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000, + 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000, + 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000, + 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000, + 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000, + 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000, + 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000, + 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000, + 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000, + 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000, + 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000, + 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000, + 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000, + 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000, + 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000, + 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000, + 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000, + 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000, + 0xaa933b1a00000000}, + {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000, + 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000, + 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000, + 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000, + 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000, + 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000, + 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000, + 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000, + 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000, + 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000, + 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000, + 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000, + 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000, + 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000, + 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000, + 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000, + 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000, + 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000, + 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000, + 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000, + 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000, + 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000, + 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000, + 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000, + 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000, + 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000, + 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000, + 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000, + 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000, + 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000, + 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000, + 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000, + 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000, + 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000, + 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000, + 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000, + 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000, + 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000, + 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000, + 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000, + 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000, + 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000, + 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000, + 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000, + 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000, + 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000, + 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000, + 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000, + 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000, + 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000, + 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000, + 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000, + 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000, + 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000, + 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000, + 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000, + 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000, + 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000, + 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000, + 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000, + 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000, + 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000, + 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000, + 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000, + 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000, + 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000, + 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000, + 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000, + 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000, + 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000, + 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000, + 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000, + 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000, + 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000, + 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000, + 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000, + 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000, + 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000, + 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000, + 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000, + 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000, + 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000, + 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000, + 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000, + 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000, + 0x6571193600000000}, + {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000, + 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000, + 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000, + 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000, + 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000, + 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000, + 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000, + 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000, + 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000, + 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000, + 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000, + 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000, + 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000, + 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000, + 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000, + 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000, + 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000, + 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000, + 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000, + 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000, + 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000, + 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000, + 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000, + 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000, + 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000, + 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000, + 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000, + 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000, + 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000, + 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000, + 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000, + 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000, + 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000, + 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000, + 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000, + 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000, + 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000, + 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000, + 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000, + 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000, + 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000, + 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000, + 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000, + 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000, + 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000, + 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000, + 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000, + 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000, + 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000, + 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000, + 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000, + 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000, + 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000, + 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000, + 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000, + 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000, + 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000, + 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000, + 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000, + 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000, + 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000, + 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000, + 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000, + 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000, + 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000, + 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000, + 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000, + 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000, + 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000, + 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000, + 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000, + 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000, + 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000, + 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000, + 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000, + 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000, + 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000, + 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000, + 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000, + 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000, + 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000, + 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000, + 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000, + 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000, + 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000, + 0xa68cee3d00000000}, + {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000, + 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000, + 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000, + 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000, + 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000, + 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000, + 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000, + 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000, + 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000, + 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000, + 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000, + 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000, + 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000, + 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000, + 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000, + 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000, + 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000, + 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000, + 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000, + 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000, + 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000, + 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000, + 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000, + 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000, + 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000, + 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000, + 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000, + 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000, + 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000, + 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000, + 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000, + 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000, + 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000, + 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000, + 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000, + 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000, + 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000, + 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000, + 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000, + 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000, + 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000, + 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000, + 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000, + 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000, + 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000, + 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000, + 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000, + 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000, + 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000, + 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000, + 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000, + 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000, + 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000, + 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000, + 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000, + 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000, + 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000, + 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000, + 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000, + 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000, + 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000, + 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000, + 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000, + 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000, + 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000, + 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000, + 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000, + 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000, + 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000, + 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000, + 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000, + 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000, + 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000, + 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000, + 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000, + 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000, + 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000, + 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000, + 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000, + 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000, + 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000, + 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000, + 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000, + 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000, + 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000, + 0x51e8883f00000000}, + {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000, + 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000, + 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000, + 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000, + 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000, + 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000, + 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000, + 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000, + 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000, + 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000, + 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000, + 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000, + 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000, + 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000, + 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000, + 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000, + 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000, + 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000, + 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000, + 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000, + 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000, + 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000, + 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000, + 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000, + 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000, + 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000, + 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000, + 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000, + 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000, + 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000, + 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000, + 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000, + 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000, + 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000, + 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000, + 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000, + 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000, + 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000, + 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000, + 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000, + 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000, + 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000, + 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000, + 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000, + 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000, + 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000, + 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000, + 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000, + 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000, + 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000, + 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000, + 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000, + 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000, + 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000, + 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000, + 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000, + 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000, + 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000, + 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000, + 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000, + 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000, + 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000, + 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000, + 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000, + 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000, + 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000, + 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000, + 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000, + 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000, + 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000, + 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000, + 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000, + 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000, + 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000, + 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000, + 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000, + 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000, + 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000, + 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000, + 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000, + 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000, + 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000, + 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000, + 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000, + 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000, + 0x8ae9531c00000000}, + {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000, + 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000, + 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000, + 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000, + 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000, + 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000, + 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000, + 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000, + 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000, + 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000, + 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000, + 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000, + 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000, + 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000, + 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000, + 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000, + 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000, + 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000, + 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000, + 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000, + 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000, + 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000, + 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000, + 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000, + 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000, + 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000, + 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000, + 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000, + 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000, + 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000, + 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000, + 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000, + 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000, + 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000, + 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000, + 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000, + 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000, + 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000, + 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000, + 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000, + 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000, + 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000, + 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000, + 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000, + 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000, + 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000, + 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000, + 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000, + 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000, + 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000, + 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000, + 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000, + 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000, + 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000, + 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000, + 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000, + 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000, + 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000, + 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000, + 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000, + 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000, + 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000, + 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000, + 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000, + 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000, + 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000, + 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000, + 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000, + 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000, + 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000, + 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000, + 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000, + 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000, + 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000, + 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000, + 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000, + 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000, + 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000, + 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000, + 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000, + 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000, + 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000, + 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000, + 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000, + 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000, + 0xd739710d00000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5, + 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d, + 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf, + 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, + 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050, + 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098, + 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb, + 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, + 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104, + 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c, + 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e, + 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, + 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358, + 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390, + 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312, + 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, + 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd, + 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335, + 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387, + 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, + 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9, + 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261, + 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, + 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, + 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c, + 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c, + 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e, + 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, + 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1, + 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619, + 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b, + 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, + 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785, + 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d, + 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf, + 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, + 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720, + 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8, + 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, + 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, + 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c, + 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4, + 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506, + 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, + 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428, + 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0, + 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462, + 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, + 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd, + 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445, + 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, + 0x8cc764ca}, + {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b, + 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27, + 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a, + 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, + 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef, + 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf, + 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a, + 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, + 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70, + 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf, + 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, + 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, + 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f, + 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f, + 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae, + 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, + 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97, + 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b, + 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436, + 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, + 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4, + 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4, + 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46, + 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, + 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c, + 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5, + 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8, + 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, + 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d, + 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d, + 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc, + 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, + 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82, + 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e, + 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623, + 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, + 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6, + 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6, + 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c, + 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, + 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66, + 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9, + 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4, + 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, + 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416, + 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946, + 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, + 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, + 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e, + 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32, + 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f, + 0xccabc4e4}, + {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4, + 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895, + 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50, + 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, + 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154, + 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906, + 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258, + 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, + 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08, + 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e, + 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, + 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, + 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44, + 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316, + 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0, + 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, + 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7, + 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6, + 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73, + 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, + 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8, + 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea, + 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, + 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, + 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b, + 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e, + 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, + 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, + 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef, + 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd, + 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b, + 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, + 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3, + 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2, + 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417, + 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, + 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13, + 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241, + 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, + 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, + 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b, + 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d, + 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, + 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, + 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003, + 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851, + 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7, + 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, + 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190, + 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1, + 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134, + 0x304a3692}, + {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84, + 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f, + 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15, + 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, + 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf, + 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7, + 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb, + 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, + 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae, + 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749, + 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243, + 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, + 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29, + 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61, + 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8, + 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, + 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1, + 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a, + 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40, + 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, + 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03, + 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b, + 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee, + 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, + 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb, + 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f, + 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, + 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, + 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f, + 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067, + 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be, + 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, + 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e, + 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5, + 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, + 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, + 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305, + 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d, + 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338, + 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, + 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d, + 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca, + 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0, + 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, + 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083, + 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb, + 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012, + 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, + 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b, + 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0, + 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea, + 0xe6064b26}}; + +#endif + +#endif + +#if N == 3 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}, + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000, + 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000, + 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000, + 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000, + 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000, + 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000, + 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000, + 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000, + 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000, + 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000, + 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000, + 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000, + 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000, + 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000, + 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000, + 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000, + 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000, + 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000, + 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000, + 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000, + 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000, + 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000, + 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000, + 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000, + 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000, + 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000, + 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000, + 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000, + 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000, + 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000, + 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000, + 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000, + 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000, + 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000, + 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000, + 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000, + 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000, + 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000, + 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000, + 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000, + 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000, + 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000, + 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000, + 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000, + 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000, + 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000, + 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000, + 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000, + 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000, + 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000, + 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000, + 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000, + 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000, + 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000, + 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000, + 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000, + 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000, + 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000, + 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000, + 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000, + 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000, + 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000, + 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000, + 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000, + 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000, + 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000, + 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000, + 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000, + 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000, + 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000, + 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000, + 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000, + 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000, + 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000, + 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000, + 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000, + 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000, + 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000, + 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000, + 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000, + 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000, + 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000, + 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000, + 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000, + 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000, + 0x4e36ba1800000000}, + {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000, + 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000, + 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000, + 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000, + 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000, + 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000, + 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000, + 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000, + 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000, + 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000, + 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000, + 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000, + 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000, + 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000, + 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000, + 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000, + 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000, + 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000, + 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000, + 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000, + 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000, + 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000, + 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000, + 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000, + 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000, + 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000, + 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000, + 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000, + 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000, + 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000, + 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000, + 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000, + 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000, + 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000, + 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000, + 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000, + 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000, + 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000, + 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000, + 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000, + 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000, + 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000, + 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000, + 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000, + 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000, + 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000, + 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000, + 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000, + 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000, + 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000, + 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000, + 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000, + 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000, + 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000, + 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000, + 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000, + 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000, + 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000, + 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000, + 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000, + 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000, + 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000, + 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000, + 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000, + 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000, + 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000, + 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000, + 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000, + 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000, + 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000, + 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000, + 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000, + 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000, + 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000, + 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000, + 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000, + 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000, + 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000, + 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000, + 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000, + 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000, + 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000, + 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000, + 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000, + 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000, + 0xa1d67c9100000000}, + {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000, + 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000, + 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000, + 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000, + 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000, + 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000, + 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000, + 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000, + 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000, + 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000, + 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000, + 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000, + 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000, + 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000, + 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000, + 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000, + 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000, + 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000, + 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000, + 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000, + 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000, + 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000, + 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000, + 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000, + 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000, + 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000, + 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000, + 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000, + 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000, + 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000, + 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000, + 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000, + 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000, + 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000, + 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000, + 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000, + 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000, + 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000, + 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000, + 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000, + 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000, + 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000, + 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000, + 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000, + 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000, + 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000, + 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000, + 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000, + 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000, + 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000, + 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000, + 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000, + 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000, + 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000, + 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000, + 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000, + 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000, + 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000, + 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000, + 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000, + 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000, + 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000, + 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000, + 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000, + 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000, + 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000, + 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000, + 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000, + 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000, + 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000, + 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000, + 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000, + 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000, + 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000, + 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000, + 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000, + 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000, + 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000, + 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000, + 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000, + 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000, + 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000, + 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000, + 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000, + 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000, + 0xa8ef40a100000000}, + {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000, + 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000, + 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000, + 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000, + 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000, + 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000, + 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000, + 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000, + 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000, + 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000, + 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000, + 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000, + 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000, + 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000, + 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000, + 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000, + 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000, + 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000, + 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000, + 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000, + 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000, + 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000, + 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000, + 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000, + 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000, + 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000, + 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000, + 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000, + 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000, + 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000, + 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000, + 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000, + 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000, + 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000, + 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000, + 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000, + 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000, + 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000, + 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000, + 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000, + 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000, + 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000, + 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000, + 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000, + 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000, + 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000, + 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000, + 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000, + 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000, + 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000, + 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000, + 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000, + 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000, + 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000, + 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000, + 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000, + 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000, + 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000, + 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000, + 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000, + 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000, + 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000, + 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000, + 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000, + 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000, + 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000, + 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000, + 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000, + 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000, + 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000, + 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000, + 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000, + 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000, + 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000, + 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000, + 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000, + 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000, + 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000, + 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000, + 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000, + 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000, + 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000, + 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000, + 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000, + 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000, + 0x356bacd800000000}, + {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000, + 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000, + 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000, + 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000, + 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000, + 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000, + 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000, + 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000, + 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000, + 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000, + 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000, + 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000, + 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000, + 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000, + 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000, + 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000, + 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000, + 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000, + 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000, + 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000, + 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000, + 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000, + 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000, + 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000, + 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000, + 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000, + 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000, + 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000, + 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000, + 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000, + 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000, + 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000, + 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000, + 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000, + 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000, + 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000, + 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000, + 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000, + 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000, + 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000, + 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000, + 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000, + 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000, + 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000, + 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000, + 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000, + 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000, + 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000, + 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000, + 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000, + 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000, + 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000, + 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000, + 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000, + 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000, + 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000, + 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000, + 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000, + 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000, + 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000, + 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000, + 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000, + 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000, + 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000, + 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000, + 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000, + 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000, + 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000, + 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000, + 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000, + 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000, + 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000, + 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000, + 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000, + 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000, + 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000, + 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000, + 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000, + 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000, + 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000, + 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000, + 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000, + 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000, + 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000, + 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000, + 0x48686b5600000000}, + {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000, + 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000, + 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000, + 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000, + 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000, + 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000, + 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000, + 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000, + 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000, + 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000, + 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000, + 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000, + 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000, + 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000, + 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000, + 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000, + 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000, + 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000, + 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000, + 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000, + 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000, + 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000, + 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000, + 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000, + 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000, + 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000, + 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000, + 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000, + 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000, + 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000, + 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000, + 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000, + 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000, + 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000, + 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000, + 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000, + 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000, + 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000, + 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000, + 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000, + 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000, + 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000, + 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000, + 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000, + 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000, + 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000, + 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000, + 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000, + 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000, + 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000, + 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000, + 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000, + 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000, + 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000, + 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000, + 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000, + 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000, + 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000, + 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000, + 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000, + 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000, + 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000, + 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000, + 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000, + 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000, + 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000, + 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000, + 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000, + 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000, + 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000, + 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000, + 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000, + 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000, + 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000, + 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000, + 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000, + 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000, + 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000, + 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000, + 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000, + 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000, + 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000, + 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000, + 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000, + 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000, + 0xcaa2517800000000}, + {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000, + 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000, + 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000, + 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000, + 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000, + 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000, + 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000, + 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000, + 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000, + 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000, + 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000, + 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000, + 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000, + 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000, + 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000, + 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000, + 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000, + 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000, + 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000, + 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000, + 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000, + 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000, + 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000, + 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000, + 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000, + 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000, + 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000, + 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000, + 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000, + 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000, + 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000, + 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000, + 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000, + 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000, + 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000, + 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000, + 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000, + 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000, + 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000, + 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000, + 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000, + 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000, + 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000, + 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000, + 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000, + 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000, + 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000, + 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000, + 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000, + 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000, + 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000, + 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000, + 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000, + 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000, + 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000, + 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000, + 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000, + 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000, + 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000, + 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000, + 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000, + 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000, + 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000, + 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000, + 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000, + 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000, + 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000, + 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000, + 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000, + 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000, + 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000, + 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000, + 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000, + 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000, + 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000, + 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000, + 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000, + 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000, + 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000, + 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000, + 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000, + 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000, + 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000, + 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000, + 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000, + 0x0c7ac97b00000000}, + {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000, + 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000, + 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000, + 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000, + 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000, + 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000, + 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000, + 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000, + 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000, + 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000, + 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000, + 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000, + 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000, + 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000, + 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000, + 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000, + 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000, + 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000, + 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000, + 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000, + 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000, + 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000, + 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000, + 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000, + 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000, + 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000, + 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000, + 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000, + 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000, + 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000, + 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000, + 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000, + 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000, + 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000, + 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000, + 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000, + 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000, + 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000, + 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000, + 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000, + 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000, + 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000, + 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000, + 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000, + 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000, + 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000, + 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000, + 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000, + 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000, + 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000, + 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000, + 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000, + 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000, + 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000, + 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000, + 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000, + 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000, + 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000, + 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000, + 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000, + 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000, + 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000, + 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000, + 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000, + 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000, + 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000, + 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000, + 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000, + 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000, + 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000, + 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000, + 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000, + 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000, + 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000, + 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000, + 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000, + 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000, + 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000, + 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000, + 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000, + 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000, + 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000, + 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000, + 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000, + 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000, + 0x5185cd0900000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d, + 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac, + 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8, + 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95, + 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817, + 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d, + 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac, + 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6, + 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564, + 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39, + 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d, + 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac, + 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de, + 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594, + 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b, + 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01, + 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f, + 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de, + 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba, + 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65, + 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7, + 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad, + 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de, + 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294, + 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716, + 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71, + 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15, + 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4, + 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca, + 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280, + 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f, + 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15, + 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9, + 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748, + 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c, + 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971, + 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3, + 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9, + 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196, + 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc, + 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e, + 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03, + 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67, + 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296, + 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a, + 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170, + 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af, + 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5, + 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb, + 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a, + 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e, + 0x4b0c4f49}, + {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09, + 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc, + 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e, + 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc, + 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934, + 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2, + 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b, + 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad, + 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155, + 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187, + 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65, + 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390, + 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e, + 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378, + 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889, + 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f, + 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0, + 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145, + 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7, + 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a, + 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2, + 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924, + 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2, + 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514, + 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec, + 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709, + 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb, + 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e, + 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1, + 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227, + 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6, + 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030, + 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0, + 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55, + 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7, + 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165, + 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d, + 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b, + 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c, + 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a, + 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362, + 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0, + 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52, + 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7, + 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237, + 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1, + 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020, + 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6, + 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719, + 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec, + 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e, + 0x14d747e1}, + {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0, + 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b, + 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652, + 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437, + 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514, + 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265, + 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de, + 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af, + 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c, + 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9, + 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0, + 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b, + 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6, + 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7, + 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734, + 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045, + 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8, + 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303, + 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a, + 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9, + 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea, + 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b, + 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6, + 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7, + 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4, + 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6, + 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f, + 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054, + 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9, + 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8, + 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b, + 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a, + 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441, + 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a, + 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3, + 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6, + 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5, + 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94, + 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9, + 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288, + 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab, + 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce, + 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7, + 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c, + 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527, + 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256, + 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5, + 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4, + 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39, + 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2, + 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db, + 0xaa933b1a}, + {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603, + 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d, + 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9, + 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b, + 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a, + 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792, + 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4, + 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c, + 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d, + 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f, + 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb, + 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65, + 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330, + 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8, + 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da, + 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742, + 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f, + 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1, + 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5, + 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f, + 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e, + 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6, + 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8, + 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250, + 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021, + 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb, + 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f, + 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511, + 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c, + 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4, + 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886, + 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e, + 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b, + 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5, + 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791, + 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003, + 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272, + 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea, + 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc, + 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24, + 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55, + 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7, + 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3, + 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d, + 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548, + 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0, + 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2, + 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a, + 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47, + 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9, + 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad, + 0x65711936}}; + +#endif + +#endif + +#if N == 4 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a, + 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe, + 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b, + 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656, + 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd, + 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d, + 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7, + 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47, + 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac, + 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691, + 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404, + 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0, + 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4, + 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424, + 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5, + 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65, + 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67, + 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3, + 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626, + 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9, + 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222, + 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2, + 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a, + 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a, + 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1, + 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2, + 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077, + 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3, + 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1, + 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621, + 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0, + 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60, + 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0, + 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64, + 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1, + 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc, + 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027, + 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7, + 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9, + 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79, + 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292, + 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af, + 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a, + 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee, + 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e, + 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe, + 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f, + 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff, + 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd, + 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29, + 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc, + 0xe3c45916}, + {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344, + 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59, + 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e, + 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463, + 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98, + 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d, + 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3, + 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656, + 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad, + 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0, + 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397, + 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a, + 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2, + 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357, + 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8, + 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d, + 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696, + 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b, + 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc, + 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0, + 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b, + 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be, + 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811, + 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384, + 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f, + 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955, + 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362, + 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f, + 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94, + 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701, + 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe, + 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b, + 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1, + 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc, + 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b, + 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986, + 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d, + 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8, + 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4, + 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371, + 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a, + 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87, + 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0, + 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad, + 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527, + 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2, + 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d, + 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998, + 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73, + 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e, + 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59, + 0xa7520488}, + {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20, + 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09, + 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431, + 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a, + 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203, + 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b, + 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14, + 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c, + 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25, + 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e, + 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36, + 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f, + 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649, + 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961, + 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58, + 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170, + 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b, + 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742, + 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a, + 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55, + 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c, + 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64, + 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f, + 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77, + 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e, + 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a, + 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2, + 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b, + 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090, + 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8, + 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881, + 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9, + 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6, + 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f, + 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7, + 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c, + 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695, + 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd, + 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb, + 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3, + 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa, + 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1, + 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9, + 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0, + 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df, + 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7, + 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace, + 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6, + 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd, + 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4, + 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec, + 0x3522e9e4}, + {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1, + 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86, + 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b, + 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669, + 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7, + 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352, + 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03, + 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6, + 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38, + 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a, + 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7, + 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80, + 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7, + 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522, + 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d, + 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8, + 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103, + 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54, + 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9, + 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0, + 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e, + 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb, + 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1, + 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624, + 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea, + 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a, + 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37, + 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360, + 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab, + 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e, + 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741, + 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4, + 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334, + 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63, + 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de, + 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c, + 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942, + 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7, + 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131, + 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4, + 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a, + 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758, + 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5, + 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2, + 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32, + 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7, + 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8, + 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d, + 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6, + 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1, + 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c, + 0x97411e28}, + {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474, + 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5, + 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6, + 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7, + 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938, + 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051, + 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a, + 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3, + 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c, + 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d, + 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e, + 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf, + 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740, + 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29, + 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592, + 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb, + 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4, + 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365, + 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036, + 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7, + 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08, + 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561, + 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a, + 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663, + 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac, + 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d, + 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce, + 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f, + 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50, + 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639, + 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82, + 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb, + 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954, + 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5, + 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86, + 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7, + 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418, + 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71, + 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa, + 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93, + 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c, + 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d, + 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e, + 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df, + 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60, + 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309, + 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2, + 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db, + 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4, + 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45, + 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16, + 0x93c7a00b}, + {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45, + 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb, + 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d, + 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696, + 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf, + 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb, + 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028, + 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c, + 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65, + 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be, + 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038, + 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6, + 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15, + 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11, + 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d, + 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19, + 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05, + 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b, + 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d, + 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c, + 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35, + 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31, + 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068, + 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c, + 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25, + 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a, + 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac, + 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22, + 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e, + 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a, + 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36, + 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32, + 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84, + 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a, + 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c, + 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057, + 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e, + 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a, + 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc, + 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8, + 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1, + 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a, + 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec, + 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62, + 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4, + 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0, + 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc, + 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8, + 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4, + 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a, + 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc, + 0xce5f968d}, + {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de, + 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b, + 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d, + 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680, + 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4, + 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d, + 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde, + 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97, + 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3, + 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e, + 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678, + 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d, + 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723, + 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a, + 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0, + 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9, + 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85, + 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770, + 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56, + 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a, + 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e, + 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67, + 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785, + 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc, + 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788, + 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90, + 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6, + 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843, + 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f, + 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336, + 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac, + 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5, + 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68, + 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d, + 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb, + 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36, + 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72, + 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b, + 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b, + 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402, + 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446, + 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb, + 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed, + 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418, + 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95, + 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc, + 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946, + 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f, + 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233, + 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6, + 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0, + 0x3e721277}, + {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb, + 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9, + 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11, + 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d, + 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9, + 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c, + 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881, + 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274, + 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790, + 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc, + 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514, + 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56, + 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9, + 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c, + 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13, + 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6, + 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c, + 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e, + 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386, + 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376, + 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692, + 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67, + 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416, + 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3, + 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07, + 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd, + 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15, + 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457, + 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd, + 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28, + 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337, + 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2, + 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594, + 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6, + 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e, + 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52, + 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6, + 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143, + 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17, + 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2, + 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306, + 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a, + 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182, + 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0, + 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496, + 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63, + 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c, + 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89, + 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903, + 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041, + 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9, + 0x1c65ace7}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000, + 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000, + 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000, + 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000, + 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000, + 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000, + 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000, + 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000, + 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000, + 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000, + 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000, + 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000, + 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000, + 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000, + 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000, + 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000, + 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000, + 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000, + 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000, + 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000, + 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000, + 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000, + 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000, + 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000, + 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000, + 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000, + 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000, + 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000, + 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000, + 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000, + 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000, + 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000, + 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000, + 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000, + 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000, + 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000, + 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000, + 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000, + 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000, + 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000, + 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000, + 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000, + 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000, + 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000, + 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000, + 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000, + 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000, + 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000, + 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000, + 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000, + 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000, + 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000, + 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000, + 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000, + 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000, + 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000, + 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000, + 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000, + 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000, + 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000, + 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000, + 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000, + 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000, + 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000, + 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000, + 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000, + 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000, + 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000, + 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000, + 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000, + 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000, + 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000, + 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000, + 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000, + 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000, + 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000, + 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000, + 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000, + 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000, + 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000, + 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000, + 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000, + 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000, + 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000, + 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000, + 0xe7ac651c00000000}, + {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000, + 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000, + 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000, + 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000, + 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000, + 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000, + 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000, + 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000, + 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000, + 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000, + 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000, + 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000, + 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000, + 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000, + 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000, + 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000, + 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000, + 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000, + 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000, + 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000, + 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000, + 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000, + 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000, + 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000, + 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000, + 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000, + 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000, + 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000, + 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000, + 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000, + 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000, + 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000, + 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000, + 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000, + 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000, + 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000, + 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000, + 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000, + 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000, + 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000, + 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000, + 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000, + 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000, + 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000, + 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000, + 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000, + 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000, + 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000, + 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000, + 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000, + 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000, + 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000, + 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000, + 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000, + 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000, + 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000, + 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000, + 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000, + 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000, + 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000, + 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000, + 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000, + 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000, + 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000, + 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000, + 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000, + 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000, + 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000, + 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000, + 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000, + 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000, + 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000, + 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000, + 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000, + 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000, + 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000, + 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000, + 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000, + 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000, + 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000, + 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000, + 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000, + 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000, + 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000, + 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000, + 0x7712723e00000000}, + {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000, + 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000, + 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000, + 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000, + 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000, + 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000, + 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000, + 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000, + 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000, + 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000, + 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000, + 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000, + 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000, + 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000, + 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000, + 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000, + 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000, + 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000, + 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000, + 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000, + 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000, + 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000, + 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000, + 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000, + 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000, + 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000, + 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000, + 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000, + 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000, + 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000, + 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000, + 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000, + 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000, + 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000, + 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000, + 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000, + 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000, + 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000, + 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000, + 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000, + 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000, + 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000, + 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000, + 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000, + 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000, + 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000, + 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000, + 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000, + 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000, + 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000, + 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000, + 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000, + 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000, + 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000, + 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000, + 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000, + 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000, + 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000, + 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000, + 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000, + 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000, + 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000, + 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000, + 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000, + 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000, + 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000, + 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000, + 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000, + 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000, + 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000, + 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000, + 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000, + 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000, + 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000, + 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000, + 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000, + 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000, + 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000, + 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000, + 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000, + 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000, + 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000, + 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000, + 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000, + 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000, + 0x8d965fce00000000}, + {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000, + 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000, + 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000, + 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000, + 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000, + 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000, + 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000, + 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000, + 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000, + 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000, + 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000, + 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000, + 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000, + 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000, + 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000, + 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000, + 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000, + 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000, + 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000, + 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000, + 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000, + 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000, + 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000, + 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000, + 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000, + 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000, + 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000, + 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000, + 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000, + 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000, + 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000, + 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000, + 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000, + 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000, + 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000, + 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000, + 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000, + 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000, + 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000, + 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000, + 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000, + 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000, + 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000, + 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000, + 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000, + 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000, + 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000, + 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000, + 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000, + 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000, + 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000, + 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000, + 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000, + 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000, + 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000, + 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000, + 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000, + 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000, + 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000, + 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000, + 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000, + 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000, + 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000, + 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000, + 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000, + 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000, + 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000, + 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000, + 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000, + 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000, + 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000, + 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000, + 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000, + 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000, + 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000, + 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000, + 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000, + 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000, + 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000, + 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000, + 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000, + 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000, + 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000, + 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000, + 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000, + 0x0ba0c79300000000}, + {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000, + 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000, + 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000, + 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000, + 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000, + 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000, + 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000, + 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000, + 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000, + 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000, + 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000, + 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000, + 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000, + 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000, + 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000, + 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000, + 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000, + 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000, + 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000, + 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000, + 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000, + 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000, + 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000, + 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000, + 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000, + 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000, + 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000, + 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000, + 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000, + 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000, + 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000, + 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000, + 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000, + 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000, + 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000, + 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000, + 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000, + 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000, + 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000, + 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000, + 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000, + 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000, + 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000, + 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000, + 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000, + 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000, + 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000, + 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000, + 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000, + 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000, + 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000, + 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000, + 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000, + 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000, + 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000, + 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000, + 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000, + 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000, + 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000, + 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000, + 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000, + 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000, + 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000, + 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000, + 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000, + 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000, + 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000, + 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000, + 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000, + 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000, + 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000, + 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000, + 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000, + 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000, + 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000, + 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000, + 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000, + 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000, + 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000, + 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000, + 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000, + 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000, + 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000, + 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000, + 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000, + 0x281e419700000000}, + {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000, + 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000, + 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000, + 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000, + 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000, + 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000, + 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000, + 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000, + 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000, + 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000, + 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000, + 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000, + 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000, + 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000, + 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000, + 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000, + 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000, + 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000, + 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000, + 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000, + 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000, + 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000, + 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000, + 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000, + 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000, + 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000, + 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000, + 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000, + 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000, + 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000, + 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000, + 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000, + 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000, + 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000, + 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000, + 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000, + 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000, + 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000, + 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000, + 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000, + 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000, + 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000, + 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000, + 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000, + 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000, + 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000, + 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000, + 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000, + 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000, + 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000, + 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000, + 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000, + 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000, + 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000, + 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000, + 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000, + 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000, + 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000, + 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000, + 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000, + 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000, + 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000, + 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000, + 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000, + 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000, + 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000, + 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000, + 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000, + 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000, + 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000, + 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000, + 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000, + 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000, + 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000, + 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000, + 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000, + 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000, + 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000, + 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000, + 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000, + 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000, + 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000, + 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000, + 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000, + 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000, + 0xe4e9223500000000}, + {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000, + 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000, + 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000, + 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000, + 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000, + 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000, + 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000, + 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000, + 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000, + 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000, + 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000, + 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000, + 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000, + 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000, + 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000, + 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000, + 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000, + 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000, + 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000, + 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000, + 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000, + 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000, + 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000, + 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000, + 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000, + 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000, + 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000, + 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000, + 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000, + 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000, + 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000, + 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000, + 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000, + 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000, + 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000, + 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000, + 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000, + 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000, + 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000, + 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000, + 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000, + 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000, + 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000, + 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000, + 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000, + 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000, + 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000, + 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000, + 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000, + 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000, + 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000, + 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000, + 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000, + 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000, + 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000, + 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000, + 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000, + 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000, + 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000, + 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000, + 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000, + 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000, + 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000, + 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000, + 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000, + 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000, + 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000, + 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000, + 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000, + 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000, + 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000, + 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000, + 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000, + 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000, + 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000, + 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000, + 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000, + 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000, + 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000, + 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000, + 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000, + 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000, + 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000, + 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000, + 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000, + 0x880452a700000000}, + {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000, + 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000, + 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000, + 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000, + 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000, + 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000, + 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000, + 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000, + 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000, + 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000, + 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000, + 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000, + 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000, + 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000, + 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000, + 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000, + 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000, + 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000, + 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000, + 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000, + 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000, + 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000, + 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000, + 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000, + 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000, + 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000, + 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000, + 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000, + 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000, + 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000, + 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000, + 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000, + 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000, + 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000, + 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000, + 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000, + 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000, + 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000, + 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000, + 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000, + 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000, + 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000, + 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000, + 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000, + 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000, + 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000, + 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000, + 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000, + 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000, + 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000, + 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000, + 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000, + 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000, + 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000, + 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000, + 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000, + 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000, + 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000, + 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000, + 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000, + 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000, + 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000, + 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000, + 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000, + 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000, + 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000, + 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000, + 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000, + 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000, + 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000, + 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000, + 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000, + 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000, + 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000, + 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000, + 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000, + 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000, + 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000, + 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000, + 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000, + 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000, + 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000, + 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000, + 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000, + 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000, + 0x1659c4e300000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0, + 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587, + 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa, + 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09, + 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee, + 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3, + 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3, + 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce, + 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429, + 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda, + 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7, + 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0, + 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd, + 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0, + 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287, + 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a, + 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9, + 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e, + 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3, + 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3, + 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054, + 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49, + 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da, + 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7, + 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20, + 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d, + 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00, + 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347, + 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14, + 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209, + 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e, + 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33, + 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3, + 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194, + 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9, + 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a, + 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd, + 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0, + 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d, + 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460, + 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87, + 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674, + 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509, + 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e, + 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae, + 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3, + 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694, + 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989, + 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da, + 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d, + 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0, + 0xa68cee3d}, + {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19, + 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae, + 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb, + 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a, + 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55, + 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1, + 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c, + 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8, + 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7, + 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936, + 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453, + 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4, + 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941, + 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5, + 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93, + 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17, + 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e, + 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89, + 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec, + 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0, + 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf, + 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b, + 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b, + 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f, + 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0, + 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e, + 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b, + 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc, + 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5, + 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261, + 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637, + 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3, + 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57, + 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0, + 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85, + 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454, + 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b, + 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f, + 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423, + 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7, + 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8, + 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739, + 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c, + 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb, + 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f, + 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b, + 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd, + 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59, + 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070, + 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7, + 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2, + 0x51e8883f}, + {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a, + 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276, + 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed, + 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55, + 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b, + 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8, + 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320, + 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413, + 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd, + 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75, + 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee, + 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312, + 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca, + 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9, + 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad, + 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e, + 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504, + 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8, + 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63, + 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353, + 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d, + 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be, + 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae, + 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d, + 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943, + 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7, + 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c, + 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390, + 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a, + 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239, + 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d, + 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e, + 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c, + 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0, + 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b, + 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93, + 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d, + 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e, + 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c, + 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f, + 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1, + 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579, + 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2, + 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e, + 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c, + 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f, + 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b, + 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158, + 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2, + 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e, + 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5, + 0x8ae9531c}, + {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4, + 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd, + 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220, + 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf, + 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495, + 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def, + 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90, + 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea, + 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0, + 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f, + 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2, + 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab, + 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e, + 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754, + 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda, + 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0, + 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c, + 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215, + 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8, + 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910, + 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a, + 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30, + 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658, + 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22, + 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478, + 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2, + 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f, + 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606, + 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba, + 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0, + 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e, + 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034, + 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f, + 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996, + 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b, + 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84, + 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de, + 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4, + 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5, + 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f, + 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5, + 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a, + 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7, + 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce, + 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65, + 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f, + 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91, + 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb, + 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57, + 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e, + 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3, + 0xd739710d}}; + +#endif + +#endif + +#if N == 5 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df, + 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8, + 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef, + 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376, + 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201, + 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399, + 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372, + 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea, + 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d, + 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004, + 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353, + 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334, + 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a, + 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2, + 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a, + 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2, + 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b, + 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c, + 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b, + 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f, + 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338, + 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0, + 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6, + 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e, + 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319, + 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3, + 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4, + 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783, + 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a, + 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492, + 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a, + 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2, + 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496, + 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1, + 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6, + 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f, + 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548, + 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0, + 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741, + 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9, + 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae, + 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437, + 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760, + 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707, + 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433, + 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab, + 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703, + 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b, + 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412, + 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475, + 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722, + 0xe9947565}, + {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5, + 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22, + 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c, + 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed, + 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d, + 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1, + 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e, + 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32, + 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142, + 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93, + 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d, + 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a, + 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58, + 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14, + 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81, + 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd, + 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab, + 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c, + 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72, + 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f, + 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff, + 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3, + 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30, + 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c, + 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c, + 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558, + 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146, + 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581, + 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7, + 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab, + 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e, + 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272, + 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838, + 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff, + 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1, + 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330, + 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840, + 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c, + 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb, + 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7, + 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7, + 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616, + 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208, + 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf, + 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85, + 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9, + 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c, + 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10, + 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76, + 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1, + 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf, + 0xf7d05006}, + {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b, + 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774, + 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58, + 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a, + 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb, + 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952, + 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e, + 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7, + 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746, + 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14, + 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338, + 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907, + 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777, + 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de, + 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064, + 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd, + 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951, + 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e, + 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42, + 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b, + 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a, + 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3, + 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904, + 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad, + 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c, + 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d, + 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861, + 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e, + 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2, + 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b, + 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1, + 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78, + 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f, + 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40, + 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c, + 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e, + 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf, + 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166, + 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d, + 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4, + 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805, + 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157, + 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b, + 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644, + 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43, + 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea, + 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850, + 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9, + 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165, + 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a, + 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676, + 0xb2075b94}, + {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf, + 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61, + 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be, + 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd, + 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3, + 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063, + 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105, + 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5, + 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb, + 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8, + 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07, + 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9, + 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5, + 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515, + 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4, + 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014, + 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7, + 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269, + 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6, + 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af, + 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1, + 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111, + 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d, + 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad, + 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3, + 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75, + 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa, + 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74, + 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7, + 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477, + 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6, + 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176, + 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af, + 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71, + 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae, + 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd, + 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3, + 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073, + 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0, + 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400, + 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e, + 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d, + 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2, + 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c, + 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5, + 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505, + 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4, + 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004, + 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7, + 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279, + 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6, + 0xba50bcb9}, + {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897, + 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb, + 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2, + 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2, + 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372, + 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70, + 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92, + 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190, + 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40, + 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430, + 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759, + 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75, + 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2, + 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0, + 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7, + 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5, + 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39, + 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215, + 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c, + 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5, + 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625, + 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27, + 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c, + 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e, + 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee, + 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71, + 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18, + 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134, + 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8, + 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba, + 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd, + 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff, + 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a, + 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6, + 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf, + 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf, + 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f, + 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d, + 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d, + 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f, + 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af, + 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df, + 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6, + 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a, + 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef, + 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed, + 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa, + 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8, + 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624, + 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08, + 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861, + 0x808abcf4}, + {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2, + 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd, + 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76, + 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52, + 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e, + 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124, + 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147, + 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d, + 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31, + 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15, + 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae, + 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1, + 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d, + 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307, + 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9, + 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3, + 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084, + 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb, + 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850, + 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2, + 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe, + 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94, + 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261, + 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b, + 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917, + 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53, + 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8, + 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787, + 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0, + 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba, + 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404, + 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e, + 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af, + 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0, + 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b, + 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f, + 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543, + 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129, + 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627, + 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d, + 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51, + 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75, + 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce, + 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1, + 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760, + 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a, + 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4, + 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde, + 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089, + 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6, + 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d, + 0xefdb3f95}, + {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8, + 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7, + 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945, + 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9, + 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652, + 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc, + 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a, + 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4, + 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f, + 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3, + 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51, + 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e, + 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c, + 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362, + 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11, + 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff, + 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7, + 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8, + 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a, + 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690, + 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b, + 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5, + 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05, + 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb, + 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740, + 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f, + 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded, + 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2, + 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa, + 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714, + 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67, + 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89, + 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7, + 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8, + 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a, + 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6, + 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d, + 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3, + 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9, + 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57, + 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc, + 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540, + 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2, + 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd, + 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93, + 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d, + 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e, + 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0, + 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8, + 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7, + 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75, + 0x0e2fbf43}, + {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc, + 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a, + 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3, + 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7, + 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b, + 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154, + 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3, + 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc, + 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330, + 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264, + 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd, + 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b, + 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a, + 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175, + 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275, + 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a, + 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234, + 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2, + 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b, + 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a, + 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6, + 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189, + 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b, + 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204, + 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8, + 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226, + 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff, + 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219, + 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167, + 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258, + 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158, + 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267, + 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c, + 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da, + 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003, + 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157, + 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b, + 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4, + 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179, + 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246, + 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a, + 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de, + 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107, + 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1, + 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba, + 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285, + 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185, + 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba, + 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4, + 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322, + 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb, + 0xf4377108}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000, + 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000, + 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000, + 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000, + 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000, + 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000, + 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000, + 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000, + 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000, + 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000, + 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000, + 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000, + 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000, + 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000, + 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000, + 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000, + 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000, + 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000, + 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000, + 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000, + 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000, + 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000, + 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000, + 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000, + 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000, + 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000, + 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000, + 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000, + 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000, + 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000, + 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000, + 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000, + 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000, + 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000, + 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000, + 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000, + 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000, + 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000, + 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000, + 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000, + 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000, + 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000, + 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000, + 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000, + 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000, + 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000, + 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000, + 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000, + 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000, + 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000, + 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000, + 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000, + 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000, + 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000, + 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000, + 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000, + 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000, + 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000, + 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000, + 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000, + 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000, + 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000, + 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000, + 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000, + 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000, + 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000, + 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000, + 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000, + 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000, + 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000, + 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000, + 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000, + 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000, + 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000, + 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000, + 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000, + 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000, + 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000, + 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000, + 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000, + 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000, + 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000, + 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000, + 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000, + 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000, + 0x087137f400000000}, + {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000, + 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000, + 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000, + 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000, + 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000, + 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000, + 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000, + 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000, + 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000, + 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000, + 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000, + 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000, + 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000, + 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000, + 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000, + 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000, + 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000, + 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000, + 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000, + 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000, + 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000, + 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000, + 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000, + 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000, + 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000, + 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000, + 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000, + 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000, + 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000, + 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000, + 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000, + 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000, + 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000, + 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000, + 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000, + 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000, + 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000, + 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000, + 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000, + 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000, + 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000, + 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000, + 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000, + 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000, + 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000, + 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000, + 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000, + 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000, + 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000, + 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000, + 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000, + 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000, + 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000, + 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000, + 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000, + 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000, + 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000, + 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000, + 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000, + 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000, + 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000, + 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000, + 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000, + 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000, + 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000, + 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000, + 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000, + 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000, + 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000, + 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000, + 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000, + 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000, + 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000, + 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000, + 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000, + 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000, + 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000, + 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000, + 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000, + 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000, + 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000, + 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000, + 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000, + 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000, + 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000, + 0x43bf2f0e00000000}, + {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000, + 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000, + 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000, + 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000, + 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000, + 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000, + 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000, + 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000, + 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000, + 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000, + 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000, + 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000, + 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000, + 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000, + 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000, + 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000, + 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000, + 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000, + 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000, + 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000, + 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000, + 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000, + 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000, + 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000, + 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000, + 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000, + 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000, + 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000, + 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000, + 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000, + 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000, + 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000, + 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000, + 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000, + 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000, + 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000, + 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000, + 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000, + 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000, + 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000, + 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000, + 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000, + 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000, + 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000, + 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000, + 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000, + 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000, + 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000, + 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000, + 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000, + 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000, + 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000, + 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000, + 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000, + 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000, + 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000, + 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000, + 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000, + 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000, + 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000, + 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000, + 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000, + 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000, + 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000, + 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000, + 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000, + 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000, + 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000, + 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000, + 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000, + 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000, + 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000, + 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000, + 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000, + 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000, + 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000, + 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000, + 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000, + 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000, + 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000, + 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000, + 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000, + 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000, + 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000, + 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000, + 0x953fdbef00000000}, + {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000, + 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000, + 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000, + 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000, + 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000, + 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000, + 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000, + 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000, + 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000, + 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000, + 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000, + 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000, + 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000, + 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000, + 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000, + 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000, + 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000, + 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000, + 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000, + 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000, + 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000, + 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000, + 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000, + 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000, + 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000, + 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000, + 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000, + 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000, + 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000, + 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000, + 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000, + 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000, + 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000, + 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000, + 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000, + 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000, + 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000, + 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000, + 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000, + 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000, + 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000, + 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000, + 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000, + 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000, + 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000, + 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000, + 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000, + 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000, + 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000, + 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000, + 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000, + 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000, + 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000, + 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000, + 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000, + 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000, + 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000, + 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000, + 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000, + 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000, + 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000, + 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000, + 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000, + 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000, + 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000, + 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000, + 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000, + 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000, + 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000, + 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000, + 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000, + 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000, + 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000, + 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000, + 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000, + 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000, + 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000, + 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000, + 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000, + 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000, + 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000, + 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000, + 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000, + 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000, + 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000, + 0xf4bc8a8000000000}, + {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000, + 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000, + 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000, + 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000, + 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000, + 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000, + 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000, + 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000, + 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000, + 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000, + 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000, + 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000, + 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000, + 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000, + 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000, + 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000, + 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000, + 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000, + 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000, + 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000, + 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000, + 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000, + 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000, + 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000, + 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000, + 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000, + 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000, + 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000, + 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000, + 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000, + 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000, + 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000, + 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000, + 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000, + 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000, + 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000, + 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000, + 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000, + 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000, + 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000, + 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000, + 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000, + 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000, + 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000, + 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000, + 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000, + 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000, + 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000, + 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000, + 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000, + 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000, + 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000, + 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000, + 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000, + 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000, + 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000, + 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000, + 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000, + 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000, + 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000, + 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000, + 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000, + 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000, + 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000, + 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000, + 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000, + 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000, + 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000, + 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000, + 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000, + 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000, + 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000, + 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000, + 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000, + 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000, + 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000, + 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000, + 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000, + 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000, + 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000, + 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000, + 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000, + 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000, + 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000, + 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000, + 0xb9bc50ba00000000}, + {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000, + 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000, + 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000, + 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000, + 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000, + 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000, + 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000, + 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000, + 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000, + 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000, + 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000, + 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000, + 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000, + 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000, + 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000, + 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000, + 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000, + 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000, + 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000, + 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000, + 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000, + 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000, + 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000, + 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000, + 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000, + 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000, + 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000, + 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000, + 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000, + 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000, + 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000, + 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000, + 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000, + 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000, + 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000, + 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000, + 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000, + 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000, + 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000, + 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000, + 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000, + 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000, + 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000, + 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000, + 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000, + 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000, + 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000, + 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000, + 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000, + 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000, + 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000, + 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000, + 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000, + 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000, + 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000, + 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000, + 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000, + 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000, + 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000, + 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000, + 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000, + 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000, + 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000, + 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000, + 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000, + 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000, + 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000, + 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000, + 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000, + 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000, + 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000, + 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000, + 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000, + 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000, + 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000, + 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000, + 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000, + 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000, + 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000, + 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000, + 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000, + 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000, + 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000, + 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000, + 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000, + 0x945b07b200000000}, + {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000, + 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000, + 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000, + 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000, + 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000, + 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000, + 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000, + 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000, + 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000, + 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000, + 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000, + 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000, + 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000, + 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000, + 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000, + 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000, + 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000, + 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000, + 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000, + 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000, + 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000, + 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000, + 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000, + 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000, + 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000, + 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000, + 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000, + 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000, + 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000, + 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000, + 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000, + 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000, + 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000, + 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000, + 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000, + 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000, + 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000, + 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000, + 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000, + 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000, + 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000, + 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000, + 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000, + 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000, + 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000, + 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000, + 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000, + 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000, + 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000, + 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000, + 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000, + 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000, + 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000, + 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000, + 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000, + 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000, + 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000, + 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000, + 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000, + 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000, + 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000, + 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000, + 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000, + 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000, + 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000, + 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000, + 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000, + 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000, + 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000, + 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000, + 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000, + 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000, + 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000, + 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000, + 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000, + 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000, + 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000, + 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000, + 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000, + 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000, + 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000, + 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000, + 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000, + 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000, + 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000, + 0x0650d0f700000000}, + {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000, + 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000, + 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000, + 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000, + 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000, + 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000, + 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000, + 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000, + 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000, + 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000, + 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000, + 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000, + 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000, + 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000, + 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000, + 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000, + 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000, + 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000, + 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000, + 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000, + 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000, + 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000, + 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000, + 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000, + 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000, + 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000, + 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000, + 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000, + 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000, + 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000, + 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000, + 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000, + 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000, + 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000, + 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000, + 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000, + 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000, + 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000, + 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000, + 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000, + 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000, + 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000, + 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000, + 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000, + 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000, + 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000, + 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000, + 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000, + 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000, + 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000, + 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000, + 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000, + 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000, + 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000, + 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000, + 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000, + 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000, + 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000, + 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000, + 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000, + 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000, + 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000, + 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000, + 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000, + 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000, + 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000, + 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000, + 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000, + 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000, + 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000, + 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000, + 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000, + 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000, + 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000, + 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000, + 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000, + 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000, + 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000, + 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000, + 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000, + 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000, + 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000, + 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000, + 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000, + 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000, + 0x657594e900000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873, + 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661, + 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441, + 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44, + 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1, + 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05, + 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa, + 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e, + 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb, + 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be, + 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e, + 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c, + 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d, + 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9, + 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f, + 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b, + 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39, + 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b, + 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b, + 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20, + 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595, + 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61, + 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0, + 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644, + 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1, + 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d, + 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d, + 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f, + 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad, + 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359, + 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f, + 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b, + 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7, + 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5, + 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5, + 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0, + 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65, + 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091, + 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633, + 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7, + 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272, + 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77, + 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57, + 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145, + 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9, + 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d, + 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb, + 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f, + 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad, + 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf, + 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f, + 0x4e36ba18}, + {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b, + 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8, + 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19, + 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4, + 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239, + 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd, + 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258, + 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc, + 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41, + 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c, + 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d, + 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e, + 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba, + 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e, + 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8, + 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c, + 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f, + 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c, + 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d, + 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d, + 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0, + 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014, + 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc, + 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628, + 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5, + 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941, + 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0, + 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53, + 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880, + 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264, + 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92, + 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776, + 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8, + 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b, + 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea, + 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837, + 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca, + 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e, + 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211, + 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5, + 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08, + 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5, + 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934, + 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7, + 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049, + 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad, + 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b, + 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf, + 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c, + 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f, + 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e, + 0xa1d67c91}, + {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9, + 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de, + 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94, + 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0, + 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a, + 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924, + 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052, + 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c, + 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6, + 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2, + 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8, + 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f, + 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d, + 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273, + 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30, + 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e, + 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7, + 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980, + 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca, + 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8, + 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62, + 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c, + 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c, + 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032, + 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798, + 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d, + 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07, + 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630, + 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389, + 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7, + 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4, + 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca, + 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55, + 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662, + 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828, + 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c, + 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6, + 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98, + 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3, + 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d, + 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037, + 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913, + 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759, + 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e, + 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1, + 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf, + 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c, + 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2, + 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b, + 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c, + 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276, + 0xa8ef40a1}, + {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e, + 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8, + 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819, + 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f, + 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d, + 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756, + 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0, + 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb, + 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9, + 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f, + 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e, + 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8, + 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835, + 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e, + 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62, + 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749, + 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b, + 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d, + 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc, + 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80, + 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2, + 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599, + 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05, + 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e, + 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c, + 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e, + 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef, + 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359, + 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b, + 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0, + 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc, + 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7, + 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f, + 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189, + 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568, + 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e, + 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c, + 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27, + 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794, + 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf, + 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d, + 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db, + 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a, + 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c, + 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544, + 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f, + 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013, + 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38, + 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea, + 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c, + 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd, + 0x356bacd8}}; + +#endif + +#endif + +#if N == 6 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370, + 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d, + 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69, + 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426, + 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3, + 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f, + 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c, + 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490, + 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155, + 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a, + 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e, + 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603, + 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349, + 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5, + 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50, + 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc, + 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b, + 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76, + 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862, + 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9, + 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c, + 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0, + 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937, + 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b, + 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e, + 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e, + 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a, + 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357, + 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0, + 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c, + 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9, + 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165, + 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766, + 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b, + 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f, + 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030, + 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5, + 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59, + 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63, + 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf, + 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a, + 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845, + 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51, + 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c, + 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f, + 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3, + 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46, + 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea, + 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d, + 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60, + 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74, + 0x8568a0a8}, + {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5, + 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf, + 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5, + 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba, + 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf, + 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f, + 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0, + 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450, + 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55, + 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a, + 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620, + 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a, + 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454, + 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4, + 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534, + 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584, + 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694, + 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e, + 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4, + 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1, + 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4, + 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164, + 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1, + 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911, + 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314, + 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c, + 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6, + 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec, + 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc, + 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c, + 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c, + 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c, + 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716, + 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c, + 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676, + 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879, + 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c, + 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc, + 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77, + 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7, + 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2, + 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd, + 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7, + 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad, + 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897, + 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827, + 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7, + 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947, + 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57, + 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d, + 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37, + 0x0d907052}, + {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d, + 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89, + 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31, + 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81, + 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e, + 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0, + 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f, + 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291, + 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e, + 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e, + 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936, + 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2, + 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13, + 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d, + 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f, + 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1, + 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a, + 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae, + 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516, + 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f, + 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20, + 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe, + 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28, + 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6, + 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419, + 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5, + 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d, + 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889, + 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412, + 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c, + 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e, + 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0, + 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02, + 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986, + 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e, + 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e, + 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221, + 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf, + 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913, + 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d, + 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622, + 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592, + 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a, + 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae, + 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c, + 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82, + 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20, + 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe, + 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025, + 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1, + 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719, + 0xfd1a6c8a}, + {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3, + 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb, + 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d, + 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb, + 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9, + 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156, + 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045, + 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa, + 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8, + 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e, + 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8, + 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0, + 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38, + 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87, + 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46, + 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9, + 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585, + 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d, + 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb, + 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531, + 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03, + 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc, + 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33, + 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c, + 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be, + 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d, + 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b, + 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303, + 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f, + 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0, + 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801, + 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe, + 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e, + 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346, + 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620, + 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776, + 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844, + 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb, + 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0, + 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f, + 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d, + 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b, + 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d, + 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75, + 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795, + 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a, + 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb, + 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354, + 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28, + 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30, + 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856, + 0x7895f01a}, + {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188, + 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33, + 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d, + 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445, + 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2, + 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058, + 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43, + 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9, + 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e, + 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06, + 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228, + 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93, + 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e, + 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4, + 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b, + 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371, + 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265, + 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede, + 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0, + 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f, + 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8, + 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32, + 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae, + 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544, + 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3, + 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f, + 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911, + 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa, + 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be, + 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54, + 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b, + 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1, + 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652, + 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9, + 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7, + 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f, + 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68, + 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782, + 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797, + 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d, + 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a, + 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2, + 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc, + 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647, + 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4, + 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e, + 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41, + 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab, + 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf, + 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904, + 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a, + 0x9239b848}, + {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad, + 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0, + 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40, + 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b, + 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d, + 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b, + 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb, + 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d, + 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b, + 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0, + 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840, + 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d, + 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b, + 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d, + 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6, + 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0, + 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580, + 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd, + 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d, + 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b, + 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d, + 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b, + 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6, + 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0, + 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6, + 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c, + 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c, + 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461, + 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841, + 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317, + 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac, + 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa, + 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7, + 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba, + 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a, + 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161, + 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777, + 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21, + 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a, + 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc, + 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da, + 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1, + 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01, + 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c, + 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241, + 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917, + 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac, + 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa, + 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da, + 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397, + 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537, + 0xeb36d3cc}, + {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b, + 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059, + 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251, + 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d, + 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9, + 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c, + 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41, + 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4, + 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10, + 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c, + 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54, + 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476, + 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8, + 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d, + 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92, + 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307, + 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad, + 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f, + 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87, + 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17, + 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3, + 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46, + 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197, + 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02, + 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6, + 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e, + 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96, + 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4, + 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e, + 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b, + 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934, + 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1, + 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7, + 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5, + 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd, + 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1, + 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475, + 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0, + 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155, + 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0, + 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304, + 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348, + 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140, + 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862, + 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14, + 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181, + 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e, + 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab, + 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01, + 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523, + 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b, + 0x38e5f3c5}, + {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06, + 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad, + 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509, + 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba, + 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414, + 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3, + 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733, + 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994, + 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a, + 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889, + 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d, + 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386, + 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621, + 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886, + 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e, + 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389, + 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f, + 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294, + 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30, + 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3, + 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d, + 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba, + 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a, + 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad, + 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03, + 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2, + 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306, + 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad, + 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b, + 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc, + 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914, + 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3, + 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435, + 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e, + 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a, + 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589, + 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27, + 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080, + 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21, + 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586, + 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28, + 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b, + 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f, + 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94, + 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12, + 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5, + 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d, + 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba, + 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c, + 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7, + 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103, + 0x3d3101a2}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000, + 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000, + 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000, + 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000, + 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000, + 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000, + 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000, + 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000, + 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000, + 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000, + 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000, + 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000, + 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000, + 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000, + 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000, + 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000, + 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000, + 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000, + 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000, + 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000, + 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000, + 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000, + 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000, + 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000, + 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000, + 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000, + 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000, + 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000, + 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000, + 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000, + 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000, + 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000, + 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000, + 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000, + 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000, + 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000, + 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000, + 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000, + 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000, + 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000, + 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000, + 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000, + 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000, + 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000, + 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000, + 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000, + 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000, + 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000, + 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000, + 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000, + 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000, + 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000, + 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000, + 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000, + 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000, + 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000, + 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000, + 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000, + 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000, + 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000, + 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000, + 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000, + 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000, + 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000, + 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000, + 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000, + 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000, + 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000, + 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000, + 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000, + 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000, + 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000, + 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000, + 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000, + 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000, + 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000, + 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000, + 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000, + 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000, + 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000, + 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000, + 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000, + 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000, + 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000, + 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000, + 0xa201313d00000000}, + {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000, + 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000, + 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000, + 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000, + 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000, + 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000, + 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000, + 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000, + 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000, + 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000, + 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000, + 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000, + 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000, + 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000, + 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000, + 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000, + 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000, + 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000, + 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000, + 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000, + 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000, + 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000, + 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000, + 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000, + 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000, + 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000, + 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000, + 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000, + 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000, + 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000, + 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000, + 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000, + 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000, + 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000, + 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000, + 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000, + 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000, + 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000, + 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000, + 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000, + 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000, + 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000, + 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000, + 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000, + 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000, + 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000, + 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000, + 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000, + 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000, + 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000, + 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000, + 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000, + 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000, + 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000, + 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000, + 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000, + 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000, + 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000, + 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000, + 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000, + 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000, + 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000, + 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000, + 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000, + 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000, + 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000, + 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000, + 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000, + 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000, + 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000, + 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000, + 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000, + 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000, + 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000, + 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000, + 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000, + 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000, + 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000, + 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000, + 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000, + 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000, + 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000, + 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000, + 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000, + 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000, + 0xc5f3e53800000000}, + {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000, + 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000, + 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000, + 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000, + 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000, + 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000, + 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000, + 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000, + 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000, + 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000, + 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000, + 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000, + 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000, + 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000, + 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000, + 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000, + 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000, + 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000, + 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000, + 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000, + 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000, + 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000, + 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000, + 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000, + 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000, + 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000, + 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000, + 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000, + 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000, + 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000, + 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000, + 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000, + 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000, + 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000, + 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000, + 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000, + 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000, + 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000, + 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000, + 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000, + 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000, + 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000, + 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000, + 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000, + 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000, + 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000, + 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000, + 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000, + 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000, + 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000, + 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000, + 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000, + 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000, + 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000, + 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000, + 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000, + 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000, + 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000, + 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000, + 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000, + 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000, + 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000, + 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000, + 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000, + 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000, + 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000, + 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000, + 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000, + 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000, + 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000, + 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000, + 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000, + 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000, + 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000, + 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000, + 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000, + 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000, + 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000, + 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000, + 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000, + 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000, + 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000, + 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000, + 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000, + 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000, + 0xccd336eb00000000}, + {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000, + 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000, + 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000, + 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000, + 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000, + 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000, + 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000, + 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000, + 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000, + 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000, + 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000, + 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000, + 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000, + 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000, + 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000, + 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000, + 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000, + 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000, + 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000, + 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000, + 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000, + 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000, + 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000, + 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000, + 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000, + 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000, + 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000, + 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000, + 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000, + 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000, + 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000, + 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000, + 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000, + 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000, + 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000, + 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000, + 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000, + 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000, + 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000, + 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000, + 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000, + 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000, + 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000, + 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000, + 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000, + 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000, + 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000, + 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000, + 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000, + 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000, + 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000, + 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000, + 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000, + 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000, + 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000, + 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000, + 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000, + 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000, + 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000, + 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000, + 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000, + 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000, + 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000, + 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000, + 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000, + 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000, + 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000, + 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000, + 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000, + 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000, + 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000, + 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000, + 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000, + 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000, + 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000, + 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000, + 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000, + 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000, + 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000, + 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000, + 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000, + 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000, + 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000, + 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000, + 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000, + 0x48b8399200000000}, + {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000, + 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000, + 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000, + 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000, + 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000, + 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000, + 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000, + 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000, + 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000, + 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000, + 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000, + 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000, + 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000, + 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000, + 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000, + 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000, + 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000, + 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000, + 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000, + 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000, + 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000, + 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000, + 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000, + 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000, + 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000, + 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000, + 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000, + 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000, + 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000, + 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000, + 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000, + 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000, + 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000, + 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000, + 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000, + 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000, + 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000, + 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000, + 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000, + 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000, + 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000, + 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000, + 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000, + 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000, + 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000, + 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000, + 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000, + 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000, + 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000, + 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000, + 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000, + 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000, + 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000, + 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000, + 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000, + 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000, + 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000, + 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000, + 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000, + 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000, + 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000, + 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000, + 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000, + 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000, + 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000, + 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000, + 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000, + 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000, + 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000, + 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000, + 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000, + 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000, + 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000, + 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000, + 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000, + 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000, + 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000, + 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000, + 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000, + 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000, + 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000, + 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000, + 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000, + 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000, + 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000, + 0x1af0957800000000}, + {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000, + 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000, + 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000, + 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000, + 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000, + 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000, + 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000, + 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000, + 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000, + 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000, + 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000, + 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000, + 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000, + 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000, + 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000, + 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000, + 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000, + 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000, + 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000, + 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000, + 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000, + 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000, + 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000, + 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000, + 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000, + 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000, + 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000, + 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000, + 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000, + 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000, + 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000, + 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000, + 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000, + 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000, + 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000, + 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000, + 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000, + 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000, + 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000, + 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000, + 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000, + 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000, + 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000, + 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000, + 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000, + 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000, + 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000, + 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000, + 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000, + 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000, + 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000, + 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000, + 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000, + 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000, + 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000, + 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000, + 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000, + 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000, + 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000, + 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000, + 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000, + 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000, + 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000, + 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000, + 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000, + 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000, + 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000, + 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000, + 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000, + 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000, + 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000, + 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000, + 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000, + 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000, + 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000, + 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000, + 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000, + 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000, + 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000, + 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000, + 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000, + 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000, + 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000, + 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000, + 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000, + 0x8a6c1afd00000000}, + {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000, + 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000, + 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000, + 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000, + 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000, + 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000, + 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000, + 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000, + 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000, + 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000, + 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000, + 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000, + 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000, + 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000, + 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000, + 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000, + 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000, + 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000, + 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000, + 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000, + 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000, + 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000, + 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000, + 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000, + 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000, + 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000, + 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000, + 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000, + 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000, + 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000, + 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000, + 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000, + 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000, + 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000, + 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000, + 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000, + 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000, + 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000, + 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000, + 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000, + 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000, + 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000, + 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000, + 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000, + 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000, + 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000, + 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000, + 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000, + 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000, + 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000, + 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000, + 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000, + 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000, + 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000, + 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000, + 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000, + 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000, + 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000, + 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000, + 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000, + 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000, + 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000, + 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000, + 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000, + 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000, + 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000, + 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000, + 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000, + 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000, + 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000, + 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000, + 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000, + 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000, + 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000, + 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000, + 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000, + 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000, + 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000, + 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000, + 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000, + 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000, + 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000, + 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000, + 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000, + 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000, + 0x5270900d00000000}, + {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000, + 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000, + 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000, + 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000, + 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000, + 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000, + 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000, + 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000, + 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000, + 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000, + 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000, + 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000, + 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000, + 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000, + 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000, + 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000, + 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000, + 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000, + 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000, + 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000, + 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000, + 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000, + 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000, + 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000, + 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000, + 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000, + 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000, + 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000, + 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000, + 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000, + 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000, + 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000, + 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000, + 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000, + 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000, + 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000, + 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000, + 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000, + 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000, + 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000, + 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000, + 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000, + 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000, + 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000, + 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000, + 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000, + 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000, + 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000, + 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000, + 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000, + 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000, + 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000, + 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000, + 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000, + 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000, + 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000, + 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000, + 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000, + 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000, + 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000, + 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000, + 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000, + 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000, + 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000, + 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000, + 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000, + 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000, + 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000, + 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000, + 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000, + 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000, + 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000, + 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000, + 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000, + 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000, + 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000, + 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000, + 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000, + 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000, + 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000, + 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000, + 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000, + 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000, + 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000, + 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000, + 0xa8a0688500000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912, + 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba, + 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3, + 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30, + 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e, + 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3, + 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73, + 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe, + 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0, + 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643, + 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a, + 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082, + 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4, + 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279, + 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735, + 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8, + 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad, + 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05, + 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c, + 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718, + 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46, + 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb, + 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc, + 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41, + 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f, + 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad, + 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4, + 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c, + 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779, + 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4, + 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8, + 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235, + 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7, + 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f, + 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476, + 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195, + 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb, + 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46, + 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622, + 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af, + 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1, + 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12, + 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b, + 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3, + 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51, + 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc, + 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90, + 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d, + 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708, + 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0, + 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9, + 0x48686b56}, + {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c, + 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae, + 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb, + 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90, + 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410, + 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b, + 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6, + 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed, + 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d, + 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036, + 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953, + 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1, + 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca, + 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781, + 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d, + 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416, + 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f, + 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd, + 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8, + 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b, + 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb, + 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0, + 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5, + 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e, + 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e, + 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558, + 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d, + 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf, + 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6, + 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad, + 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971, + 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a, + 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b, + 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969, + 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c, + 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57, + 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7, + 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c, + 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab, + 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0, + 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160, + 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b, + 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e, + 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac, + 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d, + 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546, + 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a, + 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1, + 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8, + 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a, + 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f, + 0xcaa25178}, + {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00, + 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b, + 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed, + 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777, + 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01, + 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a, + 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef, + 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74, + 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002, + 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498, + 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee, + 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75, + 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05, + 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e, + 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8, + 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73, + 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404, + 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f, + 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9, + 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71, + 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607, + 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c, + 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb, + 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470, + 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806, + 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790, + 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6, + 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d, + 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a, + 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991, + 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7, + 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c, + 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09, + 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92, + 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4, + 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e, + 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08, + 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593, + 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3, + 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778, + 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e, + 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94, + 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2, + 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079, + 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c, + 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497, + 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1, + 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a, + 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d, + 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396, + 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0, + 0x0c7ac97b}, + {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669, + 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853, + 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062, + 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527, + 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad, + 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545, + 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27, + 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf, + 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45, + 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800, + 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031, + 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b, + 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26, + 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce, + 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d, + 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5, + 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130, + 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a, + 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b, + 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480, + 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a, + 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2, + 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e, + 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996, + 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c, + 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc, + 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd, + 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7, + 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232, + 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da, + 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439, + 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1, + 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da, + 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0, + 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1, + 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94, + 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e, + 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6, + 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2, + 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a, + 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0, + 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95, + 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4, + 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e, + 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395, + 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d, + 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e, + 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676, + 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83, + 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9, + 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888, + 0x5185cd09}}; + +#endif + +#endif + +#endif + +local const z_crc_t FAR x2n_table[] = { + 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, + 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467, + 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, + 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, + 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37, + 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, + 0xc40ba6d0, 0xc4e22c3c}; diff --git a/src/libs/3rdparty/zlib/src/deflate.c b/src/libs/3rdparty/zlib/src/deflate.c new file mode 100644 index 00000000000..012ea8148e8 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/deflate.c @@ -0,0 +1,2139 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://tools.ietf.org/html/rfc1951 + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func)(deflate_state *s, int flush); +/* Compression function. Returns the block state after the call. */ + +local block_state deflate_stored(deflate_state *s, int flush); +local block_state deflate_fast(deflate_state *s, int flush); +#ifndef FASTEST +local block_state deflate_slow(deflate_state *s, int flush); +#endif +local block_state deflate_rle(deflate_state *s, int flush); +local block_state deflate_huff(deflate_state *s, int flush); + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to UPDATE_HASH are made with consecutive input + * characters, so that a running hash key can be computed from the previous + * key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to INSERT_STRING are made with consecutive input + * characters and the first MIN_MATCH bytes of str are valid (except for + * the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + do { \ + s->head[s->hash_size - 1] = NIL; \ + zmemzero((Bytef *)s->head, \ + (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ + } while (0) + +/* =========================================================================== + * Slide the hash table when sliding the window down (could be avoided with 32 + * bit values at the expense of memory usage). We slide even when level == 0 to + * keep the hash table consistent if we switch back to level > 0 later. + */ +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) + __attribute__((no_sanitize("memory"))) +# endif +#endif +local void slide_hash(deflate_state *s) { + unsigned n, m; + Posf *p; + uInt wsize = s->w_size; + + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + } while (--n); + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) { + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + strm->next_in += len; + strm->total_in += len; + + return len; +} + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(deflate_state *s) { + unsigned n; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize + MAX_DIST(s)) { + + zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + if (s->insert > s->strstart) + s->insert = s->strstart; + slide_hash(s); + more += wsize; + } + if (s->strm->avail_in == 0) break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +/* ========================================================================= */ +int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, + int stream_size) { + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, int strategy, + const char *version, int stream_size) { + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + if (windowBits < -15) + return Z_STREAM_ERROR; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + s->status = INIT_STATE; /* to pass state test in deflateReset() */ + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = (uInt)windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = (uInt)memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + /* We overlay pending_buf and sym_buf. This works since the average size + * for length/distance pairs over any compressed block is assured to be 31 + * bits or less. + * + * Analysis: The longest fixed codes are a length code of 8 bits plus 5 + * extra bits, for lengths 131 to 257. The longest fixed distance codes are + * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest + * possible fixed-codes length/distance pair is then 31 bits total. + * + * sym_buf starts one-fourth of the way into pending_buf. So there are + * three bytes in sym_buf for every four bytes in pending_buf. Each symbol + * in sym_buf is three bytes -- two for the distance and one for the + * literal/length. As each symbol is consumed, the pointer to the next + * sym_buf value to read moves forward three bytes. From that symbol, up to + * 31 bits are written to pending_buf. The closest the written pending_buf + * bits gets to the next sym_buf symbol to read is just before the last + * code is written. At that time, 31*(n - 2) bits have been written, just + * after 24*(n - 2) bits have been consumed from sym_buf. sym_buf starts at + * 8*n bits into pending_buf. (Note that the symbol buffer fills when n - 1 + * symbols are written.) The closest the writing gets to what is unread is + * then n + 14 bits. Here n is lit_bufsize, which is 16384 by default, and + * can range from 128 to 32768. + * + * Therefore, at a minimum, there are 142 bits of space between what is + * written and what is read in the overlain buffers, so the symbols cannot + * be overwritten by the compressed data. That space is actually 139 bits, + * due to the three-bit fixed-code block header. + * + * That covers the case where either Z_FIXED is specified, forcing fixed + * codes, or when the use of fixed codes is chosen, because that choice + * results in a smaller compressed block than dynamic codes. That latter + * condition then assures that the above analysis also covers all dynamic + * blocks. A dynamic-code block will only be chosen to be emitted if it has + * fewer bits than a fixed-code block would for the same set of symbols. + * Therefore its average symbol length is assured to be less than 31. So + * the compressed data for a dynamic block also cannot overwrite the + * symbols from which it is being constructed. + */ + + s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS); + s->pending_buf_size = (ulg)s->lit_bufsize * 4; + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } +#ifdef LIT_MEM + s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); + s->l_buf = s->pending_buf + (s->lit_bufsize << 2); + s->sym_end = s->lit_bufsize - 1; +#else + s->sym_buf = s->pending_buf + s->lit_bufsize; + s->sym_end = (s->lit_bufsize - 1) * 3; +#endif + /* We avoid equality with lit_bufsize*3 because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= + * Check for a valid deflate stream state. Return 0 if ok, 1 if not. + */ +local int deflateStateCheck(z_streamp strm) { + deflate_state *s; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + s = strm->state; + if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && +#ifdef GZIP + s->status != GZIP_STATE && +#endif + s->status != EXTRA_STATE && + s->status != NAME_STATE && + s->status != COMMENT_STATE && + s->status != HCRC_STATE && + s->status != BUSY_STATE && + s->status != FINISH_STATE)) + return 1; + return 0; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary, + uInt dictLength) { + deflate_state *s; + uInt str, n; + int wrap; + unsigned avail; + z_const unsigned char *next; + + if (deflateStateCheck(strm) || dictionary == Z_NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = adler32(strm->adler, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (z_const Bytef *)dictionary; + fill_window(s); + while (s->lookahead >= MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (MIN_MATCH-1); + do { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + } while (--n); + s->strstart = str; + s->lookahead = MIN_MATCH-1; + fill_window(s); + } + s->strstart += s->lookahead; + s->block_start = (long)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + strm->next_in = next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary, + uInt *dictLength) { + deflate_state *s; + uInt len; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + len = s->strstart + s->lookahead; + if (len > s->w_size) + len = s->w_size; + if (dictionary != Z_NULL && len) + zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); + if (dictLength != Z_NULL) + *dictLength = len; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateResetKeep(z_streamp strm) { + deflate_state *s; + + if (deflateStateCheck(strm)) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = +#ifdef GZIP + s->wrap == 2 ? GZIP_STATE : +#endif + INIT_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = -2; + + _tr_init(s); + + return Z_OK; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init(deflate_state *s) { + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset(z_streamp strm) { + int ret; + + ret = deflateResetKeep(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) { + if (deflateStateCheck(strm) || strm->state->wrap != 2) + return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) { + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + if (pending != Z_NULL) + *pending = strm->state->pending; + if (bits != Z_NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { + deflate_state *s; + int put; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; +#ifdef LIT_MEM + if (bits < 0 || bits > 16 || + (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#else + if (bits < 0 || bits > 16 || + s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#endif + do { + put = Buf_size - s->bi_valid; + if (put > bits) + put = bits; + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); + s->bi_valid += put; + _tr_flush_bits(s); + value >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(z_streamp strm, int level, int strategy) { + deflate_state *s; + compress_func func; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + s->last_flush != -2) { + /* Flush the last buffer: */ + int err = deflate(strm, Z_BLOCK); + if (err == Z_STREAM_ERROR) + return err; + if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead) + return Z_BUF_ERROR; + } + if (s->level != level) { + if (s->level == 0 && s->matches != 0) { + if (s->matches == 1) + slide_hash(s); + else + CLEAR_HASH(s); + s->matches = 0; + } + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, + int nice_length, int max_chain) { + deflate_state *s; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = (uInt)good_length; + s->max_lazy_match = (uInt)max_lazy; + s->nice_match = nice_length; + s->max_chain_length = (uInt)max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns a + * close to exact, as well as small, upper bound on the compressed size. This + * is an expansion of ~0.03%, plus a small constant. + * + * For any setting other than those defaults for windowBits and memLevel, one + * of two worst case bounds is returned. This is at most an expansion of ~4% or + * ~13%, plus a small constant. + * + * Both the 0.03% and 4% derive from the overhead of stored blocks. The first + * one is for stored blocks of 16383 bytes (memLevel == 8), whereas the second + * is for stored blocks of 127 bytes (the worst case memLevel == 1). The + * expansion results from five bytes of header for each stored block. + * + * The larger expansion of 13% results from a window size less than or equal to + * the symbols buffer size (windowBits <= memLevel + 7). In that case some of + * the data being compressed may have slid out of the sliding window, impeding + * a stored block from being emitted. Then the only choice is a fixed or + * dynamic block, where a fixed block limits the maximum expansion to 9 bits + * per 8-bit byte, plus 10 bits for every block. The smallest block size for + * which this can occur is 255 (memLevel == 2). + * + * Shifts are used to approximate divisions, for speed. + */ +uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { + deflate_state *s; + uLong fixedlen, storelen, wraplen; + + /* upper bound for fixed blocks with 9-bit literals and length 255 + (memLevel == 2, which is the lowest that may not use stored blocks) -- + ~13% overhead plus a small constant */ + fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + + (sourceLen >> 9) + 4; + + /* upper bound for stored blocks with length 127 (memLevel == 1) -- + ~4% overhead plus a small constant */ + storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + + (sourceLen >> 11) + 7; + + /* if can't get parameters, return larger bound plus a zlib wrapper */ + if (deflateStateCheck(strm)) + return (fixedlen > storelen ? fixedlen : storelen) + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; +#ifdef GZIP + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + Bytef *str; + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; +#endif + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return one of the conservative bounds */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + + wraplen; + + /* default settings: return tight bound for that case -- ~0.03% overhead + plus a small constant */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB(deflate_state *s, uInt b) { + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output, except for + * some deflate_stored() output, goes through this function so some + * applications may wish to modify it to avoid allocating a large + * strm->next_out buffer and copying into it. (See also read_buf()). + */ +local void flush_pending(z_streamp strm) { + unsigned len; + deflate_state *s = strm->state; + + _tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; + } +} + +/* =========================================================================== + * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. + */ +#define HCRC_UPDATE(beg) \ + do { \ + if (s->gzhead->hcrc && s->pending > (beg)) \ + strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ + s->pending - (beg)); \ + } while (0) + +/* ========================================================================= */ +int ZEXPORT deflate(z_streamp strm, int flush) { + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->avail_in != 0 && strm->next_in == Z_NULL) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + old_flush = s->last_flush; + s->last_flush = flush; + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Write the header */ + if (s->status == INIT_STATE && s->wrap == 0) + s->status = BUSY_STATE; + if (s->status == INIT_STATE) { + /* zlib header */ + uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#ifdef GZIP + if (s->status == GZIP_STATE) { + /* gzip header */ + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; + while (s->pending + left > s->pending_buf_size) { + uInt copy = s->pending_buf_size - s->pending; + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, copy); + s->pending = s->pending_buf_size; + HCRC_UPDATE(beg); + s->gzindex += copy; + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + left -= copy; + } + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, left); + s->pending += left; + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + int val; + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + int val; + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + } + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) { + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + } + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#endif + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->level == 0 ? deflate_stored(s, flush) : + s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd(z_streamp strm) { + int status; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + + status = strm->state->status; + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { +#ifdef MAXSEG_64K + (void)dest; + (void)source; + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + + + if (deflateStateCheck(source) || dest == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); +#ifdef LIT_MEM + ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); + ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); +#else + ds->sym_buf = ds->pending_buf + ds->lit_bufsize; +#endif + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +local uInt longest_match(deflate_state *s, IPos cur_match) { + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = (int)s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan + best_len - 1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len - 1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match + best_len - 1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart + 3, + 5, up to strstart + 257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart + 257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan += 2) == *(ushf*)(match += 2) && + *(ushf*)(scan += 2) == *(ushf*)(match += 2) && + *(ushf*)(scan += 2) == *(ushf*)(match += 2) && + *(ushf*)(scan += 2) == *(ushf*)(match += 2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window + strstart + 257 */ + Assert(scan <= s->window + (unsigned)(s->window_size - 1), + "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend - scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len - 1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len - 1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart + 258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window + (unsigned)(s->window_size - 1), + "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan + best_len - 1); +#else + scan_end1 = scan[best_len - 1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(deflate_state *s, IPos cur_match) { + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len - 1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart + 258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef ZLIB_DEBUG + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(deflate_state *s, IPos start, IPos match, int length) { + /* check that the match is indeed a match */ + Bytef *back = s->window + (int)match, *here = s->window + start; + IPos len = length; + if (match == (IPos)-1) { + /* match starts one byte before the current window -- just compare the + subsequent length-1 bytes */ + back++; + here++; + len--; + } + if (zmemcmp(back, here, len) != EQUAL) { + fprintf(stderr, " start %u, match %d, length %d\n", + start, (int)match, length); + do { + fprintf(stderr, "(%02x %02x)", *back++, *here++); + } while (--len != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start - match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* ZLIB_DEBUG */ + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* Maximum stored block length in deflate format (not including header). */ +#define MAX_STORED 65535 + +/* Minimum of a and b. */ +#define MIN(a, b) ((a) > (b) ? (b) : (a)) + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * + * In case deflateParams() is used to later switch to a non-zero compression + * level, s->matches (otherwise unused when storing) keeps track of the number + * of hash table slides to perform. If s->matches is 1, then one hash table + * slide will be done when switching. If s->matches is 2, the maximum value + * allowed here, then the hash table will be cleared, since two or more slides + * is the same as a clear. + * + * deflate_stored() is written to minimize the number of times an input byte is + * copied. It is most efficient with large input and output buffers, which + * maximizes the opportunities to have a single copy from next_in to next_out. + */ +local block_state deflate_stored(deflate_state *s, int flush) { + /* Smallest worthy block size when not flushing or finishing. By default + * this is 32K. This can be as small as 507 bytes for memLevel == 1. For + * large input and output buffers, the stored block size will be larger. + */ + unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); + + /* Copy as many min_block or larger stored blocks directly to next_out as + * possible. If flushing, copy the remaining available input to next_out as + * stored blocks, if there is enough space. + */ + unsigned len, left, have, last = 0; + unsigned used = s->strm->avail_in; + do { + /* Set len to the maximum size block that we can copy directly with the + * available input data and output space. Set left to how much of that + * would be copied from what's left in the window. + */ + len = MAX_STORED; /* maximum deflate stored block length */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + if (s->strm->avail_out < have) /* need room for header */ + break; + /* maximum stored block length that will fit in avail_out: */ + have = s->strm->avail_out - have; + left = s->strstart - s->block_start; /* bytes left in window */ + if (len > (ulg)left + s->strm->avail_in) + len = left + s->strm->avail_in; /* limit len to the input */ + if (len > have) + len = have; /* limit len to the output */ + + /* If the stored block would be less than min_block in length, or if + * unable to copy all of the available input when flushing, then try + * copying to the window and the pending buffer instead. Also don't + * write an empty block when flushing -- deflate() does that. + */ + if (len < min_block && ((len == 0 && flush != Z_FINISH) || + flush == Z_NO_FLUSH || + len != left + s->strm->avail_in)) + break; + + /* Make a dummy stored block in pending to get the header bytes, + * including any pending bits. This also updates the debugging counts. + */ + last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; + _tr_stored_block(s, (char *)0, 0L, last); + + /* Replace the lengths in the dummy stored block with len. */ + s->pending_buf[s->pending - 4] = len; + s->pending_buf[s->pending - 3] = len >> 8; + s->pending_buf[s->pending - 2] = ~len; + s->pending_buf[s->pending - 1] = ~len >> 8; + + /* Write the stored block header bytes. */ + flush_pending(s->strm); + +#ifdef ZLIB_DEBUG + /* Update debugging counts for the data about to be copied. */ + s->compressed_len += len << 3; + s->bits_sent += len << 3; +#endif + + /* Copy uncompressed bytes from the window to next_out. */ + if (left) { + if (left > len) + left = len; + zmemcpy(s->strm->next_out, s->window + s->block_start, left); + s->strm->next_out += left; + s->strm->avail_out -= left; + s->strm->total_out += left; + s->block_start += left; + len -= left; + } + + /* Copy uncompressed bytes directly from next_in to next_out, updating + * the check value. + */ + if (len) { + read_buf(s->strm, s->strm->next_out, len); + s->strm->next_out += len; + s->strm->avail_out -= len; + s->strm->total_out += len; + } + } while (last == 0); + + /* Update the sliding window with the last s->w_size bytes of the copied + * data, or append all of the copied data to the existing window if less + * than s->w_size bytes were copied. Also update the number of bytes to + * insert in the hash tables, in the event that deflateParams() switches to + * a non-zero compression level. + */ + used -= s->strm->avail_in; /* number of input bytes directly copied */ + if (used) { + /* If any input was used, then no unused input remains in the window, + * therefore s->block_start == s->strstart. + */ + if (used >= s->w_size) { /* supplant the previous history */ + s->matches = 2; /* clear hash */ + zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); + s->strstart = s->w_size; + s->insert = s->strstart; + } + else { + if (s->window_size - s->strstart <= used) { + /* Slide the window down. */ + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + if (s->insert > s->strstart) + s->insert = s->strstart; + } + zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); + s->strstart += used; + s->insert += MIN(used, s->w_size - s->insert); + } + s->block_start = s->strstart; + } + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* If the last block was written to next_out, then done. */ + if (last) + return finish_done; + + /* If flushing and all input has been consumed, then done. */ + if (flush != Z_NO_FLUSH && flush != Z_FINISH && + s->strm->avail_in == 0 && (long)s->strstart == s->block_start) + return block_done; + + /* Fill the window with any remaining input. */ + have = s->window_size - s->strstart; + if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { + /* Slide the window down. */ + s->block_start -= s->w_size; + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + have += s->w_size; /* more space now */ + if (s->insert > s->strstart) + s->insert = s->strstart; + } + if (have > s->strm->avail_in) + have = s->strm->avail_in; + if (have) { + read_buf(s->strm, s->window + s->strstart, have); + s->strstart += have; + s->insert += MIN(have, s->w_size - s->insert); + } + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* There was not enough avail_out to write a complete worthy or flushed + * stored block to next_out. Write a stored block to pending instead, if we + * have enough input for a worthy block, or if flushing and there is enough + * room for the remaining input as a stored block in the pending buffer. + */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + /* maximum stored block length that will fit in pending: */ + have = MIN(s->pending_buf_size - have, MAX_STORED); + min_block = MIN(have, s->w_size); + left = s->strstart - s->block_start; + if (left >= min_block || + ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && + s->strm->avail_in == 0 && left <= have)) { + len = MIN(left, have); + last = flush == Z_FINISH && s->strm->avail_in == 0 && + len == left ? 1 : 0; + _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); + s->block_start += len; + flush_pending(s->strm); + } + + /* We've done all we can with the available input and output. */ + return last ? finish_started : need_more; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(deflate_state *s, int flush) { + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart + 2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit(s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(deflate_state *s, int flush) { + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart + 2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart - 1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart - 1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart - 1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length - 1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart - 1])); + _tr_tally_lit(s, s->window[s->strstart - 1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart - 1])); + _tr_tally_lit(s, s->window[s->strstart - 1], bflush); + s->match_available = 0; + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(deflate_state *s, int flush) { + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s->lookahead <= MAX_MATCH) { + fill_window(s); + if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (uInt)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + Assert(scan <= s->window + (uInt)(s->window_size - 1), + "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit(s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(deflate_state *s, int flush) { + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit(s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/src/libs/3rdparty/zlib/src/deflate.h b/src/libs/3rdparty/zlib/src/deflate.h new file mode 100644 index 00000000000..300c6ada62b --- /dev/null +++ b/src/libs/3rdparty/zlib/src/deflate.h @@ -0,0 +1,377 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2024 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at + the cost of a larger memory footprint */ +/* #define LIT_MEM */ + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define Buf_size 16 +/* size of bit buffer in bi_buf */ + +#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ +#ifdef GZIP +# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ +#endif +#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ +#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ +#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ +#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ +#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ +#define FINISH_STATE 666 /* stream complete */ +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + const static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + ulg pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + ulg gzindex; /* where in extra, name, or comment */ + Byte method; /* can only be DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + +#ifdef LIT_MEM +# define LIT_BUFS 5 + ushf *d_buf; /* buffer for distances */ + uchf *l_buf; /* buffer for literals/lengths */ +#else +# define LIT_BUFS 4 + uchf *sym_buf; /* buffer for distances and literals/lengths */ +#endif + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt sym_next; /* running index in symbol buffer */ + uInt sym_end; /* symbol table full when sym_next reaches this */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + uInt insert; /* bytes at end of window left to insert */ + +#ifdef ZLIB_DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init(deflate_state *s); +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc); +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, + ulg stored_len, int last); +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s); +void ZLIB_INTERNAL _tr_align(deflate_state *s); +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, + ulg stored_len, int last); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef ZLIB_DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +#ifdef LIT_MEM +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->sym_next] = 0; \ + s->l_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->d_buf[s->sym_next] = dist; \ + s->l_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#else +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->sym_buf[s->sym_next++] = 0; \ + s->sym_buf[s->sym_next++] = 0; \ + s->sym_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->sym_buf[s->sym_next++] = (uch)dist; \ + s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \ + s->sym_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#endif +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/src/libs/3rdparty/zlib/src/gzclose.c b/src/libs/3rdparty/zlib/src/gzclose.c new file mode 100644 index 00000000000..48d6a86f04b --- /dev/null +++ b/src/libs/3rdparty/zlib/src/gzclose.c @@ -0,0 +1,23 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(gzFile file) { +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/src/libs/3rdparty/zlib/src/gzguts.h b/src/libs/3rdparty/zlib/src/gzguts.h new file mode 100644 index 00000000000..9d788f78534 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/gzguts.h @@ -0,0 +1,218 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004-2024 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef QT_VISIBILITY_AVAILABLE +#define HAVE_HIDDEN +#endif + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# undef _FILE_OFFSET_BITS +# undef _TIME_BITS +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include + +#ifdef _WIN32 +# include +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include +#endif + +#if defined(_WIN32) +# define WIDECHAR +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +/* unlike snprintf (which is required in C99), _snprintf does not guarantee + null termination of the result -- however this is only used in gzlib.c where + the result is assured to fit in the space provided */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#ifndef local +# define local static +#endif +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc(uInt size); + extern void free(voidpf ptr); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer (double-sized when writing) */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + int reset; /* true if a reset is pending after a Z_FINISH */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error(gz_statep, int, const char *); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror(DWORD error); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +unsigned ZLIB_INTERNAL gz_intmax(void); +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) diff --git a/src/libs/3rdparty/zlib/src/gzlib.c b/src/libs/3rdparty/zlib/src/gzlib.c new file mode 100644 index 00000000000..983153cc8e4 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/gzlib.c @@ -0,0 +1,582 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004-2024 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_WIN32) && !defined(__BORLANDC__) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror(DWORD error) { + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(gz_statep state) { + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + else /* for writing ... */ + state->reset = 0; /* no deflateReset pending */ + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(const void *path, int fd, const char *mode) { + gz_statep state; + z_size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = (gz_statep)malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef WIDECHAR + if (fd == -2) { + len = wcstombs(NULL, path, 0); + if (len == (z_size_t)-1) + len = 0; + } + else +#endif + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); + if (state->path == NULL) { + free(state); + return NULL; + } +#ifdef WIDECHAR + if (fd == -2) + if (len) + wcstombs(state->path, path, len + 1); + else + *(state->path) = 0; + else +#endif +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(state->path, len + 1, "%s", (const char *)path); +#else + strcpy(state->path, path); +#endif + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#ifdef WIDECHAR + fd == -2 ? _wopen(path, oflag, 0666) : +#endif + open((const char *)path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) { + LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ + state->mode = GZ_WRITE; /* simplify later checks */ + } + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(const char *path, const char *mode) { + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(const char *path, const char *mode) { + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(int fd, const char *mode) { + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); +#else + sprintf(path, "", fd); /* for debugging */ +#endif + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef WIDECHAR +gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) { + return gz_open(path, -2, mode); +} +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(gzFile file, unsigned size) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if ((size << 1) < size) + return -1; /* need to be able to double it */ + if (size < 8) + size = 8; /* needed to behave well with flushing */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(gzFile file) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) { + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(gzFile file) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(gzFile file) { + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(gzFile file) { + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(gzFile file) { + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(gzFile file) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(gzFile file, int *errnum) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->err == Z_MEM_ERROR ? "out of memory" : + (state->msg == NULL ? "" : state->msg); +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(gzFile file) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) + return; + + /* construct error message with path */ + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + NULL) { + state->err = Z_MEM_ERROR; + return; + } +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); +#else + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); +#endif +} + +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax(void) { +#ifdef INT_MAX + return INT_MAX; +#else + unsigned p = 1, q; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +#endif +} diff --git a/src/libs/3rdparty/zlib/src/gzread.c b/src/libs/3rdparty/zlib/src/gzread.c new file mode 100644 index 00000000000..4168cbc8875 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/gzread.c @@ -0,0 +1,602 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(gz_statep state, unsigned char *buf, unsigned len, + unsigned *have) { + int ret; + unsigned get, max = ((unsigned)-1 >> 2) + 1; + + *have = 0; + do { + get = len - *have; + if (get > max) + get = max; + ret = read(state->fd, buf + *have, get); + if (ret <= 0) + break; + *have += (unsigned)ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +local int gz_avail(gz_statep state) { + unsigned got; + z_streamp strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(gz_statep state) { + z_streamp strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = (unsigned char *)malloc(state->want); + state->out = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +local int gz_decomp(gz_statep state) { + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(gz_statep state) { + z_streamp strm = &(state->strm); + + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(gz_statep state, z_off64_t len) { + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* Read len bytes into buf from file, or less than len up to the end of the + input. Return the number of bytes read. If zero is returned, either the + end of file was reached, or there was an error. state->err must be + consulted in that case to determine which. */ +local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { + z_size_t got; + unsigned n; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return 0; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* set n to the maximum amount of len that fits in an unsigned int */ + n = (unsigned)-1; + if (n > len) + n = (unsigned)len; + + /* first just try copying data from the output buffer */ + if (state->x.have) { + if (state->x.have < n) + n = state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || n < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return 0; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, (unsigned char *)buf, n, &n) == -1) + return 0; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + state->strm.avail_out = n; + state->strm.next_out = (unsigned char *)buf; + if (gz_decomp(state) == -1) + return 0; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer */ + return got; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); + return -1; + } + + /* read len or fewer bytes to buf */ + len = (unsigned)gz_read(state, buf, len); + + /* check for an error */ + if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* return the number of bytes read (this is assured to fit in an int) */ + return (int)len; +} + +/* -- see zlib.h -- */ +z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) { + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (size && len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* read len or fewer bytes to buf, return the number of full items read */ + return len ? gz_read(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +#else +# undef gzgetc +#endif +int ZEXPORT gzgetc(gzFile file) { + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gz_read() */ + return gz_read(state, buf, 1) < 1 ? -1 : buf[0]; +} + +int ZEXPORT gzgetc_(gzFile file) { + return gzgetc(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(int c, gzFile file) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* in case this was just opened, set up the input buffer */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(gzFile file, char *buf, int len) { + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(gzFile file) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(gzFile file) { + int ret, err; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; +} diff --git a/src/libs/3rdparty/zlib/src/gzwrite.c b/src/libs/3rdparty/zlib/src/gzwrite.c new file mode 100644 index 00000000000..435b4621b53 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/gzwrite.c @@ -0,0 +1,631 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on a memory allocation failure, or 0 on + success. */ +local int gz_init(gz_statep state) { + int ret; + z_streamp strm = &(state->strm); + + /* allocate input buffer (double size for gzprintf) */ + state->in = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = (unsigned char *)malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + strm->next_in = NULL; + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file or if gz_init() + fails to allocate memory, otherwise 0. flush is assumed to be a valid + deflate() flush value. If flush is Z_FINISH, then the deflate() state is + reset to start a new gzip stream. If gz->direct is true, then simply write + to the output file without compressing, and ignore flush. */ +local int gz_comp(gz_statep state, int flush) { + int ret, writ; + unsigned have, put, max = ((unsigned)-1 >> 2) + 1; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + while (strm->avail_in) { + put = strm->avail_in > max ? max : strm->avail_in; + writ = write(state->fd, strm->next_in, put); + if (writ < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in -= (unsigned)writ; + strm->next_in += writ; + } + return 0; + } + + /* check for a pending reset */ + if (state->reset) { + /* don't start a new gzip member unless there is data to write */ + if (strm->avail_in == 0) + return 0; + deflateReset(strm); + state->reset = 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + while (strm->next_out > state->x.next) { + put = strm->next_out - state->x.next > (int)max ? max : + (unsigned)(strm->next_out - state->x.next); + writ = write(state->fd, state->x.next, put); + if (writ < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + state->x.next += writ; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = state->out; + } + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + state->reset = 1; + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on a write error or memory + allocation failure by gz_comp(), or 0 on success. */ +local int gz_zero(gz_statep state, z_off64_t len) { + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* Write len bytes from buf to file. Return the number of bytes written. If + the returned value is less than len, then there was an error. */ +local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { + z_size_t put = len; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + unsigned have, copy; + + if (state->strm.avail_in == 0) + state->strm.next_in = state->in; + have = (unsigned)((state->strm.next_in + state->strm.avail_in) - + state->in); + copy = state->size - have; + if (copy > len) + copy = (unsigned)len; + memcpy(state->in + have, buf, copy); + state->strm.avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + state->strm.next_in = (z_const Bytef *)buf; + do { + unsigned n = (unsigned)-1; + if (n > len) + n = (unsigned)len; + state->strm.avail_in = n; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + len -= n; + } while (len); + } + + /* input was all buffered or compressed */ + return put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* write len bytes from buf (the return value will fit in an int) */ + return (int)gz_write(state, buf, len); +} + +/* -- see zlib.h -- */ +z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems, + gzFile file) { + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (size && len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* write len bytes to buf, return the number of full items written */ + return len ? gz_write(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(gzFile file, int c) { + unsigned have; + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = (unsigned char)c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = (unsigned char)c; + if (gz_write(state, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(gzFile file, const char *s) { + z_size_t len, put; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* write string */ + len = strlen(s); + if ((int)len < 0 || (unsigned)len != len) { + gz_error(state, Z_STREAM_ERROR, "string length does not fit in int"); + return -1; + } + put = gz_write(state, s, len); + return put < len ? -1 : (int)len; +} + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { + int len; + unsigned left; + char *next; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return state->err; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); + next[state->size - 1] = 0; +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(next, format, va); + for (len = 0; len < state->size; len++) + if (next[len] == 0) break; +# else + len = vsprintf(next, format, va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(next, state->size, format, va); + len = strlen(next); +# else + len = vsnprintf(next, state->size, format, va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) + return 0; + + /* update buffer and position, compress first half if past that */ + strm->avail_in += (unsigned)len; + state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memmove(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return len; +} + +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { + va_list va; + int ret; + + va_start(va, format); + ret = gzvprintf(file, format, va); + va_end(va); + return ret; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, + int a4, int a5, int a6, int a7, int a8, int a9, int a10, + int a11, int a12, int a13, int a14, int a15, int a16, + int a17, int a18, int a19, int a20) { + unsigned len, left; + char *next; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return Z_STREAM_ERROR; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return state->error; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->error; + } + + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(strm->next_in + strm->avail_in); + next[state->size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, + a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (next[len] == 0) + break; +# else + len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, + a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(next); +# else + len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len == 0 || len >= state->size || next[state->size - 1] != 0) + return 0; + + /* update buffer and position, compress first half if past that */ + strm->avail_in += len; + state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memmove(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return (int)len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(gzFile file, int flush) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* compress remaining data with requested flush */ + (void)gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(gzFile file, int level, int strategy) { + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(gzFile file) { + int ret = Z_OK; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) { + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; +} diff --git a/src/libs/3rdparty/zlib/src/infback.c b/src/libs/3rdparty/zlib/src/infback.c new file mode 100644 index 00000000000..e7b25b307a3 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/infback.c @@ -0,0 +1,628 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, const char *version, + int stream_size) { + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = (uInt)windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + state->sane = 1; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(struct inflate_state FAR *state) { +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc) { + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + /* fallthrough */ + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly */ + ret = Z_STREAM_END; + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: + /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Write leftover output and return unused input */ + inf_leave: + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left) && + ret == Z_STREAM_END) + ret = Z_BUF_ERROR; + } + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(z_streamp strm) { + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/src/libs/3rdparty/zlib/src/inffast.c b/src/libs/3rdparty/zlib/src/inffast.c new file mode 100644 index 00000000000..9354676e786 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/inffast.c @@ -0,0 +1,320 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef ASMINF +# pragma message("Assembler code may have bugs -- use at your own risk") +#else + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { + struct inflate_state FAR *state; + z_const unsigned char FAR *in; /* local strm->next_in */ + z_const unsigned char FAR *last; /* have enough input while in < last */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code const *here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in; + last = in + (strm->avail_in - 5); + out = strm->next_out; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + here = lcode + (hold & lmask); + dolen: + op = (unsigned)(here->bits); + hold >>= op; + bits -= op; + op = (unsigned)(here->op); + if (op == 0) { /* literal */ + Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here->val)); + *out++ = (unsigned char)(here->val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here->val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + here = dcode + (hold & dmask); + dodist: + op = (unsigned)(here->bits); + hold >>= op; + bits -= op; + op = (unsigned)(here->op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here->val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + *out++ = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + *out++ = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + *out++ = *from++; + } while (--len); + continue; + } +#endif + } + from = window; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = window; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; + len -= 3; + } + if (len) { + *out++ = *from++; + if (len > 1) + *out++ = *from++; + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; + len -= 3; + } while (len > 2); + if (len) { + *out++ = *from++; + if (len > 1) + *out++ = *from++; + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode + here->val + (hold & ((1U << op) - 1)); + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode + here->val + (hold & ((1U << op) - 1)); + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in; + strm->next_out = out; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/src/libs/3rdparty/zlib/src/inffast.h b/src/libs/3rdparty/zlib/src/inffast.h new file mode 100644 index 00000000000..49c6d156c5c --- /dev/null +++ b/src/libs/3rdparty/zlib/src/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start); diff --git a/src/libs/3rdparty/zlib/src/inffixed.h b/src/libs/3rdparty/zlib/src/inffixed.h new file mode 100644 index 00000000000..d6283277694 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/src/libs/3rdparty/zlib/src/inflate.c b/src/libs/3rdparty/zlib/src/inflate.c new file mode 100644 index 00000000000..94ecff015a9 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/inflate.c @@ -0,0 +1,1526 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +local int inflateStateCheck(z_streamp strm) { + struct inflate_state FAR *state; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + state = (struct inflate_state FAR *)strm->state; + if (state == Z_NULL || state->strm != strm || + state->mode < HEAD || state->mode > SYNC) + return 1; + return 0; +} + +int ZEXPORT inflateResetKeep(z_streamp strm) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->flags = -1; + state->dmax = 32768U; + state->head = Z_NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset(z_streamp strm) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); +} + +int ZEXPORT inflateReset2(z_streamp strm, int windowBits) { + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + if (windowBits < -15) + return Z_STREAM_ERROR; + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 5; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size) { + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->strm = strm; + state->window = Z_NULL; + state->mode = HEAD; /* to pass state test in inflateReset2() */ + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(z_streamp strm, const char *version, + int stream_size) { + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (bits == 0) + return Z_OK; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += (unsigned)value << state->bits; + state->bits += (uInt)bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(struct inflate_state FAR *state) { +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed(void) +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) { + struct inflate_state FAR *state; + unsigned dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state->wsize) { + zmemcpy(state->window, end - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, end - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, end - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE_CHECK(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE_CHECK(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(z_streamp strm, int flush) { + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (inflateStateCheck(strm) || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + if (state->wbits == 0) + state->wbits = 15; + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + if (len > 15 || len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + state->flags = 0; /* indicate zlib header */ + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + /* fallthrough */ + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + /* fallthrough */ + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + /* fallthrough */ + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + /* fallthrough */ + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL && + (len = state->head->extra_len - state->length) < + state->head->extra_max) { + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + /* fallthrough */ + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = (Bytef)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + /* fallthrough */ + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = (Bytef)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + /* fallthrough */ + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if ((state->wrap & 4) && hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = ZSWAP32(hold); + INITBITS(); + state->mode = DICT; + /* fallthrough */ + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + /* fallthrough */ + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + /* fallthrough */ + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + /* fallthrough */ + case COPY_: + state->mode = COPY; + /* fallthrough */ + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + /* fallthrough */ + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + /* fallthrough */ + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (const code FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + /* fallthrough */ + case LEN_: + state->mode = LEN; + /* fallthrough */ + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + /* fallthrough */ + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + /* fallthrough */ + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + /* fallthrough */ + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + /* fallthrough */ + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if ((state->wrap & 4) && out) + strm->adler = state->check = + UPDATE_CHECK(state->check, put - out, out); + out = left; + if ((state->wrap & 4) && ( +#ifdef GUNZIP + state->flags ? hold : +#endif + ZSWAP32(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + /* fallthrough */ + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + /* fallthrough */ + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + /* fallthrough */ + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if ((state->wrap & 4) && out) + strm->adler = state->check = + UPDATE_CHECK(state->check, strm->next_out - out, out); + strm->data_type = (int)state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(z_streamp strm) { + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, + uInt *dictLength) { + struct inflate_state FAR *state; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* copy dictionary */ + if (state->whave && dictionary != Z_NULL) { + zmemcpy(dictionary, state->window + state->wnext, + state->whave - state->wnext); + zmemcpy(dictionary + state->whave - state->wnext, + state->window, state->wnext); + } + if (dictLength != Z_NULL) + *dictLength = state->whave; + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, + uInt dictLength) { + struct inflate_state FAR *state; + unsigned long dictid; + int ret; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary identifier */ + if (state->mode == DICT) { + dictid = adler32(0L, Z_NULL, 0); + dictid = adler32(dictid, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary + dictLength, dictLength); + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) { + struct inflate_state FAR *state; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, + unsigned len) { + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(z_streamp strm) { + unsigned len; /* number of bytes to look at or looked at */ + int flags; /* temporary to save header status */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold >>= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + if (state->flags == -1) + state->wrap = 0; /* if no header yet, treat as raw */ + else + state->wrap &= ~4; /* no point in computing a check value now */ + flags = state->flags; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->flags = flags; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(z_streamp strm) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (inflateStateCheck(source) || dest == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + copy->strm = dest; + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(z_streamp strm, int subvert) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + state->sane = !subvert; + return Z_OK; +#else + (void)subvert; + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +int ZEXPORT inflateValidate(z_streamp strm, int check) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (check && state->wrap) + state->wrap |= 4; + else + state->wrap &= ~4; + return Z_OK; +} + +long ZEXPORT inflateMark(z_streamp strm) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) + return -(1L << 16); + state = (struct inflate_state FAR *)strm->state; + return (long)(((unsigned long)((long)state->back)) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} + +unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) { + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) return (unsigned long)-1; + state = (struct inflate_state FAR *)strm->state; + return (unsigned long)(state->next - state->codes); +} diff --git a/src/libs/3rdparty/zlib/src/inflate.h b/src/libs/3rdparty/zlib/src/inflate.h new file mode 100644 index 00000000000..f127b6b1fa5 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/inflate.h @@ -0,0 +1,126 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD = 16180, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* State maintained between inflate() calls -- approximately 7K bytes, not + including the allocated sliding window, which is up to 32K bytes. */ +struct inflate_state { + z_streamp strm; /* pointer back to this zlib stream */ + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip, + bit 2 true to validate check value */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags, 0 if zlib, or + -1 if raw or no header yet */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/src/libs/3rdparty/zlib/src/inftrees.c b/src/libs/3rdparty/zlib/src/inftrees.c new file mode 100644 index 00000000000..98cfe164458 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/inftrees.c @@ -0,0 +1,299 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2024 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work) { + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + unsigned match; /* use base and extra for symbol >= match */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + match = 20; + break; + case LENS: + base = lbase; + extra = lext; + match = 257; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + match = 0; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if (work[sym] + 1U < match) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if (work[sym] >= match) { + here.op = (unsigned char)(extra[work[sym] - match]); + here.val = base[work[sym] - match]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff != 0) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/src/libs/3rdparty/zlib/src/inftrees.h b/src/libs/3rdparty/zlib/src/inftrees.h new file mode 100644 index 00000000000..396f74b5da7 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/inftrees.h @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns 852, and "enough 30 6 15" for distance codes returns 592. The + initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work); diff --git a/src/libs/3rdparty/zlib/src/trees.c b/src/libs/3rdparty/zlib/src/trees.c new file mode 100644 index 00000000000..6a523ef34e3 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/trees.c @@ -0,0 +1,1117 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2024 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef ZLIB_DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +#ifdef NO_INIT_GLOBAL_POINTERS +# define TCONST +#else +# define TCONST const +#endif + +local TCONST static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local TCONST static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local TCONST static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(unsigned code, int len) { + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(deflate_state *s) { + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(deflate_state *s) { + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->bits_sent = (s->bits_sent + 7) & ~7; +#endif +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) { + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + unsigned code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits - 1]) << 1; + next_code[bits] = (ush)code; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, + "inconsistent bit counts"); + Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) continue; + /* Now reverse the bits */ + tree[n].Code = (ush)bi_reverse(next_code[len]++, len); + + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); + } +} + +#ifdef GEN_TREES_H +local void gen_trees_header(void); +#endif + +#ifndef ZLIB_DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* !ZLIB_DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef ZLIB_DEBUG +local void send_bits(deflate_state *s, int value, int length) { + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16 - bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !ZLIB_DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = (int)value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* ZLIB_DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init(void) { +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1 << extra_lbits[code]); n++) { + _length_code[length++] = (uch)code; + } + } + Assert (length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + _length_code[length - 1] = (uch)code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1 << extra_dbits[code]); n++) { + _dist_code[dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256 + dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Generate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef ZLIB_DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width) - 1 ? ",\n" : ", ")) + +void gen_trees_header(void) { + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(deflate_state *s) { + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->sym_next = s->matches = 0; +} + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(deflate_state *s) { + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(deflate_state *s, ct_data *tree, int k) { + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(deflate_state *s, tree_desc *desc) { + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n - base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (unsigned)(bits + xbits); + if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); + } + if (overflow == 0) return; + + Tracev((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length - 1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits + 1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +#ifdef DUMP_BL_TREE +# include +#endif + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +local void build_tree(deflate_state *s, tree_desc *desc) { + ct_data *tree = desc->dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n + 1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2 + 1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree(deflate_state *s, ct_data *tree, int max_code) { + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code + 1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n + 1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree(deflate_state *s, ct_data *tree, int max_code) { + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code + 1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n + 1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count - 3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count - 3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count - 11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(deflate_state *s) { + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except the + * lengths of the bit lengths codes and the 5 + 5 + 4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(deflate_state *s, int lcodes, int dcodes, + int blcodes) { + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes - 1, 5); + send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, + ulg stored_len, int last) { + send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */ + bi_windup(s); /* align on byte boundary */ + put_short(s, (ush)stored_len); + put_short(s, (ush)~stored_len); + if (stored_len) + zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); + s->pending += stored_len; +#ifdef ZLIB_DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; + s->bits_sent += 2*16; + s->bits_sent += stored_len << 3; +#endif +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) { + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void ZLIB_INTERNAL _tr_align(deflate_state *s) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef ZLIB_DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(deflate_state *s, const ct_data *ltree, + const ct_data *dtree) { + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned sx = 0; /* running index in symbol buffers */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->sym_next != 0) do { +#ifdef LIT_MEM + dist = s->d_buf[sx]; + lc = s->l_buf[sx++]; +#else + dist = s->sym_buf[sx++] & 0xff; + dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; + lc = s->sym_buf[sx++]; +#endif + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code + LITERALS + 1, ltree); /* send length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= (unsigned)base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check for no overlay of pending_buf on needed symbols */ +#ifdef LIT_MEM + Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow"); +#else + Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); +#endif + + } while (sx < s->sym_next); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "block list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(deflate_state *s) { + /* block_mask is the bit mask of block-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long block_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("block-listed") bytes. */ + for (n = 0; n <= 31; n++, block_mask >>= 1) + if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("allow-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "block-listed" or "allow-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and write out the encoded block. + */ +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, + ulg stored_len, int last) { + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len + 3 + 7) >> 3; + static_lenb = (s->static_len + 3 + 7) >> 3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->sym_next / 3)); + +#ifndef FORCE_STATIC + if (static_lenb <= opt_lenb || s->strategy == Z_FIXED) +#endif + opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len + 4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + + } else if (static_lenb == opt_lenb) { + send_bits(s, (STATIC_TREES<<1) + last, 3); + compress_block(s, (const ct_data *)static_ltree, + (const ct_data *)static_dtree); +#ifdef ZLIB_DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1) + last, 3); + send_all_trees(s, s->l_desc.max_code + 1, s->d_desc.max_code + 1, + max_blindex + 1); + compress_block(s, (const ct_data *)s->dyn_ltree, + (const ct_data *)s->dyn_dtree); +#ifdef ZLIB_DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef ZLIB_DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3, + s->compressed_len - 7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { +#ifdef LIT_MEM + s->d_buf[s->sym_next] = (ush)dist; + s->l_buf[s->sym_next++] = (uch)lc; +#else + s->sym_buf[s->sym_next++] = (uch)dist; + s->sym_buf[s->sym_next++] = (uch)(dist >> 8); + s->sym_buf[s->sym_next++] = (uch)lc; +#endif + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + return (s->sym_next == s->sym_end); +} diff --git a/src/libs/3rdparty/zlib/src/trees.h b/src/libs/3rdparty/zlib/src/trees.h new file mode 100644 index 00000000000..d35639d82a2 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/src/libs/3rdparty/zlib/src/uncompr.c b/src/libs/3rdparty/zlib/src/uncompr.c new file mode 100644 index 00000000000..5e256663b45 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/uncompr.c @@ -0,0 +1,85 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. *sourceLen is + the byte length of the source buffer. Upon entry, *destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, + *destLen is the size of the decompressed data and *sourceLen is the number + of source bytes consumed. Upon return, source + *sourceLen points to the + first unused input byte. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, or + Z_DATA_ERROR if the input data was corrupted, including if the input data is + an incomplete zlib stream. +*/ +int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong *sourceLen) { + z_stream stream; + int err; + const uInt max = (uInt)-1; + uLong len, left; + Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ + + len = *sourceLen; + if (*destLen) { + left = *destLen; + *destLen = 0; + } + else { + left = 1; + dest = buf; + } + + stream.next_in = (z_const Bytef *)source; + stream.avail_in = 0; + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + stream.next_out = dest; + stream.avail_out = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (uLong)max ? max : (uInt)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = len > (uLong)max ? max : (uInt)len; + len -= stream.avail_in; + } + err = inflate(&stream, Z_NO_FLUSH); + } while (err == Z_OK); + + *sourceLen -= len + stream.avail_in; + if (dest != buf) + *destLen = stream.total_out; + else if (stream.total_out && err == Z_BUF_ERROR) + left = 1; + + inflateEnd(&stream); + return err == Z_STREAM_END ? Z_OK : + err == Z_NEED_DICT ? Z_DATA_ERROR : + err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : + err; +} + +int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen) { + return uncompress2(dest, destLen, source, &sourceLen); +} diff --git a/src/libs/3rdparty/zlib/src/zconf.h b/src/libs/3rdparty/zlib/src/zconf.h new file mode 100644 index 00000000000..4e14507a22d --- /dev/null +++ b/src/libs/3rdparty/zlib/src/zconf.h @@ -0,0 +1,547 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* Since Qt Core must export these symbols, define Z_PREFIX to avoid clashes system zlib */ +#define Z_PREFIX + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols and init macros */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# define adler32_z z_adler32_z +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define crc32_combine_gen z_crc32_combine_gen +# define crc32_combine_gen64 z_crc32_combine_gen64 +# define crc32_combine_op z_crc32_combine_op +# define crc32_z z_crc32_z +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateGetDictionary z_deflateGetDictionary +# define deflateInit z_deflateInit +# define deflateInit2 z_deflateInit2 +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzfread z_gzfread +# define gzfwrite z_gzfwrite +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzvprintf z_gzvprintf +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit z_inflateBackInit +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCodesUsed z_inflateCodesUsed +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetDictionary z_inflateGetDictionary +# define inflateGetHeader z_inflateGetHeader +# define inflateInit z_inflateInit +# define inflateInit2 z_inflateInit2 +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateResetKeep z_inflateResetKeep +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateValidate z_inflateValidate +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# define uncompress2 z_uncompress2 +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion +# define z_errmsg z_z_errmsg + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +#ifdef Z_SOLO +# ifdef _WIN64 + typedef unsigned long long z_size_t; +# else + typedef unsigned long z_size_t; +# endif +#else +# define z_longlong long long +# if defined(NO_SIZE_T) + typedef unsigned NO_SIZE_T z_size_t; +# elif defined(STDC) +# include + typedef size_t z_size_t; +# else + typedef unsigned long z_size_t; +# endif +# undef z_longlong +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#if defined(HAVE_UNISTD_H) || !defined(WIN32) +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#ifndef Z_HAVE_UNISTD_H +# ifdef __WATCOMC__ +# define Z_HAVE_UNISTD_H +# endif +#endif +#ifndef Z_HAVE_UNISTD_H +# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) +# define Z_HAVE_UNISTD_H +# endif +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/src/libs/3rdparty/zlib/src/zlib.h b/src/libs/3rdparty/zlib/src/zlib.h new file mode 100644 index 00000000000..7e66e998753 --- /dev/null +++ b/src/libs/3rdparty/zlib/src/zlib.h @@ -0,0 +1,1938 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.3.1, January 22nd, 2024 + + Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.3.1 (Qt)" +#define ZLIB_VERNUM 0x1310 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 3 +#define ZLIB_VER_REVISION 1 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip and raw deflate streams in + memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in the case of corrupted input. +*/ + +typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size); +typedef void (*free_func)(voidpf opaque, voidpf address); + +struct internal_state; + +typedef struct z_stream_s { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ + + Bytef *next_out; /* next output byte will go here */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use by the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field for deflate() */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion(void); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit(z_streamp strm, int level); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. total_in, total_out, adler, and msg are initialized. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate(z_streamp strm, int flush); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary. Some output may be provided even if + flush is zero. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more output + in that case. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed + codes block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six when the flush marker begins, in order to avoid + repeated flush markers upon calling deflate() again when avail_out == 0. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. + + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. + + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd(z_streamp strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit(z_streamp strm); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to Z_NULL, inflateInit updates + them to use default allocation functions. total_in, total_out, adler, and + msg are initialized. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression. + Actual decompression will be done by inflate(). So next_in, and avail_in, + next_out, and avail_out are unused and unchanged. The current + implementation of inflateInit() does not process any header information -- + that is deferred until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate(z_streamp strm, int flush); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + To assist in this, on return inflate() always sets strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed Adler-32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained unless inflateGetHeader() is used. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress was possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is to be attempted. +*/ + + +ZEXTERN int ZEXPORT inflateEnd(z_streamp strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2(z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy); + + This is another version of deflateInit with more compression options. The + fields zalloc, zfree and opaque must be initialized before by the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute a check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the Adler-32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler-32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + Adler-32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateCopy(z_streamp dest, + z_streamp source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset(z_streamp strm); +/* + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. total_in, total_out, adler, and msg are initialized. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams(z_streamp strm, + int level, + int strategy); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2(). This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression approach (which is a function of the level) or the + strategy is changed, and if there have been any deflate() calls since the + state was initialized or reset, then the input available so far is + compressed with the old level and strategy using deflate(strm, Z_BLOCK). + There are three approaches for the compression levels 0, 1..3, and 4..9 + respectively. The new level and strategy will take effect at the next call + of deflate(). + + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. +*/ + +ZEXTERN int ZEXPORT deflateTune(z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, + uLong sourceLen); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending(z_streamp strm, + unsigned *pending, + int *bits); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +ZEXTERN int ZEXPORT deflatePrime(z_streamp strm, + int bits, + int value); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm, + gz_headerp head); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to the current operating system, with no + extra, name, or comment fields. The gzip header is returned to the default + state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2(z_streamp strm, + int windowBits); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an Adler-32 or a CRC-32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will *not* automatically decode concatenated gzip members. + inflate() will return Z_STREAM_END at the end of the gzip member. The state + would need to be reset to continue decoding a subsequent gzip member. This + *must* be done if there is more data after a gzip member, in order for the + decompression to be compliant with the gzip standard (RFC 1952). + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler-32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler-32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateSync(z_streamp strm); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, + z_streamp source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset(z_streamp strm); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + total_in, total_out, adler, and msg are initialized. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2(z_streamp strm, + int windowBits); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime(z_streamp strm, + int bits, + int value); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark(z_streamp strm); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above, or -65536 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm, + gz_headerp head); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit(z_streamp strm, int windowBits, + unsigned char FAR *window); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func)(void FAR *, + z_const unsigned char FAR * FAR *); +typedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned); + +ZEXTERN int ZEXPORT inflateBack(z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags(void); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: ZLIB_DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed data. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + +ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong *sourceLen); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); + + Open the gzip (.gz) file at path for reading and decompressing, or + compressing and writing. The mode parameter is as in fopen ("rb" or "wb") + but can also include a compression level ("wb9") or a strategy: 'f' for + filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", + 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression + as in "wb9F". (See the description of deflateInit2 for more information + about the strategy parameter.) 'T' will request transparent writing or + appending with no compression and not using the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); +/* + Associate a gzFile with the file descriptor fd. File descriptors are + obtained from calls like open, dup, creat, pipe or fileno (if the file has + been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size); +/* + Set the internal buffer size used by this library's functions for file to + size. The default buffer size is 8192 bytes. This function must be called + after gzopen() or gzdopen(), and before any other calls that read or write + the file. The buffer memory allocation is always deferred to the first read + or write. Three times that size in buffer space is allocated. A larger + buffer size of, for example, 64K or 128K bytes will noticeably increase the + speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy); +/* + Dynamically update the compression level and strategy for file. See the + description of deflateInit2 for the meaning of these parameters. Previously + provided data is flushed before applying the parameter changes. + + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. +*/ + +ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len); +/* + Read and decompress up to len uncompressed bytes from file into buf. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, + gzFile file); +/* + Read and decompress up to nitems items of size size from file into buf, + otherwise operating as gzread() does. This duplicates the interface of + stdio's fread(), with size_t request and return types. If the library + defines size_t, then z_size_t is identical to size_t. If not, then z_size_t + is an unsigned integer type that can contain a pointer. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a z_size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevertheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, resetting and retrying on end-of-file, when size is not 1. +*/ + +ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); +/* + Compress and write the len uncompressed bytes at buf to file. gzwrite + returns the number of uncompressed bytes written or 0 in case of error. +*/ + +ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, + z_size_t nitems, gzFile file); +/* + Compress and write nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. If + the library defines size_t, then z_size_t is identical to size_t. If not, + then z_size_t is an unsigned integer type that can contain a pointer. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a z_size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + +ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); +/* + Convert, format, compress, and write the arguments (...) to file under + control of the string format, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf(), + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); +/* + Compress and write the given null-terminated string s to file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); +/* + Read and decompress bytes from file into buf, until len-1 characters are + read, or until a newline character is read and transferred to buf, or an + end-of-file condition is encountered. If any characters are read or if len + is one, the string is terminated with a null character. If no characters + are read due to an end-of-file or len is less than one, then the buffer is + left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc(gzFile file, int c); +/* + Compress and write c, converted to an unsigned char, into file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc(gzFile file); +/* + Read and decompress one byte from file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); +/* + Push c back onto the stream for file to be read as the first character on + the next read. At least one character of push-back is always allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); +/* + Flush all pending output to file. The parameter flush is as in the + deflate() function. The return value is the zlib error number (see function + gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatenated gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, + z_off_t offset, int whence); + + Set the starting position to offset relative to whence for the next gzread + or gzwrite on file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind(gzFile file); +/* + Rewind file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell(gzFile file); + + Return the starting position for the next gzread or gzwrite on file. + This position represents a number of bytes in the uncompressed data stream, + and is zero when starting, even if appending or reading a gzip stream from + the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file); + + Return the current compressed (actual) read or write offset of file. This + offset includes the count of bytes that precede the gzip stream, for example + when appending or when using gzdopen() for reading. When reading, the + offset does not include as yet unused buffered input. This information can + be used for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof(gzFile file); +/* + Return true (1) if the end-of-file indicator for file has been set while + reading, false (0) otherwise. Note that the end-of-file indicator is set + only if the read tried to go past the end of the input, but came up short. + Therefore, just like feof(), gzeof() may return false even if there is no + more data to read, in the event that the last read request was for the exact + number of bytes remaining in the input file. This will happen if the input + file size is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect(gzFile file); +/* + Return true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose(gzFile file); +/* + Flush all pending output for file, if necessary, close file and + deallocate the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r(gzFile file); +ZEXTERN int ZEXPORT gzclose_w(gzFile file); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); +/* + Return the error message for the last error which occurred on file. + errnum is set to zlib error number. If an error occurred in the file system + and not in the compression library, errnum is set to Z_ERRNO and the + application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr(gzFile file); +/* + Clear the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* !Z_SOLO */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. An Adler-32 value is in the range of a 32-bit + unsigned integer. If buf is Z_NULL, this function returns the required + initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, + z_size_t len); +/* + Same as adler32(), but with a size_t length. +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, + z_off_t len2); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. + If buf is Z_NULL, this function returns the required initial value for the + crc. Pre- and post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, + z_size_t len); +/* + Same as crc32(), but with a size_t length. +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. len2 must be non-negative. +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); + + Return the operator corresponding to length len2, to be used with + crc32_combine_op(). len2 must be non-negative. +*/ + +ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); +/* + Give the same result as crc32_combine(), using op in place of len2. op is + is generated from len2 by crc32_combine_gen(). This will be faster than + crc32_combine() if the generated op is used more than once. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateInit_(z_streamp strm, + const char *version, int stream_size); +ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size); +ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size); +#ifdef Z_PREFIX_SET +# define z_deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define z_inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#else +# define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#endif + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) +#endif + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); +#endif + +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# define z_crc32_combine_gen z_crc32_combine_gen64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# define crc32_combine_gen crc32_combine_gen64 +# endif +# ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); + +#endif /* !Z_SOLO */ + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError(int); +ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void); +ZEXTERN int ZEXPORT inflateUndermine(z_streamp, int); +ZEXTERN int ZEXPORT inflateValidate(z_streamp, int); +ZEXTERN unsigned long ZEXPORT inflateCodesUsed(z_streamp); +ZEXTERN int ZEXPORT inflateResetKeep(z_streamp); +ZEXTERN int ZEXPORT deflateResetKeep(z_streamp); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w(const wchar_t *path, + const char *mode); +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf(gzFile file, + const char *format, + va_list va); +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/src/libs/3rdparty/zlib/src/zutil.c b/src/libs/3rdparty/zlib/src/zutil.c new file mode 100644 index 00000000000..b1c5d2d3c6d --- /dev/null +++ b/src/libs/3rdparty/zlib/src/zutil.c @@ -0,0 +1,299 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2017 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" +#ifndef Z_SOLO +# include "gzguts.h" +#endif + +z_const char * const z_errmsg[10] = { + (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ + (z_const char *)"stream end", /* Z_STREAM_END 1 */ + (z_const char *)"", /* Z_OK 0 */ + (z_const char *)"file error", /* Z_ERRNO (-1) */ + (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ + (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ + (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ + (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ + (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ + (z_const char *)"" +}; + + +const char * ZEXPORT zlibVersion(void) { + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags(void) { + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef ZLIB_DEBUG + flags += 1 << 8; +#endif + /* +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif + */ +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef ZLIB_DEBUG +#include +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error(char *m) { + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(int err) { + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800 + /* The older Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifndef Z_SOLO + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { + voidpf buf; + ulg bsize = (ulg)items*size; + + (void)opaque; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { + int n; + + (void)opaque; + + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { + (void)opaque; + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { + (void)opaque; + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc(uInt size); +extern voidp calloc(uInt items, uInt size); +extern void free(voidpf ptr); +#endif + +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { + (void)opaque; + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { + (void)opaque; + free(ptr); +} + +#endif /* MY_ZCALLOC */ + +#endif /* !Z_SOLO */ diff --git a/src/libs/3rdparty/zlib/src/zutil.h b/src/libs/3rdparty/zlib/src/zutil.h new file mode 100644 index 00000000000..e25482fc3fd --- /dev/null +++ b/src/libs/3rdparty/zlib/src/zutil.h @@ -0,0 +1,258 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#ifdef QT_VISIBILITY_AVAILABLE +#define HAVE_HIDDEN +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifndef local +# define local static +#endif +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC) +# include +# if (ULONG_MAX == 0xffffffffffffffff) +# define Z_U8 unsigned long +# elif (ULLONG_MAX == 0xffffffffffffffff) +# define Z_U8 unsigned long long +# elif (UINT_MAX == 0xffffffffffffffff) +# define Z_U8 unsigned +# endif +#endif + +extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 1 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 2 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef __370__ +# if __TARGET_LIB__ < 0x20000000 +# define OS_CODE 4 +# elif __TARGET_LIB__ < 0x40000000 +# define OS_CODE 11 +# else +# define OS_CODE 8 +# endif +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 5 +#endif + +#ifdef OS2 +# define OS_CODE 6 +# if defined(M_I86) && !defined(Z_SOLO) +# include +# endif +#endif + +#if defined(MACOS) +# define OS_CODE 7 +#endif + +#ifdef __acorn +# define OS_CODE 13 +#endif + +#if defined(WIN32) && !defined(__CYGWIN__) +# define OS_CODE 10 +#endif + +#ifdef _BEOS_ +# define OS_CODE 16 +#endif + +#ifdef __TOS_OS400__ +# define OS_CODE 18 +#endif + +#if defined(__APPLE__) && !defined(OS_CODE) +# define OS_CODE 19 +#endif + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && \ + (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 3 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(pyr) || defined(Z_SOLO) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len); + int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); + void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); +#endif + +/* Diagnostic functions */ +#ifdef ZLIB_DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error(char *m); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, + unsigned size); + void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr); +#endif + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +/* Reverse the bytes in a 32-bit value */ +#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +#endif /* ZUTIL_H */ diff --git a/src/libs/advanceddockingsystem/dockareatitlebar.cpp b/src/libs/advanceddockingsystem/dockareatitlebar.cpp index e8d83fe69d2..3475e592205 100644 --- a/src/libs/advanceddockingsystem/dockareatitlebar.cpp +++ b/src/libs/advanceddockingsystem/dockareatitlebar.cpp @@ -330,6 +330,7 @@ TitleBarButton::TitleBarButton(bool showInTitleBar, QWidget *parent) DockAreaTitleBarPrivate::testConfigFlag(DockManager::DockAreaHideDisabledButtons)) { setFocusPolicy(Qt::NoFocus); + setVisible(m_showInTitleBar); } void TitleBarButton::setVisible(bool visible) diff --git a/src/libs/advanceddockingsystem/dockmanager.cpp b/src/libs/advanceddockingsystem/dockmanager.cpp index 60586ff4f43..dc1f0085bec 100644 --- a/src/libs/advanceddockingsystem/dockmanager.cpp +++ b/src/libs/advanceddockingsystem/dockmanager.cpp @@ -102,6 +102,9 @@ public: bool m_wasShown = false; bool m_workspaceOrderDirty = false; + bool m_mcusProject = false; + bool m_liteModeEnabled = false; + /** * Private data constructor */ @@ -370,12 +373,16 @@ DockManager::DockManager(QWidget *parent) DockManager::~DockManager() { - if (d->m_wasShown) { - emit aboutToUnloadWorkspace(d->m_workspace.fileName()); - save(); + // Only save startup workspace and lock state if not in lite design mode + if (!d->m_liteModeEnabled) { + if (d->m_wasShown) { + emit aboutToUnloadWorkspace(d->m_workspace.fileName()); + save(); + } + + saveStartupWorkspace(); + saveLockWorkspace(); } - saveStartupWorkspace(); - saveLockWorkspace(); // Fix memory leaks, see https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/307 std::vector areas; @@ -471,34 +478,41 @@ void DockManager::initialize() QString workspace = ADS::Constants::DEFAULT_WORKSPACE; - // Determine workspace to restore at startup - if (autoRestoreWorkspace()) { - const QString lastWorkspace = startupWorkspace(); - if (!lastWorkspace.isEmpty()) { - if (!workspaceExists(lastWorkspace)) { - // This is a fallback mechanism for pre 4.1 settings which stored the workspace name - // instead of the file name. + if (d->m_liteModeEnabled && workspaceExists(ADS::Constants::LITE_WORKSPACE)) { + workspace = ADS::Constants::LITE_WORKSPACE; + } else { + // Determine workspace to restore at startup + if (autoRestoreWorkspace()) { + const QString lastWorkspace = startupWorkspace(); + if (!lastWorkspace.isEmpty()) { + if (!workspaceExists(lastWorkspace)) { + // This is a fallback mechanism for pre 4.1 settings which stored the workspace + // name instead of the file name. - const std::vector separators = {"-", "_"}; + const std::vector separators = {"-", "_"}; - for (const QString &separator : separators) { - QString workspaceVariant = lastWorkspace; - workspaceVariant.replace(" ", separator); - workspaceVariant.append("." + workspaceFileExtension); + for (const QString &separator : separators) { + QString workspaceVariant = lastWorkspace; + workspaceVariant.replace(" ", separator); + workspaceVariant.append("." + workspaceFileExtension); - if (workspaceExists(workspaceVariant)) - workspace = workspaceVariant; + if (workspaceExists(workspaceVariant)) + workspace = workspaceVariant; + } + } else { + workspace = lastWorkspace; } - } else { - workspace = lastWorkspace; - } - } else - qWarning() << "Could not restore workspace:" << lastWorkspace; + } else + qWarning() << "Could not restore workspace:" << lastWorkspace; + } } openWorkspace(workspace); - lockWorkspace(d->m_settings->value(Constants::LOCK_WORKSPACE_SETTINGS_KEY, false).toBool()); + if (d->m_liteModeEnabled) + lockWorkspace(true); + else + lockWorkspace(d->m_settings->value(Constants::LOCK_WORKSPACE_SETTINGS_KEY, false).toBool()); } DockAreaWidget *DockManager::addDockWidget(DockWidgetArea area, @@ -1713,11 +1727,21 @@ void DockManager::saveLockWorkspace() } void DockManager::setMcusProject(bool value) { - m_mcusProject = value; + d->m_mcusProject = value; } bool DockManager::mcusProject() const { - return m_mcusProject; + return d->m_mcusProject; +} + +void DockManager::setLiteMode(bool value) +{ + d->m_liteModeEnabled = value; +} + +bool DockManager::isLiteModeEnabled() const +{ + return d->m_liteModeEnabled; } } // namespace ADS diff --git a/src/libs/advanceddockingsystem/dockmanager.h b/src/libs/advanceddockingsystem/dockmanager.h index b092eedef09..f0e30a5418a 100644 --- a/src/libs/advanceddockingsystem/dockmanager.h +++ b/src/libs/advanceddockingsystem/dockmanager.h @@ -31,6 +31,7 @@ namespace ADS { namespace Constants { const char DEFAULT_WORKSPACE[] = "Basic.wrk"; // Needs to align with a shipped preset +const char LITE_WORKSPACE[] = "Lite-QML-Designer.wrk"; const char STARTUP_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/StartupWorkspace"; const char AUTO_RESTORE_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/AutoRestoreLastWorkspace"; const char LOCK_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/LockWorkspace"; @@ -126,7 +127,7 @@ public: = 0x2000, ///< If this option is enabled, the tab of a dock widget is always displayed - even if it is the only visible dock widget in a floating widget. DockAreaHasUndockButton = 0x4000, //!< If the flag is set each dock area has an undock button DockAreaHasTabsMenuButton - = 0x8000, //!< If the flag is set each dock area has a tabs menu button + = 0x8000, //!< If the flag is set each dock area has a tabs menu button DockAreaHideDisabledButtons = 0x10000, //!< If the flag is set disabled dock area buttons will not appear on the toolbar at all (enabling them will bring them back) DockAreaDynamicTabsMenuButtonVisibility @@ -144,6 +145,8 @@ public: EqualSplitOnInsertion = 0x400000, ///!< if enabled, the space is equally distributed to all widgets in a splitter + HideContextMenuDockWidgetTab = 0x800000, + MiddleMouseButtonClosesTab = 0x2000000, //! If the flag is set, the user can use the mouse middle button to close the tab under the mouse @@ -182,15 +185,15 @@ public: AutoHideButtonCheckable = 0x08, //!< If the flag is set, the auto hide button will be checked and unchecked depending on the auto hide state. Mainly for styling purposes. AutoHideSideBarsIconOnly - = 0x10, ///< show only icons in auto hide side tab - if a tab has no icon, then the text will be shown + = 0x10, //!< show only icons in auto hide side tab - if a tab has no icon, then the text will be shown AutoHideShowOnMouseOver - = 0x20, ///< show the auto hide window on mouse over tab and hide it if mouse leaves auto hide container + = 0x20, //!< show the auto hide window on mouse over tab and hide it if mouse leaves auto hide container AutoHideCloseButtonCollapsesDock - = 0x40, ///< Close button of an auto hide container collapses the dock instead of hiding it completely + = 0x40, //!< Close button of an auto hide container collapses the dock instead of hiding it completely AutoHideHasCloseButton - = 0x80, //< If the flag is set an auto hide title bar has a close button + = 0x80, //!< If the flag is set an auto hide title bar has a close button AutoHideHasMinimizeButton - = 0x100, ///< if this flag is set, the auto hide title bar has a minimize button to collapse the dock widget + = 0x100, //!< if this flag is set, the auto hide title bar has a minimize button to collapse the dock widget DefaultAutoHideConfig = AutoHideFeatureEnabled | DockAreaHasAutoHideButton | AutoHideCloseButtonCollapsesDock | AutoHideHasCloseButton @@ -774,6 +777,9 @@ public: void setMcusProject(bool value); bool mcusProject() const; + void setLiteMode(bool value); + bool isLiteModeEnabled() const; + signals: void aboutToUnloadWorkspace(QString fileName); void aboutToLoadWorkspace(QString fileName); @@ -798,8 +804,6 @@ private: void saveStartupWorkspace(); void saveLockWorkspace(); - - bool m_mcusProject = false; }; // class DockManager } // namespace ADS diff --git a/src/libs/advanceddockingsystem/dockwidgettab.cpp b/src/libs/advanceddockingsystem/dockwidgettab.cpp index 3d1ef7d4905..bcf8540d357 100644 --- a/src/libs/advanceddockingsystem/dockwidgettab.cpp +++ b/src/libs/advanceddockingsystem/dockwidgettab.cpp @@ -461,6 +461,9 @@ void DockWidgetTab::mouseMoveEvent(QMouseEvent *event) void DockWidgetTab::contextMenuEvent(QContextMenuEvent *event) { + if (DockManager::testConfigFlag(DockManager::HideContextMenuDockWidgetTab)) + return; + event->accept(); if (d->isDraggingState(DraggingFloatingWidget)) return; diff --git a/src/libs/nanotrace/CMakeLists.txt b/src/libs/nanotrace/CMakeLists.txt index 50693644ea5..2c5791cf638 100644 --- a/src/libs/nanotrace/CMakeLists.txt +++ b/src/libs/nanotrace/CMakeLists.txt @@ -1,5 +1,6 @@ add_qtc_library(Nanotrace PUBLIC_DEFINES NANOTRACE_ENABLED + PUBLIC_COMPILE_OPTIONS $<$:/wd5030> SOURCES nanotraceglobals.h nanotrace.cpp nanotrace.h @@ -11,10 +12,6 @@ add_qtc_library(Nanotrace VISIBILITY_INLINES_HIDDEN OFF ) -if(TARGET Nanotrace) - target_compile_options(Nanotrace PUBLIC $<$:/wd5030>) -endif() - option(DESIGNSTUDIO_USE_NANOTRACE "Enables collecting performance data with nanotrace for Design Studio" OFF) extend_qtc_library(Nanotrace diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index 8cf85f11eda..959f2721c8c 100644 --- a/src/libs/qmljs/qmljscheck.cpp +++ b/src/libs/qmljs/qmljscheck.cpp @@ -546,19 +546,33 @@ private: uint _block = 0; }; -class IdsThatShouldNotBeUsedInDesigner : public QStringList +class IdsThatShouldNotBeUsedInDesigner : public QStringList { public: IdsThatShouldNotBeUsedInDesigner() - : QStringList({"top", "bottom", "left", "right", "width", "height", - "x", "y", "opacity", "parent", "item", "flow", - "color", "margin", "padding", "print", "border", "font", - "text", "source", "state", "visible", "focus", "data", - "clip", "layer", "scale", "enabled", "anchors", - "texture", "shaderInfo", "sprite", "spriteSequence", "baseState" - "vector", "string", "url", "var", "point", "date", "size", "list", - "enumeration"}) + : QStringList({ + "action", "alias", "anchors", "as", "baseState", "bool", + "border", "bottom", "break", "case", "catch", "clip", + "color", "continue", "data", "date", "debugger", "default", + "delete", "do", "double", "else", "enabled", "enumeration", + "finally", "flow", "focus", "font", "for", "function", + "height", "id", "if", "import", "in", "instanceof", + "int", "item", "layer", "left", "list", "margin", + "matrix4x4", "new", "opacity", "padding", "parent", "point", + "print", "quaternion", "real", "rect", "return", "right", + "scale", "shaderInfo", "size", "source", "sprite", "spriteSequence", + "state", "string", "switch", "text", "texture", "this", + "throw", "time", "top", "try", "typeof", "url", + "var", "variant", "vector", "vector2d", "vector3d", "vector4d", + "visible", "void", "while", "width", "with", "x", + "y", "z", + }) {} + + bool containsId(const QString &id) const + { + return std::binary_search(constBegin(), constEnd(), id); + } }; class VisualAspectsPropertyBlackList : public QStringList @@ -682,7 +696,7 @@ QList Check::defaultDisabledMessagesForNonQuickUi() bool Check::incompatibleDesignerQmlId(const QString &id) { - return idsThatShouldNotBeUsedInDesigner->contains(id); + return idsThatShouldNotBeUsedInDesigner->containsId(id); } Check::Check(Document::Ptr doc, const ContextPtr &context, Utils::QtcSettings *qtcSettings) @@ -936,7 +950,7 @@ bool Check::visit(UiObjectBinding *ast) if (!ast->hasOnToken) { checkProperty(ast->qualifiedId); } else { - addMessage(ErrBehavioursNotSupportedInQmlUi, locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation())); + //addMessage(ErrBehavioursNotSupportedInQmlUi, locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation())); } visitQmlObject(ast, ast->qualifiedTypeNameId, ast->initializer); diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index 09bc6aecdb8..c81d849a9f5 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -1544,10 +1544,8 @@ QList CppQmlTypes::createObjectsForImport(const QStri // if it already exists, skip const QString key = qualifiedName(package, fmo->className(), version); - if (m_objectsByQualifiedName.contains(key)) { - exportedObjects.insert(key, m_objectsByQualifiedName.value(key)); + if (m_objectsByQualifiedName.contains(key)) continue; - } ComponentVersion cppVersion; for (const FakeMetaObject::Export &bestExport : std::as_const(bestExports)) { diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp index 97c00e1c8d9..40198809be7 100644 --- a/src/libs/qmljs/qmljslink.cpp +++ b/src/libs/qmljs/qmljslink.cpp @@ -512,6 +512,16 @@ bool LinkPrivate::importLibrary(const Document::Ptr &doc, // commands in qmldir files, and is pending removal in Qt 6. for (const auto &toImport : libraryInfo.imports()) { QString importName = toImport.module; + + // These implicit imports do not work reliable, since each type + // is only added to one import/module. If a type is added here, + // it is not added to the actual module, because of caching. + // + // In case of QtQuick3D.MaterialEditor this leads to a reproducible issue. + // As a workaround we simply skip all implicit imports for QtQuick3D. + if (importName == "QtQuick3D") + continue; + ComponentVersion vNow = toImport.version; /* There was a period in which no version == auto * Required for QtQuick imports less than 2.15 diff --git a/src/libs/qmlpuppetcommunication/commands/puppettocreatorcommand.h b/src/libs/qmlpuppetcommunication/commands/puppettocreatorcommand.h index b0012f3eb24..a8f37a81e53 100644 --- a/src/libs/qmlpuppetcommunication/commands/puppettocreatorcommand.h +++ b/src/libs/qmlpuppetcommunication/commands/puppettocreatorcommand.h @@ -18,6 +18,7 @@ public: ActiveSceneChanged, ActiveSplitChanged, RenderModelNodePreviewImage, + Import3DPreviewIcon, Import3DPreviewImage, Import3DSupport, NodeAtPos, diff --git a/src/libs/qmlpuppetcommunication/commands/requestmodelnodepreviewimagecommand.cpp b/src/libs/qmlpuppetcommunication/commands/requestmodelnodepreviewimagecommand.cpp index 0b8a17a31fa..758509d603d 100644 --- a/src/libs/qmlpuppetcommunication/commands/requestmodelnodepreviewimagecommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/requestmodelnodepreviewimagecommand.cpp @@ -10,13 +10,17 @@ namespace QmlDesigner { RequestModelNodePreviewImageCommand::RequestModelNodePreviewImageCommand() = default; -RequestModelNodePreviewImageCommand::RequestModelNodePreviewImageCommand(qint32 id, const QSize &size, - const QString &componentPath, - qint32 renderItemId) +RequestModelNodePreviewImageCommand::RequestModelNodePreviewImageCommand( + qint32 id, + const QSize &size, + const QString &componentPath, + qint32 renderItemId, + const QByteArray &requestId) : m_instanceId(id) , m_size(size) , m_componentPath(componentPath) , m_renderItemId(renderItemId) + , m_requestId(requestId) { } @@ -40,12 +44,18 @@ qint32 RequestModelNodePreviewImageCommand::renderItemId() const return m_renderItemId; } +QByteArray RequestModelNodePreviewImageCommand::requestId() const +{ + return m_requestId; +} + QDataStream &operator<<(QDataStream &out, const RequestModelNodePreviewImageCommand &command) { out << int(command.instanceId()); out << command.size(); out << command.componentPath(); out << command.renderItemId(); + out << command.requestId(); return out; } @@ -56,6 +66,7 @@ QDataStream &operator>>(QDataStream &in, RequestModelNodePreviewImageCommand &co in >> command.m_size; in >> command.m_componentPath; in >> command.m_renderItemId; + in >> command.m_requestId; return in; } @@ -65,7 +76,8 @@ QDebug operator <<(QDebug debug, const RequestModelNodePreviewImageCommand &comm << "instanceId: " << command.instanceId() << ", " << "size: " << command.size() << ", " << "componentPath: " << command.componentPath() << ", " - << "renderItemId: " << command.renderItemId() << ")"; + << "renderItemId: " << command.renderItemId() << ", " + << "requestId: " << command.requestId() << ")"; } } // namespace QmlDesigner diff --git a/src/libs/qmlpuppetcommunication/commands/requestmodelnodepreviewimagecommand.h b/src/libs/qmlpuppetcommunication/commands/requestmodelnodepreviewimagecommand.h index 414b8f6cc9d..33a1c97866b 100644 --- a/src/libs/qmlpuppetcommunication/commands/requestmodelnodepreviewimagecommand.h +++ b/src/libs/qmlpuppetcommunication/commands/requestmodelnodepreviewimagecommand.h @@ -18,38 +18,46 @@ class RequestModelNodePreviewImageCommand public: RequestModelNodePreviewImageCommand(); - explicit RequestModelNodePreviewImageCommand(qint32 id, const QSize &size, - const QString &componentPath, qint32 renderItemId); + explicit RequestModelNodePreviewImageCommand( + qint32 id, + const QSize &size, + const QString &componentPath, + qint32 renderItemId, + const QByteArray &requestId = {}); qint32 instanceId() const; QSize size() const; QString componentPath() const; qint32 renderItemId() const; + QByteArray requestId() const; private: qint32 m_instanceId; QSize m_size; QString m_componentPath; qint32 m_renderItemId; + QByteArray m_requestId; }; inline bool operator==(const RequestModelNodePreviewImageCommand &first, const RequestModelNodePreviewImageCommand &second) { - return first.instanceId() == second.instanceId() - && first.size() == second.size() - && first.componentPath() == second.componentPath() - && first.renderItemId() == second.renderItemId(); + return first.instanceId() == second.instanceId() && first.size() == second.size() + && first.componentPath() == second.componentPath() + && first.renderItemId() == second.renderItemId() + && first.requestId() == second.requestId(); } inline size_t qHash(const RequestModelNodePreviewImageCommand &key, size_t seed = 0) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) return ::qHash(key.instanceId(), seed) - ^ ::qHash(std::make_pair(key.size().width(), key.size().height()), seed) - ^ ::qHash(key.componentPath(), seed) ^ ::qHash(key.renderItemId(), seed); + ^ ::qHash(std::make_pair(key.size().width(), key.size().height()), seed) + ^ ::qHash(key.componentPath(), seed) ^ ::qHash(key.renderItemId(), seed) + ^ ::qHash(key.requestId(), seed); #else - return qHashMulti(seed, key.instanceId(), key.size(), key.componentPath(), key.renderItemId()); + return qHashMulti( + seed, key.instanceId(), key.size(), key.componentPath(), key.renderItemId(), key.requestId()); #endif } diff --git a/src/libs/qmlpuppetcommunication/commands/view3dactioncommand.cpp b/src/libs/qmlpuppetcommunication/commands/view3dactioncommand.cpp index a522499ffa7..72605d6711b 100644 --- a/src/libs/qmlpuppetcommunication/commands/view3dactioncommand.cpp +++ b/src/libs/qmlpuppetcommunication/commands/view3dactioncommand.cpp @@ -3,11 +3,17 @@ #include "view3dactioncommand.h" -#include - #include #include +namespace { +template +[[nodiscard]] constexpr std::underlying_type_t to_underlying(Enumeration enumeration) noexcept +{ + return static_cast>(enumeration); +} +} + namespace QmlDesigner { View3DActionCommand::View3DActionCommand(View3DActionType type, const QVariant &value) @@ -68,7 +74,7 @@ QDebug operator<<(QDebug debug, const View3DActionCommand &command) QDebug operator<<(QDebug debug, View3DActionType type) { - return debug.nospace() << Utils::to_underlying(type); + return debug.nospace() << to_underlying(type); } } // namespace QmlDesigner diff --git a/src/libs/qmlpuppetcommunication/container/imagecontainer.cpp b/src/libs/qmlpuppetcommunication/container/imagecontainer.cpp index 7747a9d1188..5cfeb2967bc 100644 --- a/src/libs/qmlpuppetcommunication/container/imagecontainer.cpp +++ b/src/libs/qmlpuppetcommunication/container/imagecontainer.cpp @@ -56,6 +56,11 @@ QRectF ImageContainer::rect() const return m_rect; } +QByteArray ImageContainer::requestId() const +{ + return m_requestId; +} + void ImageContainer::setImage(const QImage &image) { QTC_ASSERT(m_image.isNull(), /**/); @@ -68,6 +73,11 @@ void ImageContainer::setRect(const QRectF &rectangle) m_rect = rectangle; } +void ImageContainer::setRequestId(const QByteArray &newRequestId) +{ + m_requestId = newRequestId; +} + void ImageContainer::removeSharedMemorys(const QVector &keyNumberVector) { for (qint32 keyNumber : keyNumberVector) { @@ -151,6 +161,7 @@ QDataStream &operator<<(QDataStream &out, const ImageContainer &container) out << container.instanceId(); out << container.keyNumber(); out << container.rect(); + out << container.requestId(); const QImage image = container.image(); @@ -236,6 +247,7 @@ QDataStream &operator>>(QDataStream &in, ImageContainer &container) in >> container.m_instanceId; in >> container.m_keyNumber; in >> container.m_rect; + in >> container.m_requestId; in >> sharedMemoryIsUsed; if (sharedMemoryIsUsed) { @@ -259,10 +271,11 @@ bool operator <(const ImageContainer &first, const ImageContainer &second) QDebug operator <<(QDebug debug, const ImageContainer &container) { - return debug.nospace() << "ImageContainer(" - << "instanceId: " << container.instanceId() << ", " - << "size: " << container.image().size() << ")"; + debug.nospace() << "ImageContainer(" + << "instanceId: " << container.instanceId() << ", "; + if (!container.requestId().isEmpty()) + debug << "requestId: " << container.requestId() << ", "; + return debug << "size: " << container.image().size() << ")"; } - } // namespace QmlDesigner diff --git a/src/libs/qmlpuppetcommunication/container/imagecontainer.h b/src/libs/qmlpuppetcommunication/container/imagecontainer.h index cc028d45c0f..214cf0f18f7 100644 --- a/src/libs/qmlpuppetcommunication/container/imagecontainer.h +++ b/src/libs/qmlpuppetcommunication/container/imagecontainer.h @@ -23,9 +23,11 @@ public: QImage image() const; qint32 keyNumber() const; QRectF rect() const; + QByteArray requestId() const; void setImage(const QImage &image); void setRect(const QRectF &rectangle); + void setRequestId(const QByteArray &newRequestId); static void removeSharedMemorys(const QVector &keyNumberVector); @@ -34,6 +36,7 @@ private: qint32 m_instanceId; qint32 m_keyNumber; QRectF m_rect; + QByteArray m_requestId; }; QDataStream &operator<<(QDataStream &out, const ImageContainer &container); diff --git a/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h b/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h index d248e5e6fd1..d5647a0740b 100644 --- a/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h +++ b/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h @@ -5,13 +5,16 @@ #include #include +#include #include namespace QmlDesigner { using PropertyName = QByteArray; +using PropertyNameView = QByteArrayView; using PropertyNameList = QList; +using PropertyNameViews = QVarLengthArray; using PropertyNames = std::vector; using TypeName = QByteArray; @@ -20,7 +23,8 @@ enum class AuxiliaryDataType { Temporary, Document, NodeInstancePropertyOverwrite, - NodeInstanceAuxiliary + NodeInstanceAuxiliary, + Persistent }; enum class View3DActionType { @@ -58,7 +62,9 @@ enum class View3DActionType { EditCameraStopAllMoves, SetLastSceneEnvData, Import3dUpdatePreviewImage, - Import3dRotatePreviewModel + Import3dRotatePreviewModel, + Import3dAddPreviewModel, + Import3dSetCurrentPreviewModel }; constexpr bool isNanotraceEnabled() diff --git a/src/libs/solutions/CMakeLists.txt b/src/libs/solutions/CMakeLists.txt index 67630f067c7..0e7447009a2 100644 --- a/src/libs/solutions/CMakeLists.txt +++ b/src/libs/solutions/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(spinner) add_subdirectory(tasking) add_subdirectory(terminal) +add_subdirectory(zip) diff --git a/src/libs/solutions/zip/CMakeLists.txt b/src/libs/solutions/zip/CMakeLists.txt new file mode 100644 index 00000000000..14bd1235be0 --- /dev/null +++ b/src/libs/solutions/zip/CMakeLists.txt @@ -0,0 +1,43 @@ +add_qtc_library(Zip + DEPENDS Qt::Core + DEFINES ZIP_LIB + SOURCES + zip.cpp + zipreader.h + zipwriter.h + zip_global.h + INCLUDES + ${CMAKE_CURRENT_LIST_DIR}/../../3rdparty/zlib/src +) + +extend_qtc_library(Zip + SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/../../3rdparty/zlib/src + SKIP_AUTOMOC + SOURCES + adler32.c + compress.c + crc32.c + crc32.h + deflate.c + deflate.h + gzclose.c + gzguts.h + gzlib.c + gzread.c + gzwrite.c + infback.c + inffast.c + inffast.h + inffixed.h + inflate.c + inflate.h + inftrees.c + inftrees.h + trees.c + trees.h + uncompr.c + zconf.h + zlib.h + zutil.c + zutil.h +) diff --git a/src/libs/solutions/zip/zip.cpp b/src/libs/solutions/zip/zip.cpp new file mode 100644 index 00000000000..70f445384e0 --- /dev/null +++ b/src/libs/solutions/zip/zip.cpp @@ -0,0 +1,1343 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "zipreader.h" +#include "zipwriter.h" + +#include + +#include +#include +#include +#include + +#include + +// Zip standard version for archives handled by this API +// (actually, the only basic support of this version is implemented but it is enough for now) +#define ZIP_VERSION 20 + +#if 0 +#define ZDEBUG qDebug +#else +#define ZDEBUG if (0) qDebug +#endif + +static inline uint readUInt(const uchar *data) +{ + return (data[0]) + (data[1]<<8) + (data[2]<<16) + (data[3]<<24); +} + +static inline ushort readUShort(const uchar *data) +{ + return (data[0]) + (data[1]<<8); +} + +static inline void writeUInt(uchar *data, uint i) +{ + data[0] = i & 0xff; + data[1] = (i>>8) & 0xff; + data[2] = (i>>16) & 0xff; + data[3] = (i>>24) & 0xff; +} + +static inline void writeUShort(uchar *data, ushort i) +{ + data[0] = i & 0xff; + data[1] = (i>>8) & 0xff; +} + +static inline void copyUInt(uchar *dest, const uchar *src) +{ + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + dest[3] = src[3]; +} + +static inline void copyUShort(uchar *dest, const uchar *src) +{ + dest[0] = src[0]; + dest[1] = src[1]; +} + +static void writeMSDosDate(uchar *dest, const QDateTime& dt) +{ + if (dt.isValid()) { + quint16 time = + (dt.time().hour() << 11) // 5 bit hour + | (dt.time().minute() << 5) // 6 bit minute + | (dt.time().second() >> 1); // 5 bit double seconds + + dest[0] = time & 0xff; + dest[1] = time >> 8; + + quint16 date = + ((dt.date().year() - 1980) << 9) // 7 bit year 1980-based + | (dt.date().month() << 5) // 4 bit month + | (dt.date().day()); // 5 bit day + + dest[2] = char(date); + dest[3] = char(date >> 8); + } else { + dest[0] = 0; + dest[1] = 0; + dest[2] = 0; + dest[3] = 0; + } +} + +static int inflate(Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen) +{ + z_stream stream; + int err; + + stream.next_in = const_cast(source); + stream.avail_in = (uInt)sourceLen; + if ((uLong)stream.avail_in != sourceLen) + return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) + return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)nullptr; + stream.zfree = (free_func)nullptr; + + err = inflateInit2(&stream, -MAX_WBITS); + if (err != Z_OK) + return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} + +static int deflate (Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen) +{ + z_stream stream; + int err; + + stream.next_in = const_cast(source); + stream.avail_in = (uInt)sourceLen; + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)nullptr; + stream.zfree = (free_func)nullptr; + stream.opaque = (voidpf)nullptr; + + err = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + + +namespace WindowsFileAttributes { +enum { + Dir = 0x10, // FILE_ATTRIBUTE_DIRECTORY + File = 0x80, // FILE_ATTRIBUTE_NORMAL + TypeMask = 0x90, + + ReadOnly = 0x01, // FILE_ATTRIBUTE_READONLY + PermMask = 0x01 +}; +} + +namespace UnixFileAttributes { +enum { + Dir = 0040000, // __S_IFDIR + File = 0100000, // __S_IFREG + SymLink = 0120000, // __S_IFLNK + TypeMask = 0170000, // __S_IFMT + + ReadUser = 0400, // __S_IRUSR + WriteUser = 0200, // __S_IWUSR + ExeUser = 0100, // __S_IXUSR + ReadGroup = 0040, // __S_IRGRP + WriteGroup = 0020, // __S_IWGRP + ExeGroup = 0010, // __S_IXGRP + ReadOther = 0004, // __S_IROTH + WriteOther = 0002, // __S_IWOTH + ExeOther = 0001, // __S_IXOTH + PermMask = 0777 +}; +} + +static QFile::Permissions modeToPermissions(quint32 mode) +{ + QFile::Permissions ret; + if (mode & UnixFileAttributes::ReadUser) + ret |= QFile::ReadOwner | QFile::ReadUser; + if (mode & UnixFileAttributes::WriteUser) + ret |= QFile::WriteOwner | QFile::WriteUser; + if (mode & UnixFileAttributes::ExeUser) + ret |= QFile::ExeOwner | QFile::ExeUser; + if (mode & UnixFileAttributes::ReadGroup) + ret |= QFile::ReadGroup; + if (mode & UnixFileAttributes::WriteGroup) + ret |= QFile::WriteGroup; + if (mode & UnixFileAttributes::ExeGroup) + ret |= QFile::ExeGroup; + if (mode & UnixFileAttributes::ReadOther) + ret |= QFile::ReadOther; + if (mode & UnixFileAttributes::WriteOther) + ret |= QFile::WriteOther; + if (mode & UnixFileAttributes::ExeOther) + ret |= QFile::ExeOther; + return ret; +} + +static quint32 permissionsToMode(QFile::Permissions perms) +{ + quint32 mode = 0; + if (perms & (QFile::ReadOwner | QFile::ReadUser)) + mode |= UnixFileAttributes::ReadUser; + if (perms & (QFile::WriteOwner | QFile::WriteUser)) + mode |= UnixFileAttributes::WriteUser; + if (perms & (QFile::ExeOwner | QFile::ExeUser)) + mode |= UnixFileAttributes::WriteUser; + if (perms & QFile::ReadGroup) + mode |= UnixFileAttributes::ReadGroup; + if (perms & QFile::WriteGroup) + mode |= UnixFileAttributes::WriteGroup; + if (perms & QFile::ExeGroup) + mode |= UnixFileAttributes::ExeGroup; + if (perms & QFile::ReadOther) + mode |= UnixFileAttributes::ReadOther; + if (perms & QFile::WriteOther) + mode |= UnixFileAttributes::WriteOther; + if (perms & QFile::ExeOther) + mode |= UnixFileAttributes::ExeOther; + return mode; +} + +static QDateTime readMSDosDate(const uchar *src) +{ + uint dosDate = readUInt(src); + quint64 uDate; + uDate = (quint64)(dosDate >> 16); + uint tm_mday = (uDate & 0x1f); + uint tm_mon = ((uDate & 0x1E0) >> 5); + uint tm_year = (((uDate & 0x0FE00) >> 9) + 1980); + uint tm_hour = ((dosDate & 0xF800) >> 11); + uint tm_min = ((dosDate & 0x7E0) >> 5); + uint tm_sec = ((dosDate & 0x1f) << 1); + + return QDateTime(QDate(tm_year, tm_mon, tm_mday), QTime(tm_hour, tm_min, tm_sec)); +} + +// for details, see http://www.pkware.com/documents/casestudies/APPNOTE.TXT + +enum HostOS { + HostFAT = 0, + HostAMIGA = 1, + HostVMS = 2, // VAX/VMS + HostUnix = 3, + HostVM_CMS = 4, + HostAtari = 5, // what if it's a minix filesystem? [cjh] + HostHPFS = 6, // filesystem used by OS/2 (and NT 3.x) + HostMac = 7, + HostZ_System = 8, + HostCPM = 9, + HostTOPS20 = 10, // pkzip 2.50 NTFS + HostNTFS = 11, // filesystem used by Windows NT + HostQDOS = 12, // SMS/QDOS + HostAcorn = 13, // Archimedes Acorn RISC OS + HostVFAT = 14, // filesystem used by Windows 95, NT + HostMVS = 15, + HostBeOS = 16, // hybrid POSIX/database filesystem + HostTandem = 17, + HostOS400 = 18, + HostOSX = 19 +}; +Q_DECLARE_TYPEINFO(HostOS, Q_PRIMITIVE_TYPE); + +enum GeneralPurposeFlag { + Encrypted = 0x01, + AlgTune1 = 0x02, + AlgTune2 = 0x04, + HasDataDescriptor = 0x08, + PatchedData = 0x20, + StrongEncrypted = 0x40, + Utf8Names = 0x0800, + CentralDirectoryEncrypted = 0x2000 +}; +Q_DECLARE_TYPEINFO(GeneralPurposeFlag, Q_PRIMITIVE_TYPE); + +enum CompressionMethod { + CompressionMethodStored = 0, + CompressionMethodShrunk = 1, + CompressionMethodReduced1 = 2, + CompressionMethodReduced2 = 3, + CompressionMethodReduced3 = 4, + CompressionMethodReduced4 = 5, + CompressionMethodImploded = 6, + CompressionMethodReservedTokenizing = 7, // reserved for tokenizing + CompressionMethodDeflated = 8, + CompressionMethodDeflated64 = 9, + CompressionMethodPKImploding = 10, + + CompressionMethodBZip2 = 12, + + CompressionMethodLZMA = 14, + + CompressionMethodTerse = 18, + CompressionMethodLz77 = 19, + + CompressionMethodJpeg = 96, + CompressionMethodWavPack = 97, + CompressionMethodPPMd = 98, + CompressionMethodWzAES = 99 +}; +Q_DECLARE_TYPEINFO(CompressionMethod, Q_PRIMITIVE_TYPE); + +struct LocalFileHeader +{ + uchar signature[4]; // 0x04034b50 + uchar version_needed[2]; + uchar general_purpose_bits[2]; + uchar compression_method[2]; + uchar last_mod_file[4]; + uchar crc_32[4]; + uchar compressed_size[4]; + uchar uncompressed_size[4]; + uchar file_name_length[2]; + uchar extra_field_length[2]; +}; +Q_DECLARE_TYPEINFO(LocalFileHeader, Q_PRIMITIVE_TYPE); + +struct DataDescriptor +{ + uchar crc_32[4]; + uchar compressed_size[4]; + uchar uncompressed_size[4]; +}; +Q_DECLARE_TYPEINFO(DataDescriptor, Q_PRIMITIVE_TYPE); + +struct CentralFileHeader +{ + uchar signature[4]; // 0x02014b50 + uchar version_made[2]; + uchar version_needed[2]; + uchar general_purpose_bits[2]; + uchar compression_method[2]; + uchar last_mod_file[4]; + uchar crc_32[4]; + uchar compressed_size[4]; + uchar uncompressed_size[4]; + uchar file_name_length[2]; + uchar extra_field_length[2]; + uchar file_comment_length[2]; + uchar disk_start[2]; + uchar internal_file_attributes[2]; + uchar external_file_attributes[4]; + uchar offset_local_header[4]; +}; +Q_DECLARE_TYPEINFO(CentralFileHeader, Q_PRIMITIVE_TYPE); + +struct EndOfDirectory +{ + uchar signature[4]; // 0x06054b50 + uchar this_disk[2]; + uchar start_of_directory_disk[2]; + uchar num_dir_entries_this_disk[2]; + uchar num_dir_entries[2]; + uchar directory_size[4]; + uchar dir_start_offset[4]; + uchar comment_length[2]; +}; +Q_DECLARE_TYPEINFO(EndOfDirectory, Q_PRIMITIVE_TYPE); + +struct FileHeader +{ + CentralFileHeader h; + QByteArray file_name; + QByteArray extra_field; + QByteArray file_comment; +}; +Q_DECLARE_TYPEINFO(FileHeader, Q_RELOCATABLE_TYPE); + +class ZipPrivate +{ +public: + ZipPrivate(QIODevice *device, bool ownDev) + : device(device), ownDevice(ownDev), dirtyFileTree(true), start_of_directory(0) + { + } + + ~ZipPrivate() + { + if (ownDevice) + delete device; + } + + ZipReader::FileInfo fillFileInfo(int index) const; + + QIODevice *device; + bool ownDevice; + bool dirtyFileTree; + QList fileHeaders; + QByteArray comment; + uint start_of_directory; +}; + +ZipReader::FileInfo ZipPrivate::fillFileInfo(int index) const +{ + ZipReader::FileInfo fileInfo; + FileHeader header = fileHeaders.at(index); + quint32 mode = readUInt(header.h.external_file_attributes); + const HostOS hostOS = HostOS(readUShort(header.h.version_made) >> 8); + switch (hostOS) { + case HostUnix: + mode = (mode >> 16) & 0xffff; + switch (mode & UnixFileAttributes::TypeMask) { + case UnixFileAttributes::SymLink: + fileInfo.isSymLink = true; + break; + case UnixFileAttributes::Dir: + fileInfo.isDir = true; + break; + case UnixFileAttributes::File: + default: // ### just for the case; should we warn? + fileInfo.isFile = true; + break; + } + fileInfo.permissions = modeToPermissions(mode); + break; + case HostFAT: + case HostNTFS: + case HostHPFS: + case HostVFAT: + switch (mode & WindowsFileAttributes::TypeMask) { + case WindowsFileAttributes::Dir: + fileInfo.isDir = true; + break; + case WindowsFileAttributes::File: + default: + fileInfo.isFile = true; + break; + } + fileInfo.permissions |= QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther; + if ((mode & WindowsFileAttributes::ReadOnly) == 0) + fileInfo.permissions |= QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther; + if (fileInfo.isDir) + fileInfo.permissions |= QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther; + break; + default: + qWarning("Zip: Zip entry format at %d is not supported.", index); + return fileInfo; // we don't support anything else + } + + ushort general_purpose_bits = readUShort(header.h.general_purpose_bits); + // if bit 11 is set, the filename and comment fields must be encoded using UTF-8 + const bool inUtf8 = (general_purpose_bits & Utf8Names) != 0; + fileInfo.filePath = inUtf8 ? QString::fromUtf8(header.file_name) : QString::fromLocal8Bit(header.file_name); + fileInfo.crc = readUInt(header.h.crc_32); + fileInfo.size = readUInt(header.h.uncompressed_size); + fileInfo.lastModified = readMSDosDate(header.h.last_mod_file); + + // fix the file path, if broken (convert separators, eat leading and trailing ones) + fileInfo.filePath = QDir::fromNativeSeparators(fileInfo.filePath); + QStringView filePathRef(fileInfo.filePath); + while (filePathRef.startsWith(u'.') || filePathRef.startsWith(u'/')) + filePathRef = filePathRef.mid(1); + while (filePathRef.endsWith(u'/')) + filePathRef.chop(1); + + fileInfo.filePath = filePathRef.toString(); + return fileInfo; +} + +class ZipReaderPrivate : public ZipPrivate +{ +public: + ZipReaderPrivate(QIODevice *device, bool ownDev) + : ZipPrivate(device, ownDev), status(ZipReader::NoError) + { + } + + void scanFiles(); + + ZipReader::Status status; +}; + +class ZipWriterPrivate : public ZipPrivate +{ +public: + ZipWriterPrivate(QIODevice *device, bool ownDev) + : ZipPrivate(device, ownDev), + status(ZipWriter::NoError), + permissions(QFile::ReadOwner | QFile::WriteOwner), + compressionPolicy(ZipWriter::AlwaysCompress) + { + } + + ZipWriter::Status status; + QFile::Permissions permissions; + ZipWriter::CompressionPolicy compressionPolicy; + + enum EntryType { Directory, File, Symlink }; + + void addEntry(EntryType type, const QString &fileName, const QByteArray &contents); +}; + +static LocalFileHeader toLocalHeader(const CentralFileHeader &ch) +{ + LocalFileHeader h; + writeUInt(h.signature, 0x04034b50); + copyUShort(h.version_needed, ch.version_needed); + copyUShort(h.general_purpose_bits, ch.general_purpose_bits); + copyUShort(h.compression_method, ch.compression_method); + copyUInt(h.last_mod_file, ch.last_mod_file); + copyUInt(h.crc_32, ch.crc_32); + copyUInt(h.compressed_size, ch.compressed_size); + copyUInt(h.uncompressed_size, ch.uncompressed_size); + copyUShort(h.file_name_length, ch.file_name_length); + copyUShort(h.extra_field_length, ch.extra_field_length); + return h; +} + +void ZipReaderPrivate::scanFiles() +{ + if (!dirtyFileTree) + return; + + if (! (device->isOpen() || device->open(QIODevice::ReadOnly))) { + status = ZipReader::FileOpenError; + return; + } + + if ((device->openMode() & QIODevice::ReadOnly) == 0) { // only read the index from readable files. + status = ZipReader::FileReadError; + return; + } + + dirtyFileTree = false; + uchar tmp[4]; + device->read((char *)tmp, 4); + if (readUInt(tmp) != 0x04034b50) { + qWarning("Zip: not a zip file!"); + return; + } + + // find EndOfDirectory header + int i = 0; + int start_of_directory = -1; + int num_dir_entries = 0; + EndOfDirectory eod; + while (start_of_directory == -1) { + const int pos = device->size() - int(sizeof(EndOfDirectory)) - i; + if (pos < 0 || i > 65535) { + qWarning("Zip: EndOfDirectory not found"); + return; + } + + device->seek(pos); + device->read((char *)&eod, sizeof(EndOfDirectory)); + if (readUInt(eod.signature) == 0x06054b50) + break; + ++i; + } + + // have the eod + start_of_directory = readUInt(eod.dir_start_offset); + num_dir_entries = readUShort(eod.num_dir_entries); + ZDEBUG("start_of_directory at %d, num_dir_entries=%d", start_of_directory, num_dir_entries); + int comment_length = readUShort(eod.comment_length); + if (comment_length != i) + qWarning("Zip: failed to parse zip file."); + comment = device->read(qMin(comment_length, i)); + + + device->seek(start_of_directory); + for (i = 0; i < num_dir_entries; ++i) { + FileHeader header; + int read = device->read((char *) &header.h, sizeof(CentralFileHeader)); + if (read < (int)sizeof(CentralFileHeader)) { + qWarning("Zip: Failed to read complete header, index may be incomplete"); + break; + } + if (readUInt(header.h.signature) != 0x02014b50) { + qWarning("Zip: invalid header signature, index may be incomplete"); + break; + } + + int l = readUShort(header.h.file_name_length); + header.file_name = device->read(l); + if (header.file_name.size() != l) { + qWarning("Zip: Failed to read filename from zip index, index may be incomplete"); + break; + } + l = readUShort(header.h.extra_field_length); + header.extra_field = device->read(l); + if (header.extra_field.size() != l) { + qWarning("Zip: Failed to read extra field in zip file, skipping file, index may be incomplete"); + break; + } + l = readUShort(header.h.file_comment_length); + header.file_comment = device->read(l); + if (header.file_comment.size() != l) { + qWarning("Zip: Failed to read read file comment, index may be incomplete"); + break; + } + + ZDEBUG("found file '%s'", header.file_name.data()); + fileHeaders.append(header); + } +} + +void ZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const QByteArray &contents/*, QFile::Permissions permissions, Zip::Method m*/) +{ +#ifndef NDEBUG + static const char *const entryTypes[] = { + "directory", + "file ", + "symlink " }; + ZDEBUG() << "adding" << entryTypes[type] <<":" << fileName.toUtf8().data() << (type == 2 ? QByteArray(" -> " + contents).constData() : ""); +#endif + + if (! (device->isOpen() || device->open(QIODevice::WriteOnly))) { + status = ZipWriter::FileOpenError; + return; + } + device->seek(start_of_directory); + + // don't compress small files + ZipWriter::CompressionPolicy compression = compressionPolicy; + if (compressionPolicy == ZipWriter::AutoCompress) { + if (contents.size() < 64) + compression = ZipWriter::NeverCompress; + else + compression = ZipWriter::AlwaysCompress; + } + + FileHeader header; + memset(&header.h, 0, sizeof(CentralFileHeader)); + writeUInt(header.h.signature, 0x02014b50); + + writeUShort(header.h.version_needed, ZIP_VERSION); + writeUInt(header.h.uncompressed_size, contents.size()); + writeMSDosDate(header.h.last_mod_file, QDateTime::currentDateTime()); + QByteArray data = contents; + if (compression == ZipWriter::AlwaysCompress) { + writeUShort(header.h.compression_method, CompressionMethodDeflated); + + ulong len = contents.size(); + // shamelessly copied form zlib + len += (len >> 12) + (len >> 14) + 11; + int res; + do { + data.resize(len); + res = deflate((uchar*)data.data(), &len, (const uchar*)contents.constData(), contents.size()); + + switch (res) { + case Z_OK: + data.resize(len); + break; + case Z_MEM_ERROR: + qWarning("Zip: Z_MEM_ERROR: Not enough memory to compress file, skipping"); + data.resize(0); + break; + case Z_BUF_ERROR: + len *= 2; + break; + } + } while (res == Z_BUF_ERROR); + } +// TODO add a check if data.length() > contents.length(). Then try to store the original and revert the compression method to be uncompressed + writeUInt(header.h.compressed_size, data.size()); + uint crc_32 = ::crc32(0, nullptr, 0); + crc_32 = ::crc32(crc_32, (const uchar *)contents.constData(), contents.size()); + writeUInt(header.h.crc_32, crc_32); + + // if bit 11 is set, the filename and comment fields must be encoded using UTF-8 + ushort general_purpose_bits = Utf8Names; // always use utf-8 + writeUShort(header.h.general_purpose_bits, general_purpose_bits); + + const bool inUtf8 = (general_purpose_bits & Utf8Names) != 0; + header.file_name = inUtf8 ? fileName.toUtf8() : fileName.toLocal8Bit(); + if (header.file_name.size() > 0xffff) { + qWarning("Zip: Filename is too long, chopping it to 65535 bytes"); + header.file_name = header.file_name.left(0xffff); // ### don't break the utf-8 sequence, if any + } + if (header.file_comment.size() + header.file_name.size() > 0xffff) { + qWarning("Zip: File comment is too long, chopping it to 65535 bytes"); + header.file_comment.truncate(0xffff - header.file_name.size()); // ### don't break the utf-8 sequence, if any + } + writeUShort(header.h.file_name_length, header.file_name.size()); + //h.extra_field_length[2]; + + writeUShort(header.h.version_made, HostUnix << 8); + //uchar internal_file_attributes[2]; + //uchar external_file_attributes[4]; + quint32 mode = permissionsToMode(permissions); + switch (type) { + case Symlink: + mode |= UnixFileAttributes::SymLink; + break; + case Directory: + mode |= UnixFileAttributes::Dir; + break; + case File: + mode |= UnixFileAttributes::File; + break; + default: + Q_UNREACHABLE(); + break; + } + writeUInt(header.h.external_file_attributes, mode << 16); + writeUInt(header.h.offset_local_header, start_of_directory); + + + fileHeaders.append(header); + + LocalFileHeader h = toLocalHeader(header.h); + device->write((const char *)&h, sizeof(LocalFileHeader)); + device->write(header.file_name); + device->write(data); + start_of_directory = device->pos(); + dirtyFileTree = true; +} + +////////////////////////////// Reader + +/*! + \class ZipReader::FileInfo + \internal + Represents one entry in the zip table of contents. +*/ + +/*! + \variable ZipReader::FileInfo::filePath + The full filepath inside the archive. +*/ + +/*! + \variable ZipReader::FileInfo::isDir + A boolean type indicating if the entry is a directory. +*/ + +/*! + \variable ZipReader::FileInfo::isFile + A boolean type, if it is one this entry is a file. +*/ + +/*! + \variable ZipReader::FileInfo::isSymLink + A boolean type, if it is one this entry is symbolic link. +*/ + +/*! + \variable ZipReader::FileInfo::permissions + A list of flags for the permissions of this entry. +*/ + +/*! + \variable ZipReader::FileInfo::crc + The calculated checksum as a crc type. +*/ + +/*! + \variable ZipReader::FileInfo::size + The total size of the unpacked content. +*/ + +/*! + \class ZipReader + \internal + \since 4.5 + + \brief the ZipReader class provides a way to inspect the contents of a zip + archive and extract individual files from it. + + ZipReader can be used to read a zip archive either from a file or from any + device. An in-memory QBuffer for instance. The reader can be used to read + which files are in the archive using fileInfoList() and entryInfoAt() but + also to extract individual files using fileData() or even to extract all + files in the archive using extractAll() +*/ + +/*! + Create a new zip archive that operates on the \a fileName. The file will be + opened with the \a mode. +*/ +ZipReader::ZipReader(const QString &archive, QIODevice::OpenMode mode) +{ + auto f = std::make_unique(archive); + const bool result = f->open(mode); + ZipReader::Status status; + const QFileDevice::FileError error = f->error(); + if (result && error == QFile::NoError) { + status = NoError; + } else { + if (error == QFile::ReadError) + status = FileReadError; + else if (error == QFile::OpenError) + status = FileOpenError; + else if (error == QFile::PermissionsError) + status = FilePermissionsError; + else + status = FileError; + } + + d = new ZipReaderPrivate(f.get(), /*ownDevice=*/true); + Q_UNUSED(f.release()); + d->status = status; +} + +/*! + Create a new zip archive that operates on the archive found in \a device. + You have to open the device previous to calling the constructor and only a + device that is readable will be scanned for zip filecontent. + */ +ZipReader::ZipReader(QIODevice *device) + : d(new ZipReaderPrivate(device, /*ownDevice=*/false)) +{ + Q_ASSERT(device); +} + +/*! + Destructor +*/ +ZipReader::~ZipReader() +{ + close(); + delete d; +} + +/*! + Returns device used for reading zip archive. +*/ +QIODevice* ZipReader::device() const +{ + return d->device; +} + +/*! + Returns \c true if the user can read the file; otherwise returns \c false. +*/ +bool ZipReader::isReadable() const +{ + return d->device->isReadable(); +} + +/*! + Returns \c true if the file exists; otherwise returns \c false. +*/ +bool ZipReader::exists() const +{ + QFile *f = qobject_cast (d->device); + if (f == nullptr) + return true; + return f->exists(); +} + +/*! + Returns the list of files the archive contains. +*/ +QList ZipReader::fileInfoList() const +{ + d->scanFiles(); + QList files; + const int numFileHeaders = d->fileHeaders.size(); + files.reserve(numFileHeaders); + for (int i = 0; i < numFileHeaders; ++i) + files.append(d->fillFileInfo(i)); + return files; + +} + +/*! + Return the number of items in the zip archive. +*/ +int ZipReader::count() const +{ + d->scanFiles(); + return d->fileHeaders.size(); +} + +/*! + Returns a FileInfo of an entry in the zipfile. + The \a index is the index into the directory listing of the zipfile. + Returns an invalid FileInfo if \a index is out of boundaries. + + \sa fileInfoList() +*/ +ZipReader::FileInfo ZipReader::entryInfoAt(int index) const +{ + d->scanFiles(); + if (index >= 0 && index < d->fileHeaders.size()) + return d->fillFileInfo(index); + return ZipReader::FileInfo(); +} + +/*! + Fetch the file contents from the zip archive and return the uncompressed bytes. +*/ +QByteArray ZipReader::fileData(const QString &fileName) const +{ + d->scanFiles(); + int i; + for (i = 0; i < d->fileHeaders.size(); ++i) { + if (QString::fromLocal8Bit(d->fileHeaders.at(i).file_name) == fileName) + break; + } + if (i == d->fileHeaders.size()) + return QByteArray(); + + FileHeader header = d->fileHeaders.at(i); + + ushort version_needed = readUShort(header.h.version_needed); + if (version_needed > ZIP_VERSION) { + qWarning("Zip: .ZIP specification version %d implementationis needed to extract the data.", version_needed); + return QByteArray(); + } + + ushort general_purpose_bits = readUShort(header.h.general_purpose_bits); + int compressed_size = readUInt(header.h.compressed_size); + int uncompressed_size = readUInt(header.h.uncompressed_size); + int start = readUInt(header.h.offset_local_header); + //qDebug("uncompressing file %d: local header at %d", i, start); + + d->device->seek(start); + LocalFileHeader lh; + d->device->read((char *)&lh, sizeof(LocalFileHeader)); + uint skip = readUShort(lh.file_name_length) + readUShort(lh.extra_field_length); + d->device->seek(d->device->pos() + skip); + + int compression_method = readUShort(lh.compression_method); + //qDebug("file=%s: compressed_size=%d, uncompressed_size=%d", fileName.toLocal8Bit().data(), compressed_size, uncompressed_size); + + if ((general_purpose_bits & Encrypted) != 0) { + qWarning("Zip: Unsupported encryption method is needed to extract the data."); + return QByteArray(); + } + + //qDebug("file at %lld", d->device->pos()); + QByteArray compressed = d->device->read(compressed_size); + if (compression_method == CompressionMethodStored) { + // no compression + compressed.truncate(uncompressed_size); + return compressed; + } else if (compression_method == CompressionMethodDeflated) { + // Deflate + //qDebug("compressed=%d", compressed.size()); + compressed.truncate(compressed_size); + QByteArray baunzip; + ulong len = qMax(uncompressed_size, 1); + int res; + do { + baunzip.resize(len); + res = inflate((uchar*)baunzip.data(), &len, + (const uchar*)compressed.constData(), compressed_size); + + switch (res) { + case Z_OK: + if ((int)len != baunzip.size()) + baunzip.resize(len); + break; + case Z_MEM_ERROR: + qWarning("Zip: Z_MEM_ERROR: Not enough memory"); + break; + case Z_BUF_ERROR: + len *= 2; + break; + case Z_DATA_ERROR: + qWarning("Zip: Z_DATA_ERROR: Input data is corrupted"); + break; + } + } while (res == Z_BUF_ERROR); + return baunzip; + } + + qWarning("Zip: Unsupported compression method %d is needed to extract the data.", compression_method); + return QByteArray(); +} + +/*! + Extracts the full contents of the zip file into \a destinationDir on + the local filesystem. + In case writing or linking a file fails, the extraction will be aborted. +*/ +bool ZipReader::extractAll(const QString &destinationDir) const +{ + QDir baseDir(destinationDir); + + // create directories first + const QList allFiles = fileInfoList(); + bool foundDirs = false; + bool hasDirs = false; + for (const FileInfo &fi : allFiles) { + const QString absPath = destinationDir + QDir::separator() + fi.filePath; + if (fi.isDir) { + foundDirs = true; + if (!baseDir.mkpath(fi.filePath)) + return false; + if (!QFile::setPermissions(absPath, fi.permissions)) + return false; + } else if (!hasDirs && fi.filePath.contains(u"/")) { + // filePath does not have leading or trailing '/', so if we find + // one, than the file path contains directories. + hasDirs = true; + } + } + + // Some zip archives can be broken in the sense that they do not report + // separate entries for directories, only for files. In this case we + // need to recreate directory structure based on the file paths. + if (hasDirs && !foundDirs) { + for (const FileInfo &fi : allFiles) { + const auto dirPath = fi.filePath.left(fi.filePath.lastIndexOf(u"/")); + if (!baseDir.mkpath(dirPath)) + return false; + // We will leave the directory permissions default in this case, + // because setting dir permissions based on file is incorrect + } + } + + // set up symlinks + for (const FileInfo &fi : allFiles) { + const QString absPath = destinationDir + QDir::separator() + fi.filePath; + if (fi.isSymLink) { + QString destination = QFile::decodeName(fileData(fi.filePath)); + if (destination.isEmpty()) + return false; + QFileInfo linkFi(absPath); + if (!QFile::exists(linkFi.absolutePath())) + QDir::root().mkpath(linkFi.absolutePath()); + if (!QFile::link(destination, absPath)) + return false; + /* cannot change permission of links + if (!QFile::setPermissions(absPath, fi.permissions)) + return false; + */ + } + } + + for (const FileInfo &fi : allFiles) { + const QString absPath = destinationDir + QDir::separator() + fi.filePath; + if (fi.isFile) { + QFile f(absPath); + if (!f.open(QIODevice::WriteOnly)) + return false; + f.write(fileData(fi.filePath)); + f.setPermissions(fi.permissions); + f.close(); + } + } + + return true; +} + +/*! + \enum ZipReader::Status + + The following status values are possible: + + \value NoError No error occurred. + \value FileReadError An error occurred when reading from the file. + \value FileOpenError The file could not be opened. + \value FilePermissionsError The file could not be accessed. + \value FileError Another file error occurred. +*/ + +/*! + Returns a status code indicating the first error that was met by ZipReader, + or ZipReader::NoError if no error occurred. +*/ +ZipReader::Status ZipReader::status() const +{ + return d->status; +} + +/*! + Close the zip file. +*/ +void ZipReader::close() +{ + d->device->close(); +} + +////////////////////////////// Writer + +/*! + \class ZipWriter + \internal + \since 4.5 + + \brief the ZipWriter class provides a way to create a new zip archive. + + ZipWriter can be used to create a zip archive containing any number of files + and directories. The files in the archive will be compressed in a way that is + compatible with common zip reader applications. +*/ + + +/*! + Create a new zip archive that operates on the \a archive filename. The file will + be opened with the \a mode. + \sa isValid() +*/ +ZipWriter::ZipWriter(const QString &fileName, QIODevice::OpenMode mode) +{ + auto f = std::make_unique(fileName); + ZipWriter::Status status; + if (f->open(mode) && f->error() == QFile::NoError) + status = ZipWriter::NoError; + else { + if (f->error() == QFile::WriteError) + status = ZipWriter::FileWriteError; + else if (f->error() == QFile::OpenError) + status = ZipWriter::FileOpenError; + else if (f->error() == QFile::PermissionsError) + status = ZipWriter::FilePermissionsError; + else + status = ZipWriter::FileError; + } + + d = new ZipWriterPrivate(f.get(), /*ownDevice=*/true); + Q_UNUSED(f.release()); + d->status = status; +} + +/*! + Create a new zip archive that operates on the archive found in \a device. + You have to open the device previous to calling the constructor and + only a device that is readable will be scanned for zip filecontent. + */ +ZipWriter::ZipWriter(QIODevice *device) + : d(new ZipWriterPrivate(device, /*ownDevice=*/false)) +{ + Q_ASSERT(device); +} + +ZipWriter::~ZipWriter() +{ + close(); + delete d; +} + +/*! + Returns device used for writing zip archive. +*/ +QIODevice* ZipWriter::device() const +{ + return d->device; +} + +/*! + Returns \c true if the user can write to the archive; otherwise returns \c false. +*/ +bool ZipWriter::isWritable() const +{ + return d->device->isWritable(); +} + +/*! + Returns \c true if the file exists; otherwise returns \c false. +*/ +bool ZipWriter::exists() const +{ + QFile *f = qobject_cast (d->device); + if (f == nullptr) + return true; + return f->exists(); +} + +/*! + \enum ZipWriter::Status + + The following status values are possible: + + \value NoError No error occurred. + \value FileWriteError An error occurred when writing to the device. + \value FileOpenError The file could not be opened. + \value FilePermissionsError The file could not be accessed. + \value FileError Another file error occurred. +*/ + +/*! + Returns a status code indicating the first error that was met by ZipWriter, + or ZipWriter::NoError if no error occurred. +*/ +ZipWriter::Status ZipWriter::status() const +{ + return d->status; +} + +/*! + \enum ZipWriter::CompressionPolicy + + \value AlwaysCompress A file that is added is compressed. + \value NeverCompress A file that is added will be stored without changes. + \value AutoCompress A file that is added will be compressed only if that will give a smaller file. +*/ + +/*! + Sets the policy for compressing newly added files to the new \a policy. + + \note the default policy is AlwaysCompress + + \sa compressionPolicy() + \sa addFile() +*/ +void ZipWriter::setCompressionPolicy(CompressionPolicy policy) +{ + d->compressionPolicy = policy; +} + +/*! + Returns the currently set compression policy. + \sa setCompressionPolicy() + \sa addFile() +*/ +ZipWriter::CompressionPolicy ZipWriter::compressionPolicy() const +{ + return d->compressionPolicy; +} + +/*! + Sets the permissions that will be used for newly added files. + + \note the default permissions are QFile::ReadOwner | QFile::WriteOwner. + + \sa creationPermissions() + \sa addFile() +*/ +void ZipWriter::setCreationPermissions(QFile::Permissions permissions) +{ + d->permissions = permissions; +} + +/*! + Returns the currently set creation permissions. + + \sa setCreationPermissions() + \sa addFile() +*/ +QFile::Permissions ZipWriter::creationPermissions() const +{ + return d->permissions; +} + +/*! + Add a file to the archive with \a data as the file contents. + The file will be stored in the archive using the \a fileName which + includes the full path in the archive. + + The new file will get the file permissions based on the current + creationPermissions and it will be compressed using the zip compression + based on the current compression policy. + + \sa setCreationPermissions() + \sa setCompressionPolicy() +*/ +void ZipWriter::addFile(const QString &fileName, const QByteArray &data) +{ + d->addEntry(ZipWriterPrivate::File, QDir::fromNativeSeparators(fileName), data); +} + +/*! + Add a file to the archive with \a device as the source of the contents. + The contents returned from QIODevice::readAll() will be used as the + filedata. + The file will be stored in the archive using the \a fileName which + includes the full path in the archive. +*/ +void ZipWriter::addFile(const QString &fileName, QIODevice *device) +{ + Q_ASSERT(device); + QIODevice::OpenMode mode = device->openMode(); + bool opened = false; + if ((mode & QIODevice::ReadOnly) == 0) { + opened = true; + if (! device->open(QIODevice::ReadOnly)) { + d->status = FileOpenError; + return; + } + } + d->addEntry(ZipWriterPrivate::File, QDir::fromNativeSeparators(fileName), device->readAll()); + if (opened) + device->close(); +} + +/*! + Create a new directory in the archive with the specified \a dirName and + the \a permissions; +*/ +void ZipWriter::addDirectory(const QString &dirName) +{ + QString name(QDir::fromNativeSeparators(dirName)); + // separator is mandatory + if (!name.endsWith(u'/')) + name.append(u'/'); + d->addEntry(ZipWriterPrivate::Directory, name, QByteArray()); +} + +/*! + Create a new symbolic link in the archive with the specified \a dirName + and the \a permissions; + A symbolic link contains the destination (relative) path and name. +*/ +void ZipWriter::addSymLink(const QString &fileName, const QString &destination) +{ + d->addEntry(ZipWriterPrivate::Symlink, QDir::fromNativeSeparators(fileName), QFile::encodeName(destination)); +} + +/*! + Closes the zip file. +*/ +void ZipWriter::close() +{ + if (!(d->device->openMode() & QIODevice::WriteOnly)) { + d->device->close(); + return; + } + + //qDebug("Zip::close writing directory, %d entries", d->fileHeaders.size()); + d->device->seek(d->start_of_directory); + // write new directory + for (int i = 0; i < d->fileHeaders.size(); ++i) { + const FileHeader &header = d->fileHeaders.at(i); + d->device->write((const char *)&header.h, sizeof(CentralFileHeader)); + d->device->write(header.file_name); + d->device->write(header.extra_field); + d->device->write(header.file_comment); + } + int dir_size = d->device->pos() - d->start_of_directory; + // write end of directory + EndOfDirectory eod; + memset(&eod, 0, sizeof(EndOfDirectory)); + writeUInt(eod.signature, 0x06054b50); + //uchar this_disk[2]; + //uchar start_of_directory_disk[2]; + writeUShort(eod.num_dir_entries_this_disk, d->fileHeaders.size()); + writeUShort(eod.num_dir_entries, d->fileHeaders.size()); + writeUInt(eod.directory_size, dir_size); + writeUInt(eod.dir_start_offset, d->start_of_directory); + writeUShort(eod.comment_length, d->comment.size()); + + d->device->write((const char *)&eod, sizeof(EndOfDirectory)); + d->device->write(d->comment); + d->device->close(); +} diff --git a/src/libs/solutions/zip/zip_global.h b/src/libs/solutions/zip/zip_global.h new file mode 100644 index 00000000000..46badde33d0 --- /dev/null +++ b/src/libs/solutions/zip/zip_global.h @@ -0,0 +1,12 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +#if defined(ZIP_LIB) +# define ZIP_EXPORT Q_DECL_EXPORT +#else +# define ZIP_EXPORT Q_DECL_IMPORT +#endif diff --git a/src/libs/solutions/zip/zipreader.h b/src/libs/solutions/zip/zipreader.h new file mode 100644 index 00000000000..45d19e50982 --- /dev/null +++ b/src/libs/solutions/zip/zipreader.h @@ -0,0 +1,69 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "zip_global.h" + +#include +#include +#include + +class ZipReaderPrivate; + +class ZIP_EXPORT ZipReader +{ +public: + explicit ZipReader(const QString &fileName, QIODevice::OpenMode mode = QIODevice::ReadOnly ); + + explicit ZipReader(QIODevice *device); + ~ZipReader(); + + QIODevice* device() const; + + bool isReadable() const; + bool exists() const; + + struct FileInfo + { + FileInfo() noexcept + : isDir(false), isFile(false), isSymLink(false), crc(0), size(0) + {} + + bool isValid() const noexcept { return isDir || isFile || isSymLink; } + + QString filePath; + uint isDir : 1; + uint isFile : 1; + uint isSymLink : 1; + QFile::Permissions permissions; + uint crc; + qint64 size; + QDateTime lastModified; + }; + + QList fileInfoList() const; + int count() const; + + FileInfo entryInfoAt(int index) const; + QByteArray fileData(const QString &fileName) const; + bool extractAll(const QString &destinationDir) const; + + enum Status { + NoError, + FileReadError, + FileOpenError, + FilePermissionsError, + FileError + }; + + Status status() const; + + void close(); + +private: + ZipReaderPrivate *d; + Q_DISABLE_COPY_MOVE(ZipReader) +}; +Q_DECLARE_TYPEINFO(ZipReader::FileInfo, Q_RELOCATABLE_TYPE); +Q_DECLARE_TYPEINFO(ZipReader::Status, Q_PRIMITIVE_TYPE); diff --git a/src/libs/solutions/zip/zipwriter.h b/src/libs/solutions/zip/zipwriter.h new file mode 100644 index 00000000000..61c0c1f7d11 --- /dev/null +++ b/src/libs/solutions/zip/zipwriter.h @@ -0,0 +1,61 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "zip_global.h" + +#include + +class ZipWriterPrivate; + +QT_FORWARD_DECLARE_CLASS(QString) + +class ZIP_EXPORT ZipWriter +{ +public: + explicit ZipWriter(const QString &fileName, QIODevice::OpenMode mode = (QIODevice::WriteOnly | QIODevice::Truncate) ); + + explicit ZipWriter(QIODevice *device); + ~ZipWriter(); + + QIODevice* device() const; + + bool isWritable() const; + bool exists() const; + + enum Status { + NoError, + FileWriteError, + FileOpenError, + FilePermissionsError, + FileError + }; + + Status status() const; + + enum CompressionPolicy { + AlwaysCompress, + NeverCompress, + AutoCompress + }; + + void setCompressionPolicy(CompressionPolicy policy); + CompressionPolicy compressionPolicy() const; + + void setCreationPermissions(QFile::Permissions permissions); + QFile::Permissions creationPermissions() const; + + void addFile(const QString &fileName, const QByteArray &data); + + void addFile(const QString &fileName, QIODevice *device); + + void addDirectory(const QString &dirName); + + void addSymLink(const QString &fileName, const QString &destination); + + void close(); +private: + ZipWriterPrivate *d; + Q_DISABLE_COPY_MOVE(ZipWriter) +}; diff --git a/src/libs/sqlite/CMakeLists.txt b/src/libs/sqlite/CMakeLists.txt index e0cf3093142..b010cfb0f2a 100644 --- a/src/libs/sqlite/CMakeLists.txt +++ b/src/libs/sqlite/CMakeLists.txt @@ -20,7 +20,7 @@ add_qtc_library(SqliteInternal OBJECT extend_qtc_library(SqliteInternal CONDITION QTC_STATIC_BUILD - PROPERTIES COMPILE_OPTIONS $,/FIsqlite_static_config.h,-includesqlite_static_config.h> + PRIVATE_COMPILE_OPTIONS $,/FIsqlite_static_config.h,-includesqlite_static_config.h> ) if (APPLE) @@ -80,7 +80,7 @@ extend_qtc_library(Sqlite extend_qtc_library(Sqlite CONDITION QTC_STATIC_BUILD + PRIVATE_COMPILE_OPTIONS $,/FIsqlite_static_config.h,-includesqlite_static_config.h> PROPERTIES - COMPILE_OPTIONS $,/FIsqlite_static_config.h,-includesqlite_static_config.h> INTERFACE_COMPILE_OPTIONS $,/FI../3rdparty/sqlite/sqlite_static_config.h,-include../3rdparty/sqlite/sqlite_static_config.h> ) diff --git a/src/libs/sqlite/createtablesqlstatementbuilder.h b/src/libs/sqlite/createtablesqlstatementbuilder.h index 9c13370e138..988c3afa4af 100644 --- a/src/libs/sqlite/createtablesqlstatementbuilder.h +++ b/src/libs/sqlite/createtablesqlstatementbuilder.h @@ -14,16 +14,18 @@ namespace Sqlite { template class CreateTableSqlStatementBuilder { + using Columns = StableReferenceBasicColumns; + public: CreateTableSqlStatementBuilder() : m_sqlStatementBuilder(templateText()) {} - void setTableName(Utils::SmallString &&tableName) + void setTableName(Utils::SmallStringView tableName) { m_sqlStatementBuilder.clear(); - this->m_tableName = std::move(tableName); + this->m_tableName = tableName; } void addColumn(Utils::SmallStringView columnName, @@ -42,7 +44,8 @@ public: { m_tableConstraints = std::move(constraints); } - void setColumns(BasicColumns columns) + + void setColumns(Columns columns) { m_sqlStatementBuilder.clear(); @@ -291,7 +294,7 @@ private: void bindAll() const { - m_sqlStatementBuilder.bind("$table", m_tableName.clone()); + m_sqlStatementBuilder.bind("$table", m_tableName); bindTemporary(); bindIfNotExists(); @@ -330,7 +333,7 @@ private: private: mutable SqlStatementBuilder m_sqlStatementBuilder; Utils::SmallString m_tableName; - BasicColumns m_columns; + Columns m_columns; TableConstraints m_tableConstraints; bool m_useWithoutRowId = false; bool m_useIfNotExits = false; diff --git a/src/libs/sqlite/sqlitebasestatement.h b/src/libs/sqlite/sqlitebasestatement.h index 64acba0a27a..a41be5f4822 100644 --- a/src/libs/sqlite/sqlitebasestatement.h +++ b/src/libs/sqlite/sqlitebasestatement.h @@ -77,7 +77,7 @@ public: void bind(int index, ValueView value); void bind(int index, BlobView blobView); - template> + template = true> void bind(int index, Type id) { if (!id.isNull()) @@ -527,8 +527,7 @@ private: operator BlobView() { return statement.fetchBlobValue(column); } operator ValueView() { return statement.fetchValueView(column); } - template> + template> constexpr operator ConversionType() { if (statement.fetchType(column) == Type::Integer) { diff --git a/src/libs/sqlite/sqlitecolumn.h b/src/libs/sqlite/sqlitecolumn.h index 918711fdf95..82e8894ecc6 100644 --- a/src/libs/sqlite/sqlitecolumn.h +++ b/src/libs/sqlite/sqlitecolumn.h @@ -5,7 +5,10 @@ #include "constraints.h" +#include + #include +#include #include namespace Sqlite { @@ -84,18 +87,24 @@ public: using Column = BasicColumn; using StrictColumn = BasicColumn; -using Columns = std::vector; -using StrictColumns = std::vector; +inline constexpr qsizetype maximumSupportedColumnCount = 32; + +using Columns = QVarLengthArray; +using StableReferenceColumns = std::list; +using StrictColumns = QVarLengthArray; +using StableReferenceStrictColumns = std::list; using ColumnConstReference = std::reference_wrapper; using StrictColumnConstReference = std::reference_wrapper; -using ColumnConstReferences = std::vector; -using StrictColumnConstReferences = std::vector; +using ColumnConstReferences = QVarLengthArray; +using StrictColumnConstReferences = QVarLengthArray; template -using BasicColumns = std::vector>; +using BasicColumns = QVarLengthArray, maximumSupportedColumnCount>; +template +using StableReferenceBasicColumns = std::list>; template using BasicColumnConstReference = std::reference_wrapper>; template -using BasicColumnConstReferences = std::vector>; +using BasicColumnConstReferences = QVarLengthArray, maximumSupportedColumnCount>; } // namespace Sqlite diff --git a/src/libs/sqlite/sqlitedatabase.h b/src/libs/sqlite/sqlitedatabase.h index 0db256c8162..c4d839b13a3 100644 --- a/src/libs/sqlite/sqlitedatabase.h +++ b/src/libs/sqlite/sqlitedatabase.h @@ -102,7 +102,10 @@ public: void walCheckpointFull() override { std::lock_guard lock{m_databaseMutex}; - m_databaseBackend.walCheckpointFull(); + try { + m_databaseBackend.walCheckpointFull(); + } catch (const StatementIsBusy &) { + } } void setUpdateHook(void *object, diff --git a/src/libs/sqlite/sqliteids.h b/src/libs/sqlite/sqliteids.h index abbb13d7c16..f8a735de937 100644 --- a/src/libs/sqlite/sqliteids.h +++ b/src/libs/sqlite/sqliteids.h @@ -15,6 +15,9 @@ namespace Sqlite { template class BasicId { + template + friend class CompoundBasicId; + public: using IsBasicId = std::true_type; using DatabaseType = InternalIntegerType; @@ -91,10 +94,110 @@ public: NanotraceHR::convertToString(string, id.internalId()); } + friend bool compareId(BasicId first, BasicId second) { return first.id == second.id; } + protected: InternalIntegerType id = 0; }; +template +class CompoundBasicId +{ +public: + using IsBasicId = std::true_type; + using DatabaseType = long long; + + using MainId = BasicId; + using ContextId = BasicId; + + constexpr explicit CompoundBasicId() = default; + + static constexpr CompoundBasicId create(MainId id, ContextId contextId) + { + CompoundBasicId compoundId; + compoundId.id = (static_cast(contextId.id) << 32) | static_cast(id.id); + + return compoundId; + } + + static constexpr CompoundBasicId create(long long idNumber) + { + CompoundBasicId id; + id.id = idNumber; + + return id; + } + + constexpr MainId mainId() const { return MainId::create(id); } + + constexpr ContextId contextId() const { return ContextId::create(id >> 32); } + + friend constexpr bool compareInvalidAreTrue(CompoundBasicId first, CompoundBasicId second) + { + return first.id, second.id; + } + + friend constexpr bool operator==(CompoundBasicId first, CompoundBasicId second) + { + return first.id == second.id; + } + + friend constexpr bool operator!=(CompoundBasicId first, CompoundBasicId second) + { + return !(first == second); + } + + friend constexpr bool operator<(CompoundBasicId first, CompoundBasicId second) + { + return first.id < second.id; + } + + friend constexpr bool operator>(CompoundBasicId first, CompoundBasicId second) + { + return first.id > second.id; + } + + friend constexpr bool operator<=(CompoundBasicId first, CompoundBasicId second) + { + return first.id <= second.id; + } + + friend constexpr bool operator>=(CompoundBasicId first, CompoundBasicId second) + { + return first.id >= second.id; + } + + friend constexpr long long operator-(CompoundBasicId first, CompoundBasicId second) + { + return first.id - second.id; + } + + constexpr bool isValid() const { return id != 0; } + + constexpr bool isNull() const { return id == 0; } + + explicit operator bool() const { return isValid(); } + + long long internalId() const { return id; } + + explicit operator std::size_t() const { return static_cast(id | 0xFFFFFFFFULL); } + + template + friend void convertToString(String &string, CompoundBasicId id) + { + convertToString(string, id.id); + convertToString(string, id.contextId); + } + + friend bool compareId(CompoundBasicId first, CompoundBasicId second) + { + return first.id == second.id; + } + +protected: + long long id = 0; +}; + template auto toIntegers(const Container &container) { diff --git a/src/libs/sqlite/sqliteindex.h b/src/libs/sqlite/sqliteindex.h index 7c7a8dbb2ba..00a20b18fc2 100644 --- a/src/libs/sqlite/sqliteindex.h +++ b/src/libs/sqlite/sqliteindex.h @@ -8,8 +8,12 @@ #include "sqliteexception.h" +#include + #include +#include + namespace Sqlite { enum class IndexType @@ -90,6 +94,7 @@ private: Utils::SmallString m_condition; }; -using SqliteIndices = std::vector; +using SqliteIndices = QVarLengthArray; +using StableReferenceSqliteIndices = std::list; } // diff --git a/src/libs/sqlite/sqlitetable.h b/src/libs/sqlite/sqlitetable.h index 38355c7f67b..d9a6db88373 100644 --- a/src/libs/sqlite/sqlitetable.h +++ b/src/libs/sqlite/sqlitetable.h @@ -19,13 +19,10 @@ class BasicTable public: using Column = ::Sqlite::BasicColumn; using ColumnConstReferences = ::Sqlite::BasicColumnConstReferences; - using Columns = ::Sqlite::BasicColumns; + using Columns = ::Sqlite::StableReferenceBasicColumns; + using Indices = StableReferenceSqliteIndices; - BasicTable(std::size_t reserve = 10) - { - m_sqliteColumns.reserve(reserve); - m_sqliteIndices.reserve(reserve); - } + BasicTable([[maybe_unused]] std::size_t reserve = 10) {} void setName(Utils::SmallStringView name) { m_tableName = name; } @@ -107,7 +104,6 @@ public: void addPrimaryKeyContraint(const BasicColumnConstReferences &columns) { Utils::SmallStringVector columnNames; - columnNames.reserve(columns.size()); for (const auto &column : columns) columnNames.emplace_back(column.name); @@ -145,7 +141,7 @@ public: { CreateTableSqlStatementBuilder builder; - builder.setTableName(m_tableName.clone()); + builder.setTableName(m_tableName); builder.setUseWithoutRowId(m_withoutRowId); builder.setUseIfNotExists(m_useIfNotExists); builder.setUseTemporaryTable(m_useTemporaryTable); @@ -199,7 +195,7 @@ private: private: Utils::SmallString m_tableName; Columns m_sqliteColumns; - SqliteIndices m_sqliteIndices; + Indices m_sqliteIndices; TableConstraints m_tableConstraints; bool m_withoutRowId = false; bool m_useIfNotExists = false; diff --git a/src/libs/sqlite/sqlstatementbuilder.cpp b/src/libs/sqlite/sqlstatementbuilder.cpp index e756b460c75..243fb6460af 100644 --- a/src/libs/sqlite/sqlstatementbuilder.cpp +++ b/src/libs/sqlite/sqlstatementbuilder.cpp @@ -23,7 +23,7 @@ void SqlStatementBuilder::bindEmptyText(Utils::SmallString &&name) changeBinding(std::move(name), {}); } -void SqlStatementBuilder::bind(Utils::SmallString &&name, Utils::SmallString &&text) +void SqlStatementBuilder::bind(Utils::SmallStringView name, Utils::SmallStringView text) { clearSqlStatement(); checkBindingTextIsNotEmpty(text); @@ -31,7 +31,7 @@ void SqlStatementBuilder::bind(Utils::SmallString &&name, Utils::SmallString &&t changeBinding(std::move(name), std::move(text)); } -void SqlStatementBuilder::bind(Utils::SmallString &&name, const Utils::SmallStringVector &textVector) +void SqlStatementBuilder::bind(Utils::SmallStringView name, const Utils::SmallStringVector &textVector) { clearSqlStatement(); checkBindingTextVectorIsNotEmpty(textVector); @@ -39,7 +39,7 @@ void SqlStatementBuilder::bind(Utils::SmallString &&name, const Utils::SmallStri changeBinding(std::move(name), textVector.join(", ")); } -void SqlStatementBuilder::bind(Utils::SmallString &&name, int value) +void SqlStatementBuilder::bind(Utils::SmallStringView name, int value) { clearSqlStatement(); checkIfPlaceHolderExists(name); @@ -60,7 +60,8 @@ Utils::SmallStringVector integerVectorToStringVector(const std::vector &int return stringVector; } } -void SqlStatementBuilder::bind(Utils::SmallString &&name, const std::vector &integerVector) + +void SqlStatementBuilder::bind(Utils::SmallStringView name, const std::vector &integerVector) { clearSqlStatement(); checkBindingIntegerVectorIsNotEmpty(integerVector); diff --git a/src/libs/sqlite/sqlstatementbuilder.h b/src/libs/sqlite/sqlstatementbuilder.h index 3e202572c9b..6d496ce1342 100644 --- a/src/libs/sqlite/sqlstatementbuilder.h +++ b/src/libs/sqlite/sqlstatementbuilder.h @@ -19,10 +19,10 @@ public: SqlStatementBuilder(Utils::SmallStringView m_sqlTemplate); void bindEmptyText(Utils::SmallString &&name); - void bind(Utils::SmallString &&name, Utils::SmallString &&text); - void bind(Utils::SmallString &&name, const Utils::SmallStringVector &textVector); - void bind(Utils::SmallString &&name, int value); - void bind(Utils::SmallString &&name, const std::vector &integerVector); + void bind(Utils::SmallStringView name, Utils::SmallStringView text); + void bind(Utils::SmallStringView name, const Utils::SmallStringVector &textVector); + void bind(Utils::SmallStringView name, int value); + void bind(Utils::SmallStringView name, const std::vector &integerVector); void bindWithInsertTemplateParameters(Utils::SmallString &&name, const Utils::SmallStringVector &columns); void bindWithUpdateTemplateParameters(Utils::SmallString &&name, @@ -56,8 +56,8 @@ protected: Utils::SmallString sqlTemplate); private: - Utils::BasicSmallString<510> m_sqlTemplate; - mutable Utils::BasicSmallString<510> m_sqlStatement; + Utils::BasicSmallString<496> m_sqlTemplate; + mutable Utils::BasicSmallString<496> m_sqlStatement; mutable std::vector m_bindings; }; diff --git a/src/libs/sqlite/tableconstraints.h b/src/libs/sqlite/tableconstraints.h index f02ca9282f3..6385f5b6e63 100644 --- a/src/libs/sqlite/tableconstraints.h +++ b/src/libs/sqlite/tableconstraints.h @@ -8,6 +8,8 @@ #include +#include + #include namespace Sqlite { @@ -23,6 +25,6 @@ public: }; using TableConstraint = std::variant; -using TableConstraints = std::vector; +using TableConstraints = QVarLengthArray; } // namespace Sqlite diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index 849316c9a93..f173f9844a5 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -457,6 +457,30 @@ bool contains(const C &container, R S::*member) return anyOf(container, std::mem_fn(member)); } +template +[[nodiscard]] bool contains(const T (&array)[Size], const V &value) +{ + auto begin = std::begin(array); + auto end = std::end(array); + + auto found = std::find(begin, end, value); + + return found != end; +} + +////////////////// +// containsInSorted +///////////////// + +template +[[nodiscard]] bool containsInSorted(const C &container, const V &value) +{ + auto begin = std::begin(container); + auto end = std::end(container); + + return std::binary_search(begin, end, value); +} + ////////////////// // findOr ///////////////// diff --git a/src/libs/utils/appmainwindow.h b/src/libs/utils/appmainwindow.h index 0f5b2469bfa..218c07d5901 100644 --- a/src/libs/utils/appmainwindow.h +++ b/src/libs/utils/appmainwindow.h @@ -15,6 +15,8 @@ class QTCREATOR_UTILS_EXPORT AppMainWindow : public QMainWindow public: AppMainWindow(); + QMenu *createPopupMenu() override { return nullptr; } + public slots: void raiseWindow(); diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h index e8c3d74b926..f475186c486 100644 --- a/src/libs/utils/smallstring.h +++ b/src/libs/utils/smallstring.h @@ -16,14 +16,8 @@ #include #include -#include -#include -#include -#include -#include #include #include -#include #include #include #include @@ -45,9 +39,10 @@ public: using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; using size_type = std::size_t; + static constexpr size_type Capacity = Size; static_assert(Size < 64 ? sizeof(Internal::StringDataLayout) == Size + 1 - : sizeof(Internal::StringDataLayout) == Size + 2, + : sizeof(Internal::StringDataLayout) == Size + 16, "Size is wrong"); BasicSmallString() noexcept = default; @@ -63,16 +58,8 @@ public: {} BasicSmallString(const char *string, size_type size, size_type capacity) noexcept - { - if (Q_LIKELY(capacity <= shortStringCapacity())) { - m_data.control = Internal::ControlBlock(size, false, false); - std::char_traits::copy(m_data.shortString, string, size); - } else { - auto pointer = Memory::allocate(capacity); - std::char_traits::copy(pointer, string, size); - initializeLongString(pointer, size, capacity); - } - } + : m_data{string, size, capacity} + {} explicit BasicSmallString(SmallStringView stringView) noexcept : BasicSmallString(stringView.data(), stringView.size(), stringView.size()) @@ -126,7 +113,7 @@ public: ~BasicSmallString() noexcept { if (Q_UNLIKELY(hasAllocatedMemory())) - Memory::deallocate(m_data.reference.pointer); + Memory::deallocate(m_data.data()); } BasicSmallString(const BasicSmallString &other) noexcept @@ -170,17 +157,6 @@ public: } BasicSmallString take() noexcept { return std::move(*this); } - BasicSmallString clone() const noexcept - { - BasicSmallString clonedString(m_data); - - if (Q_UNLIKELY(hasAllocatedMemory())) - new (&clonedString) BasicSmallString{m_data.reference.pointer, - m_data.reference.size, - m_data.reference.capacity}; - - return clonedString; - } friend void swap(BasicSmallString &first, BasicSmallString &second) noexcept { @@ -227,8 +203,8 @@ public: { if (fitsNotInCapacity(newCapacity)) { if (Q_UNLIKELY(hasAllocatedMemory())) { - m_data.reference.pointer = Memory::reallocate(m_data.reference.pointer, newCapacity); - m_data.reference.capacity = newCapacity; + m_data.setPointer(Memory::reallocate(m_data.data(), newCapacity)); + m_data.setAllocatedCapacity(newCapacity); } else { auto oldSize = size(); new (this) BasicSmallString{data(), oldSize, std::max(newCapacity, oldSize)}; @@ -250,15 +226,9 @@ public: m_data = Internal::StringDataLayout(); } - char *data() noexcept - { - return Q_LIKELY(isShortString()) ? m_data.shortString : m_data.reference.pointer; - } + char *data() noexcept { return m_data.data(); } - const char *data() const noexcept - { - return Q_LIKELY(isShortString()) ? m_data.shortString : m_data.reference.pointer; - } + const char *data() const noexcept { return m_data.data(); } iterator begin() noexcept { @@ -385,21 +355,9 @@ public: return at(size() - 1) == character; } - size_type size() const noexcept - { - if (!isShortString()) - return m_data.reference.size; + size_type size() const noexcept { return m_data.size(); } - return m_data.control.shortStringSize(); - } - - size_type capacity() const noexcept - { - if (!isShortString()) - return m_data.reference.capacity; - - return shortStringCapacity(); - } + size_type capacity() const noexcept { return m_data.capacity(); } bool isEmpty() const noexcept { @@ -505,9 +463,11 @@ public: reserve(optimalCapacity(newSize)); - std::memcpy(data() + oldSize, temporaryArray, newAppendedStringSize); + auto begin = data(); - newEnd = data() + newSize; + std::memcpy(begin + oldSize, temporaryArray, newAppendedStringSize); + + newEnd = begin + newSize; } setSize(newEnd - data()); } @@ -606,11 +566,6 @@ public: return size; } - constexpr size_type shortStringSize() const noexcept - { - return m_data.control.shortStringSize(); - } - static BasicSmallString join(std::initializer_list list, Utils::SmallStringView separator) noexcept { @@ -705,19 +660,33 @@ public: return operator+(SmallStringView(first), second); } -unittest_public: - constexpr - bool isShortString() const noexcept + size_type count(SmallStringView text) const noexcept { - return m_data.control.isShortString(); + auto found = begin(); + + size_type count = 0; + + while (true) { + found = std::search(found, end(), text.begin(), text.end()); + if (found == end()) + break; + + ++count; + found += text.size(); + } + + return count; } - constexpr - bool isReadOnlyReference() const noexcept + size_type count(char character) const noexcept { return std::count(begin(), end(), character); } + + unittest_public : constexpr bool isShortString() const noexcept { - return m_data.control.isReadOnlyReference(); + return m_data.isShortString(); } + constexpr bool isReadOnlyReference() const noexcept { return m_data.isReadOnlyReference(); } + constexpr bool hasAllocatedMemory() const noexcept { @@ -726,10 +695,7 @@ unittest_public: bool fitsNotInCapacity(size_type capacity) const noexcept { - if (isShortString()) - return capacity > shortStringCapacity(); - - return capacity > m_data.reference.capacity; + return capacity > m_data.capacity(); } static size_type optimalHeapCapacity(const size_type size) noexcept @@ -741,27 +707,6 @@ unittest_public: return (cacheLineBlocks + 1) * cacheLineSize; } - size_type countOccurrence(SmallStringView text) noexcept - { - auto found = begin(); - - size_type count = 0; - - while (true) { - found = std::search(found, - end(), - text.begin(), - text.end()); - if (found == end()) - break; - - ++count; - found += text.size(); - } - - return count; - } - private: BasicSmallString(const Internal::StringDataLayout &data) noexcept : m_data(data) @@ -788,13 +733,6 @@ private: } } - constexpr void initializeLongString(char *pointer, size_type size, size_type capacity) noexcept - { - m_data.control = Internal::ControlBlock(0, false, true); - m_data.reference.pointer = pointer; - m_data.reference.size = size; - m_data.reference.capacity = capacity; - } char &at(size_type index) noexcept { return *(data() + index); } @@ -910,7 +848,7 @@ private: size_type startIndex = 0; size_type replacementTextSizeDifference = toText.size() - fromText.size(); - size_type occurrences = countOccurrence(fromText); + size_type occurrences = count(fromText); size_type newSize = size() + (replacementTextSizeDifference * occurrences); if (occurrences > 0) { @@ -920,13 +858,7 @@ private: } } - void setSize(size_type size) noexcept - { - if (isShortString()) - m_data.control.setShortStringSize(size); - else - m_data.reference.size = size; - } + void setSize(size_type size) noexcept { m_data.setSize(size); } private: Internal::StringDataLayout m_data; @@ -960,7 +892,7 @@ Type clone(const Type &vector) } using SmallString = BasicSmallString<31>; -using PathString = BasicSmallString<190>; +using PathString = BasicSmallString<176>; inline SmallString operator+(SmallStringView first, SmallStringView second) noexcept { @@ -973,6 +905,17 @@ inline SmallString operator+(SmallStringView first, SmallStringView second) noex return text; } +inline SmallString operator+(SmallStringView first, char second) noexcept +{ + SmallString text; + text.reserve(first.size() + 1); + + text.append(first); + text.append(second); + + return text; +} + template inline SmallString operator+(SmallStringView first, const char (&second)[Size]) noexcept { @@ -987,3 +930,5 @@ SmallString operator+(const char(&first)[Size], SmallStringView second) } } // namespace Utils + +Q_DECLARE_METATYPE(Utils::SmallString) diff --git a/src/libs/utils/smallstringfwd.h b/src/libs/utils/smallstringfwd.h index 5e9ef7e66ba..5660bf92d31 100644 --- a/src/libs/utils/smallstringfwd.h +++ b/src/libs/utils/smallstringfwd.h @@ -17,6 +17,6 @@ class SmallStringView; template class BasicSmallString; using SmallString = BasicSmallString<31>; -using PathString = BasicSmallString<190>; +using PathString = BasicSmallString<176>; } // namespace Utils diff --git a/src/libs/utils/smallstringlayout.h b/src/libs/utils/smallstringlayout.h index 0d87bd101ba..6e33e3010c4 100644 --- a/src/libs/utils/smallstringlayout.h +++ b/src/libs/utils/smallstringlayout.h @@ -3,12 +3,19 @@ #pragma once +#include "smallstringmemory.h" + #include #include +#include +#include +#include #include +#include #include #include +#include #include QT_WARNING_PUSH @@ -110,7 +117,27 @@ struct alignas(16) StringDataLayout } } - constexpr static size_type shortStringCapacity() noexcept + StringDataLayout(const char *string, size_type size, size_type capacity) noexcept + { + if (Q_LIKELY(capacity <= shortStringCapacity())) { + control = Internal::ControlBlock(size, false, false); + std::char_traits::copy(shortString, string, size); + } else { + auto pointer = Memory::allocate(capacity); + std::char_traits::copy(pointer, string, size); + initializeLongString(pointer, size, capacity); + } + } + + constexpr void initializeLongString(char *pointer, size_type size, size_type capacity) noexcept + { + control = Internal::ControlBlock(0, false, true); + reference.pointer = pointer; + reference.size = size; + reference.capacity = capacity; + } + + static constexpr size_type shortStringCapacity() noexcept { return MaximumShortStringDataAreaSize; } @@ -126,6 +153,45 @@ struct alignas(16) StringDataLayout #endif } + void setSize(size_type size) noexcept + { + if (isShortString()) + control.setShortStringSize(size); + else + reference.size = size; + } + + size_type size() const noexcept + { + if (!control.isShortString()) + return reference.size; + + return control.shortStringSize(); + } + + bool isShortString() const noexcept { return control.isShortString(); } + + size_type capacity() const noexcept + { + if (!isShortString()) + return reference.capacity; + + return shortStringCapacity(); + } + + constexpr bool isReadOnlyReference() const noexcept { return control.isReadOnlyReference(); } + + char *data() noexcept { return Q_LIKELY(isShortString()) ? shortString : reference.pointer; } + + const char *data() const noexcept + { + return Q_LIKELY(isShortString()) ? shortString : reference.pointer; + } + + void setPointer(char *p) noexcept { reference.pointer = p; } + + void setAllocatedCapacity(size_type capacity) noexcept { reference.capacity = capacity; } + union { struct { @@ -145,45 +211,46 @@ struct alignas(16) StringDataLayout= 32>> { static_assert(MaximumShortStringDataAreaSize > 31, "Size must be greater than 31 bytes!"); - static_assert(MaximumShortStringDataAreaSize < 64 - ? ((MaximumShortStringDataAreaSize + 1) % 16) == 0 - : ((MaximumShortStringDataAreaSize + 2) % 16) == 0, - "Size + 1 must be dividable by 16 if under 64 and Size + 2 must be dividable by " - "16 if over 64!"); + static_assert(((MaximumShortStringDataAreaSize + 16) % 16) == 0, + "Size + 16 must be dividable by 16!"); constexpr StringDataLayout() noexcept { reset(); } constexpr StringDataLayout(const char *string, size_type size) noexcept - : controlReference{0, true, true} - , reference{{string}, size, 0} + : constPointer{string} + , size_{static_cast(size)} + , capacity_{0} {} template constexpr StringDataLayout(const char (&string)[Size]) noexcept { - constexpr auto size = Size - 1; + constexpr size_type size = Size - 1; + size_ = size; if constexpr (size <= MaximumShortStringDataAreaSize) { - control = {size, false, false}; + pointer = buffer; + capacity_ = MaximumShortStringDataAreaSize; for (size_type i = 0; i < size; ++i) - shortString[i] = string[i]; + buffer[i] = string[i]; #if defined(__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811L if (std::is_constant_evaluated()) { for (size_type i = size; i < MaximumShortStringDataAreaSize; ++i) - shortString[i] = 0; + buffer[i] = 0; } #endif } else { - control = {0, true, true}; - reference = {{string}, size, 0}; + constPointer = string; + capacity_ = 0; } } void copyHere(const StringDataLayout &other) noexcept { - constexpr auto controlBlockSize = sizeof(ControlBlock); - auto shortStringLayoutSize = other.control.stringSize() + controlBlockSize; - constexpr auto referenceLayoutSize = sizeof(ReferenceLayout); - std::memcpy(this, &other, std::max(shortStringLayoutSize, referenceLayoutSize)); + auto isShortString = other.isShortString(); + auto shortStringSize = isShortString ? other.size() : 0; + auto areaSize = 8 + shortStringSize; + pointer = isShortString ? buffer : other.pointer; + std::memcpy(&size_, &other.size_, areaSize); } StringDataLayout(const StringDataLayout &other) noexcept { copyHere(other); } @@ -195,6 +262,18 @@ struct alignas(16) StringDataLayout(size)} + , capacity_{static_cast(std::max(capacity, MaximumShortStringDataAreaSize))} + { + if (Q_LIKELY(capacity <= shortStringCapacity())) { + std::char_traits::copy(buffer, string, size); + pointer = buffer; + } else { + pointer = Memory::allocate(capacity); + std::char_traits::copy(pointer, string, size); + } + } constexpr static size_type shortStringCapacity() noexcept { return MaximumShortStringDataAreaSize; @@ -202,27 +281,42 @@ struct alignas(16) StringDataLayout(); -#if defined(__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811L - if (std::is_constant_evaluated()) { - for (size_type i = 0; i < MaximumShortStringDataAreaSize; ++i) - shortString[i] = 0; - } -#endif + pointer = buffer; + size_ = 0; + capacity_ = MaximumShortStringDataAreaSize; } + void setSize(size_type size) noexcept { size_ = static_cast(size); } + + size_type size() const noexcept { return size_; } + + bool isShortString() const noexcept { return pointer == buffer; } + + size_type capacity() const noexcept { return capacity_; } + + constexpr bool isReadOnlyReference() const noexcept { return capacity_ == 0; } + + char *data() noexcept { return pointer; } + + const char *data() const noexcept { return constPointer; } + + void setPointer(char *p) noexcept { pointer = p; } + + void setAllocatedCapacity(size_type capacity) noexcept + { + capacity_ = static_cast(capacity); + } + + constexpr size_type shortStringSize() const noexcept { return size_; } + union { - struct - { - ControlBlock control; - char shortString[MaximumShortStringDataAreaSize]; - }; - struct - { - ControlBlock controlReference; - ReferenceLayout reference; - }; + char *pointer; + const char *constPointer; }; + + int size_; + int capacity_; + char buffer[MaximumShortStringDataAreaSize]; }; } // namespace Internal diff --git a/src/libs/utils/smallstringvector.h b/src/libs/utils/smallstringvector.h index 909acec5db3..186cb0a4278 100644 --- a/src/libs/utils/smallstringvector.h +++ b/src/libs/utils/smallstringvector.h @@ -128,6 +128,6 @@ private: using SmallStringVector = BasicSmallStringVector>; -using PathStringVector = BasicSmallStringVector>; +using PathStringVector = BasicSmallStringVector>; using StringViewVector = BasicSmallStringVector; } // namespace Utils; diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index c78d8b95c26..02076d0071e 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -289,6 +289,7 @@ public: MainWindow *m_mainwindow = nullptr; QTimer m_trimTimer; + QString m_prependAboutInformation; QStringList m_aboutInformation; Context m_highPrioAdditionalContexts; Context m_lowPrioAdditionalContexts{Constants::C_GLOBAL}; @@ -1158,7 +1159,9 @@ void ICore::saveSettings(SaveSettingsReason reason) */ QStringList ICore::additionalAboutInformation() { - return d->m_aboutInformation; + auto aboutInformation = d->m_aboutInformation; + aboutInformation.prepend(d->m_prependAboutInformation); + return aboutInformation; } /*! @@ -1169,6 +1172,14 @@ void ICore::clearAboutInformation() d->m_aboutInformation.clear(); } +/*! + \internal +*/ +void ICore::setPrependAboutInformation(const QString &line) +{ + d->m_prependAboutInformation = line; +} + /*! \internal */ diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index 9567e7c8d7c..dee5be74b40 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -142,6 +142,7 @@ public: static Utils::FilePath pathRelativeToActiveProject(const Utils::FilePath &path); static QStringList additionalAboutInformation(); static void clearAboutInformation(); + static void setPrependAboutInformation(const QString &line); static void appendAboutInformation(const QString &line); static QString aboutInformationCompact(); static QString aboutInformationHtml(); diff --git a/src/plugins/effectcomposer/effectcomposermodel.cpp b/src/plugins/effectcomposer/effectcomposermodel.cpp index 43efefe51d6..41ad13b2485 100644 --- a/src/plugins/effectcomposer/effectcomposermodel.cpp +++ b/src/plugins/effectcomposer/effectcomposermodel.cpp @@ -846,7 +846,8 @@ R"( QString parentChanged{ R"( - onParentChanged: { + function setupParentLayer() + { if (_oldParent && _oldParent !== parent) { _oldParent.layer.enabled = false _oldParent.layer.effect = null @@ -860,26 +861,21 @@ R"( if (visible) { parent.layer.enabled = true parent.layer.effect = effectComponent + %6 + %4%1%5%3 + } else { + parent.layer.enabled = false + parent.layer.effect = null + %8 + %4%2 } - %6 - %4%1%5%3 + parent.update() } } - onVisibleChanged: { - if (visible) { - parent.layer.enabled = true - parent.layer.effect = effectComponent - %6 - %4%1%5%3 - } else { - parent.layer.enabled = false - parent.layer.effect = null - %8 - %4%2 - } - parent.update() - } + onParentChanged: setupParentLayer() + + onVisibleChanged: setupParentLayer() )" }; diff --git a/src/plugins/effectcomposer/effectcomposerview.cpp b/src/plugins/effectcomposer/effectcomposerview.cpp index 7e854ac1e0b..552306141a0 100644 --- a/src/plugins/effectcomposer/effectcomposerview.cpp +++ b/src/plugins/effectcomposer/effectcomposerview.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -16,6 +17,8 @@ #include +#include + namespace EffectComposer { EffectComposerView::EffectComposerView(QmlDesigner::ExternalDependenciesInterface &externalDependencies) @@ -106,8 +109,10 @@ QmlDesigner::WidgetInfo EffectComposerView::widgetInfo() }); } - return createWidgetInfo(m_widget.data(), "EffectComposer", - QmlDesigner::WidgetInfo::LeftPane, 0, tr("Effect Composer [beta]")); + return createWidgetInfo(m_widget.data(), + "EffectComposer", + QmlDesigner::WidgetInfo::LeftPane, + tr("Effect Composer [beta]")); } void EffectComposerView::customNotification([[maybe_unused]] const AbstractView *view, @@ -167,4 +172,48 @@ void EffectComposerView::selectedNodesChanged(const QListeffectComposerModel()->setHasValidTarget(hasValidTarget); } +void EffectComposerView::nodeAboutToBeRemoved(const QmlDesigner::ModelNode &removedNode) +{ + QList nodes = removedNode.allSubModelNodesAndThisNode(); + bool effectRemoved = false; + for (const QmlDesigner::ModelNode &node : nodes) { + QmlDesigner::QmlItemNode qmlNode(node); + if (qmlNode.isEffectItem()) { + effectRemoved = true; + break; + } + } + if (effectRemoved) + QTimer::singleShot(0, this, &EffectComposerView::removeUnusedEffectImports); +} + +void EffectComposerView::removeUnusedEffectImports() +{ + QTC_ASSERT(model(), return); + + const QString effectPrefix = m_componentUtils.composedEffectsTypePrefix(); + + const QmlDesigner::Imports &imports = model()->imports(); + QHash effectImports; + for (const QmlDesigner::Import &import : imports) { + if (import.url().startsWith(effectPrefix)) { + QString type = import.url().split('.').last(); + effectImports.insert(type, import); + } + } + + const QList allNodes = allModelNodes(); + for (const QmlDesigner::ModelNode &node : allNodes) { + if (QmlDesigner::QmlItemNode(node).isEffectItem()) + effectImports.remove(node.simplifiedTypeName()); + } + + if (!effectImports.isEmpty()) { + QmlDesigner::Imports removeImports; + for (const QmlDesigner::Import &import : effectImports) + removeImports.append(import); + model()->changeImports({}, removeImports); + } +} + } // namespace EffectComposer diff --git a/src/plugins/effectcomposer/effectcomposerview.h b/src/plugins/effectcomposer/effectcomposerview.h index ff1cc616904..18f2da4312e 100644 --- a/src/plugins/effectcomposer/effectcomposerview.h +++ b/src/plugins/effectcomposer/effectcomposerview.h @@ -29,10 +29,12 @@ public: void modelAboutToBeDetached(QmlDesigner::Model *model) override; void selectedNodesChanged(const QList &selectedNodeList, const QList &lastSelectedNodeList) override; + void nodeAboutToBeRemoved(const QmlDesigner::ModelNode &removedNode) override; private: void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data) override; + void removeUnusedEffectImports(); QPointer m_widget; QString m_currProjectPath; diff --git a/src/plugins/insight/insightview.cpp b/src/plugins/insight/insightview.cpp index a06cb5e8736..28101dc94e3 100644 --- a/src/plugins/insight/insightview.cpp +++ b/src/plugins/insight/insightview.cpp @@ -45,7 +45,6 @@ WidgetInfo InsightView::widgetInfo() return createWidgetInfo(m_insightWidget.data(), "QtInsight", WidgetInfo::RightPane, - 0, tr("Qt Insight")); } diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 36bba76777f..c63acc52d05 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -8,13 +8,13 @@ if (APPLE) set(QmlDesignerPluginInstallPrefix "${IDE_PLUGIN_PATH}/QmlDesigner") endif() - set(BUILD_NOT_DESIGNSTUDIO NOT ${BUILD_NOT_DESIGNSTUDIO}) option(QTC_USE_QML_DESIGNER_LITE "Use Qml Designer Lite" ${BUILD_NOT_DESIGNSTUDIO}) add_feature_info("Qml Designer Lite" ${QTC_USE_QML_DESIGNER_LITE} "") option(USE_PROJECTSTORAGE "Use ProjectStorage" ${QTC_USE_QML_DESIGNER_LITE}) + env_with_default("QTC_ENABLE_PROJECT_STORAGE_TRACING" ENV_QTC_ENABLE_PROJECT_STORAGE_TRACING OFF) option(ENABLE_PROJECT_STORAGE_TRACING "Enable sqlite tracing" ${ENV_QTC_ENABLE_PROJECT_STORAGE_TRACING}) add_feature_info("Sqlite tracing" ${ENABLE_PROJECT_STORAGE_TRACING} "") @@ -34,9 +34,10 @@ add_feature_info("Meta info tracing" ${ENABLE_METAINFO_TRACING} "") add_qtc_library(QmlDesignerUtils STATIC DEPENDS Qt::Gui Utils Qt::QmlPrivate - PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/utils SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/utils + PUBLIC_COMPILE_OPTIONS + $<$:-Wno-unneeded-internal-declaration> SOURCES asset.cpp asset.h designeralgorithm.h @@ -47,16 +48,14 @@ add_qtc_library(QmlDesignerUtils STATIC ktximage.cpp ktximage.h imageutils.cpp imageutils.h qmldesignerutils_global.h + version.cpp version.h ) -if (TARGET QmlDesignerUtils) - target_compile_options(QmlDesignerUtils PUBLIC $<$:-Wno-error=maybe-uninitialized>) - target_compile_options(QmlDesignerUtils PUBLIC $<$:-Wno-unneeded-internal-declaration>) -endif() - extend_qtc_library(QmlDesignerUtils CONDITION ENABLE_COMPILE_WARNING_AS_ERROR PROPERTIES COMPILE_WARNING_AS_ERROR ON + PUBLIC_COMPILE_OPTIONS + $<$:-Wno-error=maybe-uninitialized> ) add_qtc_library(QmlDesignerCore STATIC @@ -95,10 +94,17 @@ add_qtc_library(QmlDesignerCore STATIC PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore ${CMAKE_CURRENT_LIST_DIR}/designercore/include - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore +) + +extend_qtc_library(QmlDesignerCore + PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/designercoreutils + SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/designercoreutils SOURCES - rewritertransaction.cpp rewritertransaction.h generatedcomponentutils.cpp generatedcomponentutils.h + modelmerger.cpp modelmerger.h + modelutils.cpp modelutils.h + skipiterator.h + stylesheetmerger.cpp stylesheetmerger.h uniquename.cpp uniquename.h ) @@ -117,10 +123,11 @@ extend_qtc_library(QmlDesignerCore extend_qtc_library(QmlDesignerCore CONDITION ENABLE_COMPILE_WARNING_AS_ERROR PROPERTIES COMPILE_WARNING_AS_ERROR ON + PUBLIC_COMPILE_OPTIONS $<$:-Wno-error=maybe-uninitialized> ) extend_qtc_library(QmlDesignerCore - CONDITION Qt6_VERSION VERSION_GREATER_EQUAL 6.5.0 AND Qt6_VERSION VERSION_LESS 6.6.0 + CONDITION IS_SUPPORTED_PROJECTSTORAGE_QT PUBLIC_DEFINES QDS_BUILD_QMLPARSER ) extend_qtc_library(QmlDesignerCore @@ -279,9 +286,7 @@ extend_qtc_library(QmlDesignerCore invalidslideindexexception.h mathutils.h modelfwd.h - modelmerger.h modelnode.h - modelnodepositionstorage.h module.h nodeabstractproperty.h nodeinstance.h @@ -305,9 +310,9 @@ extend_qtc_library(QmlDesignerCore qmltimelinekeyframegroup.h removebasestateexception.h rewritingexception.h + rewritertransaction.h signalhandlerproperty.h stringutils.h - stylesheetmerger.h synchronousimagecache.h variantproperty.h ) @@ -362,8 +367,8 @@ extend_qtc_library(QmlDesignerCore abstractview.cpp anchorline.cpp annotation.cpp + auxiliarypropertystorageview.cpp auxiliarypropertystorageview.h bindingproperty.cpp - componenttextmodifier.cpp documentmessage.cpp import.cpp internalbindingproperty.cpp @@ -384,25 +389,46 @@ extend_qtc_library(QmlDesignerCore internalvariantproperty.h model.cpp model_p.h - modelmerger.cpp modelnode.cpp - modelnodepositionrecalculator.cpp - modelnodepositionrecalculator.h - modelnodepositionstorage.cpp modelresourcemanagementinterface.h modelresourcemanagementfwd.h modelresourcemanagement.cpp modelresourcemanagement.h - modeltotextmerger.cpp - modeltotextmerger.h - modelutils.cpp - modelutils.h nodeabstractproperty.cpp nodelistproperty.cpp nodeproperty.cpp + signalhandlerproperty.cpp + variantproperty.cpp +) + +extend_qtc_library(QmlDesignerCore + INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/rewriter + SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/rewriter + SOURCES + componenttextmodifier.cpp + modelnodepositionrecalculator.cpp + modelnodepositionrecalculator.h + modelnodepositionstorage.cpp + modelnodepositionstorage.h + modeltotextmerger.cpp + modeltotextmerger.h plaintexteditmodifier.cpp propertycontainer.cpp propertynode.cpp propertyparser.cpp + rewriteaction.cpp + rewriteaction.h + rewriteactioncompressor.cpp + rewriteactioncompressor.h + rewritertransaction.cpp + rewriterview.cpp + textmodifier.cpp + texttomodelmerger.cpp + texttomodelmerger.h +) +extend_qtc_library(QmlDesignerCore + INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/qmltools + SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/qmltools + SOURCES qml3dnode.cpp qmlanchors.cpp qmlchangeset.cpp @@ -416,18 +442,6 @@ extend_qtc_library(QmlDesignerCore qmltimeline.cpp qmltimelinekeyframegroup.cpp qmlvisualnode.cpp - rewriteaction.cpp - rewriteaction.h - rewriteactioncompressor.cpp - rewriteactioncompressor.h - rewriterview.cpp - signalhandlerproperty.cpp - skipiterator.h - stylesheetmerger.cpp - textmodifier.cpp - texttomodelmerger.cpp - texttomodelmerger.h - variantproperty.cpp ) extend_qtc_library(QmlDesignerCore @@ -444,6 +458,7 @@ extend_qtc_library(QmlDesignerCore SOURCES_PREFIX designercore/projectstorage PUBLIC_INCLUDES designercore/projectstorage SOURCES_PROPERTIES SKIP_AUTOGEN ON + DEFINES QML_DOM_MSVC2019_COMPAT # can be removed for Qt 6.8 SOURCES commontypecache.h directorypathcompressor.h @@ -493,7 +508,7 @@ add_qtc_plugin(QmlDesigner PLUGIN_MANUAL_DEPENDS LicenseChecker ${IDE_VERSION} optional DEPENDS QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem - Qt::QuickWidgets Qt::CorePrivate Qt::Xml Qt::Svg QmlDesignerCore Sqlite + Qt::QuickWidgets Qt::CorePrivate Qt::Xml Qt::Svg QmlDesignerCore Sqlite Zip PUBLIC_DEPENDS QmlDesignerUtils QmlPuppetCommunication QmlDesignerBase DEFINES @@ -516,10 +531,12 @@ add_qtc_plugin(QmlDesigner ${CMAKE_CURRENT_LIST_DIR}/components/propertyeditor ${CMAKE_CURRENT_LIST_DIR}/components/stateseditor ${CMAKE_CURRENT_LIST_DIR}/components/texteditor + ${CMAKE_CURRENT_LIST_DIR}/components/designsystem PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/designercore #can not be a public dependency -> EXCLUDE_FROM_INSTALL in QmlDesignerCore ${CMAKE_CURRENT_LIST_DIR}/designercore/include #iwidgetplugin.h is used by other plugins + ${CMAKE_CURRENT_LIST_DIR}/designercore/designercoreutils SOURCES designmodewidget.cpp designmodewidget.h documentmanager.cpp documentmanager.h @@ -550,6 +567,7 @@ add_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner CONDITION ENABLE_COMPILE_WARNING_AS_ERROR PROPERTIES COMPILE_WARNING_AS_ERROR ON + PUBLIC_COMPILE_OPTIONS $<$:-Wno-error=maybe-uninitialized> ) function(get_and_add_as_subdirectory name repository git_tag build_dir source_dir source_subdir) @@ -659,9 +677,11 @@ extend_qtc_plugin(QmlDesigner edit3dwidget.cpp edit3dwidget.h edit3dcanvas.cpp edit3dcanvas.h edit3dactions.cpp edit3dactions.h + edit3dmaterialsaction.cpp edit3dmaterialsaction.h edit3dtoolbarmenu.cpp edit3dtoolbarmenu.h backgroundcolorselection.cpp backgroundcolorselection.h bakelights.cpp bakelights.h + indicatoractionwidget.cpp indicatoractionwidget.h snapconfiguration.cpp snapconfiguration.h cameraspeedconfiguration.cpp cameraspeedconfiguration.h bakelightsdatamodel.cpp bakelightsdatamodel.h @@ -813,10 +833,12 @@ extend_qtc_plugin(QmlDesigner propertyeditorvalue.cpp propertyeditorvalue.h propertyeditorview.cpp propertyeditorview.h propertyeditorwidget.cpp propertyeditorwidget.h + propertynamevalidator.cpp propertynamevalidator.h tooltip.cpp tooltip.h qmlanchorbindingproxy.cpp qmlanchorbindingproxy.h qmlmodelnodeproxy.cpp qmlmodelnodeproxy.h quick2propertyeditorview.cpp quick2propertyeditorview.h + propertyeditorutils.cpp propertyeditorutils.h ) extend_qtc_plugin(QmlDesigner @@ -836,6 +858,9 @@ extend_qtc_plugin(QmlDesigner contentlibraryeffectscategory.cpp contentlibraryeffectscategory.h contentlibraryeffectsmodel.cpp contentlibraryeffectsmodel.h contentlibraryusermodel.cpp contentlibraryusermodel.h + usercategory.cpp usercategory.h + useritemcategory.cpp useritemcategory.h + usertexturecategory.cpp usertexturecategory.h ) extend_qtc_plugin(QmlDesigner @@ -843,6 +868,7 @@ extend_qtc_plugin(QmlDesigner SOURCES materialeditorcontextobject.cpp materialeditorcontextobject.h materialeditordynamicpropertiesproxymodel.cpp materialeditordynamicpropertiesproxymodel.h + materialeditorimageprovider.cpp materialeditorimageprovider.h materialeditorqmlbackend.cpp materialeditorqmlbackend.h materialeditortransaction.cpp materialeditortransaction.h materialeditorview.cpp materialeditorview.h @@ -942,7 +968,7 @@ extend_qtc_plugin(QmlDesigner SOURCES_PREFIX designercore PUBLIC_INCLUDES designercore SOURCES - model/basetexteditmodifier.cpp + rewriter/basetexteditmodifier.cpp ) extend_qtc_plugin(QmlDesigner @@ -1149,6 +1175,14 @@ extend_qtc_plugin(QmlDesigner toolbarbackend.h ) +extend_qtc_plugin(QmlDesigner + SOURCES_PREFIX components/designsystem + SOURCES + dsconstants.h + dsthememanager.h dsthememanager.cpp + dsthemegroup.cpp dsthemegroup.h +) + add_qtc_plugin(assetexporterplugin PLUGIN_CLASS AssetExporterPlugin CONDITION TARGET QmlDesigner diff --git a/src/plugins/qmldesigner/assetexporterplugin/assetexporter.cpp b/src/plugins/qmldesigner/assetexporterplugin/assetexporter.cpp index 760ffdf622d..df938129c24 100644 --- a/src/plugins/qmldesigner/assetexporterplugin/assetexporter.cpp +++ b/src/plugins/qmldesigner/assetexporterplugin/assetexporter.cpp @@ -6,7 +6,7 @@ #include "exportnotification.h" #include -#include +#include #include #include #include diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp index 13b8beaeae9..ad474d2015e 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp @@ -63,7 +63,7 @@ WidgetInfo AssetsLibraryView::widgetInfo() this}; } - return createWidgetInfo(m_widget.data(), "Assets", WidgetInfo::LeftPane, 0, tr("Assets")); + return createWidgetInfo(m_widget.data(), "Assets", WidgetInfo::LeftPane, tr("Assets")); } void AssetsLibraryView::customNotification(const AbstractView * /*view*/, diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index c6cb77a7d0d..9b935917e3b 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -413,9 +413,13 @@ void AssetsLibraryWidget::handleExtFilesDrop(const QList &simpleFilePaths, targetDirPath, isDropOnRoot); if (result.status() == AddFilesResult::Failed) { - Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"), - tr("Could not add %1 to project.") - .arg(simpleFilePathStrings.join(' '))); + QWidget *w = Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"), + tr("Could not add %1 to project.") + .arg(simpleFilePathStrings.join(' '))); + // Avoid multiple modal dialogs open at the same time + auto mb = qobject_cast(w); + if (mb && !complexFilePathStrings.empty()) + mb->exec(); } } } @@ -609,6 +613,9 @@ void AssetsLibraryWidget::addResources(const QStringList &files, bool showDialog categoryFileNames.insert(category, fileName); } + QStringList unsupportedFiles; + QStringList failedOpsFiles; + for (const QString &category : categoryFileNames.uniqueKeys()) { QStringList fileNames = categoryFileNames.values(category); AddResourceOperation operation = categoryToOperation.value(category); @@ -617,9 +624,7 @@ void AssetsLibraryWidget::addResources(const QStringList &files, bool showDialog AddFilesResult result = operation(fileNames, document->fileName().parentDir().toString(), showDialog); if (result.status() == AddFilesResult::Failed) { - Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"), - tr("Could not add %1 to project.") - .arg(fileNames.join(' '))); + failedOpsFiles.append(fileNames); } else { if (!result.directory().isEmpty()) { emit directoryCreated(result.directory()); @@ -634,11 +639,24 @@ void AssetsLibraryWidget::addResources(const QStringList &files, bool showDialog } } } else { - Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"), - tr("Could not add %1 to project. Unsupported file format.") - .arg(fileNames.join(' '))); + unsupportedFiles.append(fileNames); } } + + if (!failedOpsFiles.isEmpty()) { + QWidget *w = Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"), + tr("Could not add %1 to project.") + .arg(failedOpsFiles.join(' '))); + // Avoid multiple modal dialogs open at the same time + auto mb = qobject_cast(w); + if (mb && !unsupportedFiles.isEmpty()) + mb->exec(); + } + if (!unsupportedFiles.isEmpty()) { + Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"), + tr("Could not add %1 to project. Unsupported file format.") + .arg(unsupportedFiles.join(' '))); + } } void AssetsLibraryWidget::addAssetsToContentLibrary(const QStringList &assetPaths) diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h index da7c5bf72eb..644a7227498 100644 --- a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h +++ b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h @@ -9,197 +9,284 @@ namespace QmlDesigner { namespace ComponentCoreConstants { -const char rootCategory[] = ""; +inline constexpr char rootCategory[] = ""; -const char selectionCategory[] = "Selection"; -const char connectionsCategory[] = "Connections"; -const char arrangeCategory[] = "Arrange"; -const char qmlPreviewCategory[] = "QmlPreview"; -const char editCategory[] = "Edit"; -const char anchorsCategory[] = "Anchors"; -const char positionerCategory[] = "Position"; -const char groupCategory[] = "Group"; -const char snappingCategory[] = "Snapping"; -const char layoutCategory[] = "Layout"; -const char flowCategory[] = "Flow"; -const char flowEffectCategory[] = "FlowEffect"; -const char flowConnectionCategory[] = "FlowConnection"; -const char stackedContainerCategory[] = "StackedContainer"; -const char genericToolBarCategory[] = "GenericToolBar"; -const char eventListCategory[] = "QmlEventList"; +inline constexpr char selectionCategory[] = "Selection"; +inline constexpr char connectionsCategory[] = "Connections"; +inline constexpr char arrangeCategory[] = "Arrange"; +inline constexpr char qmlPreviewCategory[] = "QmlPreview"; +inline constexpr char editCategory[] = "Edit"; +inline constexpr char anchorsCategory[] = "Anchors"; +inline constexpr char positionerCategory[] = "Position"; +inline constexpr char groupCategory[] = "Group"; +inline constexpr char snappingCategory[] = "Snapping"; +inline constexpr char layoutCategory[] = "Layout"; +inline constexpr char flowCategory[] = "Flow"; +inline constexpr char flowEffectCategory[] = "FlowEffect"; +inline constexpr char flowConnectionCategory[] = "FlowConnection"; +inline constexpr char stackedContainerCategory[] = "StackedContainer"; +inline constexpr char genericToolBarCategory[] = "GenericToolBar"; +inline constexpr char eventListCategory[] = "QmlEventList"; -const char toFrontCommandId[] = "ToFront"; -const char toBackCommandId[] = "ToBack"; -const char raiseCommandId[] = "Raise"; -const char lowerCommandId[] = "Lower"; -const char resetZCommandId[] = "ResetZ"; -const char reverseCommandId[] = "Reverse"; -const char resetSizeCommandId[] = "ResetSize"; -const char resetPositionCommandId[] = "ResetPosition"; -const char copyFormatCommandId[] = "CopyFormat"; -const char applyFormatCommandId[] = "ApplyFormat"; -const char visiblityCommandId[] = "ToggleVisiblity"; -const char anchorsFillCommandId[] = "AnchorsFill"; -const char anchorsResetCommandId[] = "AnchorsReset"; +inline constexpr char toFrontCommandId[] = "ToFront"; +inline constexpr char toBackCommandId[] = "ToBack"; +inline constexpr char raiseCommandId[] = "Raise"; +inline constexpr char lowerCommandId[] = "Lower"; +inline constexpr char resetZCommandId[] = "ResetZ"; +inline constexpr char reverseCommandId[] = "Reverse"; +inline constexpr char resetSizeCommandId[] = "ResetSize"; +inline constexpr char resetPositionCommandId[] = "ResetPosition"; +inline constexpr char copyFormatCommandId[] = "CopyFormat"; +inline constexpr char applyFormatCommandId[] = "ApplyFormat"; +inline constexpr char visiblityCommandId[] = "ToggleVisiblity"; +inline constexpr char anchorsFillCommandId[] = "AnchorsFill"; +inline constexpr char anchorsResetCommandId[] = "AnchorsReset"; -const char anchorParentTopAndBottomCommandId[] = "AnchorParentTopAndBottom"; -const char anchorParentLeftAndRightCommandId[] = "AnchorParentLeftAndRight"; -const char anchorParentTopCommandId[] = "AnchorParentTop"; -const char anchorParentRightCommandId[] = "AnchorParentRight"; -const char anchorParentBottomCommandId[] = "AnchorParentBottom"; -const char anchorParentLeftCommandId[] = "AnchorParentLeft"; +inline constexpr char anchorParentTopAndBottomCommandId[] = "AnchorParentTopAndBottom"; +inline constexpr char anchorParentLeftAndRightCommandId[] = "AnchorParentLeftAndRight"; +inline constexpr char anchorParentTopCommandId[] = "AnchorParentTop"; +inline constexpr char anchorParentRightCommandId[] = "AnchorParentRight"; +inline constexpr char anchorParentBottomCommandId[] = "AnchorParentBottom"; +inline constexpr char anchorParentLeftCommandId[] = "AnchorParentLeft"; -const char removePositionerCommandId[] = "RemovePositioner"; -const char createFlowActionAreaCommandId[] = "CreateFlowActionArea"; -const char setFlowStartCommandId[] = "SetFlowStart"; -const char selectFlowEffectCommandId[] = "SelectFlowEffect"; -const char layoutRowPositionerCommandId[] = "LayoutRowPositioner"; -const char layoutColumnPositionerCommandId[] = "LayoutColumnPositioner"; -const char layoutGridPositionerCommandId[] = "LayoutGridPositioner"; -const char layoutFlowPositionerCommandId[] = "LayoutFlowPositioner"; -const char removeLayoutCommandId[] = "RemoveLayout"; -const char layoutRowLayoutCommandId[] = "LayoutRowLayout"; -const char layoutColumnLayoutCommandId[] = "LayoutColumnLayout"; -const char layoutGridLayoutCommandId[] = "LayoutGridLayout"; -const char layoutFillWidthCommandId[] = "LayoutFillWidth"; -const char layoutFillHeightCommandId[] = "LayoutFillHeight"; -const char goIntoComponentCommandId[] = "GoIntoComponent"; -const char jumpToCodeCommandId[] = "JumpToCode"; -const char mergeTemplateCommandId[] = "MergeTemplate"; -const char goToImplementationCommandId[] = "GoToImplementation"; -const char makeComponentCommandId[] = "MakeComponent"; -const char editMaterialCommandId[] = "EditMaterial"; -const char addItemToStackedContainerCommandId[] = "AddItemToStackedContainer"; -const char addTabBarToStackedContainerCommandId[] = "AddTabBarToStackedContainer"; -const char increaseIndexOfStackedContainerCommandId[] = "IncreaseIndexOfStackedContainer"; -const char decreaseIndexOfStackedContainerCommandId[] = "DecreaseIndexOfStackedContainer"; -const char flowAssignEffectCommandId[] = "AssignFlowEffect"; -const char flowAssignCustomEffectCommandId[] = "AssignFlowCustomEffect"; -const char addToGroupItemCommandId[] = "AddToGroupItem"; -const char fitRootToScreenCommandId[] = "FitRootToScreen"; -const char fitSelectionToScreenCommandId[] = "FitSelectionToScreen"; -const char editAnnotationsCommandId[] = "EditAnnotation"; -const char addMouseAreaFillCommandId[] = "AddMouseAreaFill"; -const char editIn3dViewCommandId[] = "editIn3dView"; +inline constexpr char removePositionerCommandId[] = "RemovePositioner"; +inline constexpr char createFlowActionAreaCommandId[] = "CreateFlowActionArea"; +inline constexpr char setFlowStartCommandId[] = "SetFlowStart"; +inline constexpr char selectFlowEffectCommandId[] = "SelectFlowEffect"; +inline constexpr char layoutRowPositionerCommandId[] = "LayoutRowPositioner"; +inline constexpr char layoutColumnPositionerCommandId[] = "LayoutColumnPositioner"; +inline constexpr char layoutGridPositionerCommandId[] = "LayoutGridPositioner"; +inline constexpr char layoutFlowPositionerCommandId[] = "LayoutFlowPositioner"; +inline constexpr char removeLayoutCommandId[] = "RemoveLayout"; +inline constexpr char layoutRowLayoutCommandId[] = "LayoutRowLayout"; +inline constexpr char layoutColumnLayoutCommandId[] = "LayoutColumnLayout"; +inline constexpr char layoutGridLayoutCommandId[] = "LayoutGridLayout"; +inline constexpr char layoutFillWidthCommandId[] = "LayoutFillWidth"; +inline constexpr char layoutFillHeightCommandId[] = "LayoutFillHeight"; +inline constexpr char goIntoComponentCommandId[] = "GoIntoComponent"; +inline constexpr char jumpToCodeCommandId[] = "JumpToCode"; +inline constexpr char mergeTemplateCommandId[] = "MergeTemplate"; +inline constexpr char goToImplementationCommandId[] = "GoToImplementation"; +inline constexpr char makeComponentCommandId[] = "MakeComponent"; +inline constexpr char importComponentCommandId[] = "ImportComponent"; +inline constexpr char exportComponentCommandId[] = "ExportComponent"; +inline constexpr char editMaterialCommandId[] = "EditMaterial"; +inline constexpr char addToContentLibraryCommandId[] = "AddToContentLibrary"; +inline constexpr char addItemToStackedContainerCommandId[] = "AddItemToStackedContainer"; +inline constexpr char addTabBarToStackedContainerCommandId[] = "AddTabBarToStackedContainer"; +inline constexpr char increaseIndexOfStackedContainerCommandId[] + = "IncreaseIndexOfStackedContainer"; +inline constexpr char decreaseIndexOfStackedContainerCommandId[] + = "DecreaseIndexOfStackedContainer"; +inline constexpr char flowAssignEffectCommandId[] = "AssignFlowEffect"; +inline constexpr char flowAssignCustomEffectCommandId[] = "AssignFlowCustomEffect"; +inline constexpr char addToGroupItemCommandId[] = "AddToGroupItem"; +inline constexpr char fitRootToScreenCommandId[] = "FitRootToScreen"; +inline constexpr char fitSelectionToScreenCommandId[] = "FitSelectionToScreen"; +inline constexpr char editAnnotationsCommandId[] = "EditAnnotation"; +inline constexpr char addMouseAreaFillCommandId[] = "AddMouseAreaFill"; +inline constexpr char editIn3dViewCommandId[] = "editIn3dView"; -const char openSignalDialogCommandId[] = "OpenSignalDialog"; -const char update3DAssetCommandId[] = "Update3DAsset"; +inline constexpr char openSignalDialogCommandId[] = "OpenSignalDialog"; +inline constexpr char update3DAssetCommandId[] = "Update3DAsset"; -const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection"); -const char connectionsCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connections"); -const char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect"); -const char selectEffectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select Effect"); -const char arrangeCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Arrange"); -const char editCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit"); -const char anchorsCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Anchors"); -const char positionerCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Positioner"); -const char groupCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Group"); -const char snappingCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Snapping"); -const char layoutCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout"); -const char flowCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Flow"); -const char flowEffectCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Flow Effects"); -const char stackedContainerCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Stacked Container"); +inline constexpr char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Selection"); +inline constexpr char connectionsCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Connections"); +inline constexpr char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Connect"); +inline constexpr char selectEffectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Select Effect"); +inline constexpr char arrangeCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Arrange"); +inline constexpr char editCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit"); +inline constexpr char anchorsCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Anchors"); +inline constexpr char positionerCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Positioner"); +inline constexpr char groupCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Group"); +inline constexpr char snappingCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Snapping"); +inline constexpr char layoutCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Layout"); +inline constexpr char flowCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Flow"); +inline constexpr char flowEffectCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Flow Effects"); +inline constexpr char stackedContainerCategoryDisplayName[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Stacked Container"); -const char cutSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Cut"); -const char copySelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Copy"); -const char pasteSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Paste"); -const char deleteSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Delete Selection"); +inline constexpr char cutSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Cut"); +inline constexpr char copySelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Copy"); +inline constexpr char pasteSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Paste"); +inline constexpr char deleteSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Delete Selection"); -const char toFrontDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Bring to Front"); -const char toBackDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Send to Back"); +inline constexpr char toFrontDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Bring to Front"); +inline constexpr char toBackDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Send to Back"); -const char raiseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Bring Forward"); -const char lowerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Send Backward"); +inline constexpr char raiseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Bring Forward"); +inline constexpr char lowerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Send Backward"); -const char undoDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Undo"); -const char redoDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Redo"); +inline constexpr char undoDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Undo"); +inline constexpr char redoDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Redo"); -const char visibilityDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Visibility"); +inline constexpr char visibilityDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Visibility"); -const char resetSizeDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset Size"); -const char resetPositionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset Position"); -const char copyFormatDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Copy Formatting"); -const char applyFormatDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Apply Formatting"); +inline constexpr char resetSizeDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Reset Size"); +inline constexpr char resetPositionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Reset Position"); +inline constexpr char copyFormatDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Copy Formatting"); +inline constexpr char applyFormatDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Apply Formatting"); -const char enterComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit Component"); -const char JumpToCodeDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Jump to the Code"); -const char mergeTemplateDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Merge with Template"); -const char goToImplementationDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Go to Implementation"); -const char makeComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Create Component"); -const char editMaterialDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit Material"); -const char editAnnotationsDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit Annotations"); -const char addMouseAreaFillDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Add Mouse Area"); -const char editIn3dViewDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit in 3D View"); +inline constexpr char enterComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Edit Component"); +inline constexpr char JumpToCodeDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Jump to the Code"); +inline constexpr char mergeTemplateDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Merge with Template"); +inline constexpr char goToImplementationDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Go to Implementation"); +inline constexpr char makeComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Create Component"); +inline constexpr char editMaterialDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Edit Material"); +inline constexpr char addToContentLibraryDisplayName[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Add to Content Library"); +inline constexpr char importComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Import Component"); +inline constexpr char exportComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Export Component"); +inline constexpr char editAnnotationsDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Edit Annotations"); +inline constexpr char addMouseAreaFillDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Add Mouse Area"); +inline constexpr char editIn3dViewDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Edit in 3D View"); -const char openSignalDialogDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Open Signal Dialog"); -const char update3DAssetDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Update 3D Asset"); +inline constexpr char openSignalDialogDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Open Signal Dialog"); +inline constexpr char update3DAssetDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Update 3D Asset"); -const char setIdDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set Id"); +inline constexpr char setIdDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set Id"); -const char resetZDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset z Property"); +inline constexpr char resetZDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Reset z Property"); -const char reverseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reverse"); +inline constexpr char reverseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reverse"); -const char anchorsFillDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fill Parent"); -const char anchorsResetDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "No Anchors"); +inline constexpr char anchorsFillDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Fill Parent"); +inline constexpr char anchorsResetDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "No Anchors"); -const char anchorParentTopAndBottomDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Top And Bottom"); -const char anchorParentLeftAndRightDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Left And Right"); -const char anchorParentTopDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Top"); -const char anchorParentRightDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Right"); -const char anchorParentBottomDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Bottom"); -const char anchorParentLeftDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Left"); +inline constexpr char anchorParentTopAndBottomDisplayName[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Top And Bottom"); +inline constexpr char anchorParentLeftAndRightDisplayName[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Left And Right"); +inline constexpr char anchorParentTopDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Top"); +inline constexpr char anchorParentRightDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Right"); +inline constexpr char anchorParentBottomDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Bottom"); +inline constexpr char anchorParentLeftDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Left"); -const char layoutColumnPositionerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Column Positioner"); -const char layoutRowPositionerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Row Positioner"); -const char layoutGridPositionerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Grid Positioner"); -const char layoutFlowPositionerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Flow Positioner"); -const char removePositionerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Remove Positioner"); -const char createFlowActionAreaDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Create Flow Action"); -const char setFlowStartDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set Flow Start"); -const char removeLayoutDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Remove Layout"); +inline constexpr char layoutColumnPositionerDisplayName[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Column Positioner"); +inline constexpr char layoutRowPositionerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Row Positioner"); +inline constexpr char layoutGridPositionerDisplayName[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Grid Positioner"); +inline constexpr char layoutFlowPositionerDisplayName[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Flow Positioner"); +inline constexpr char removePositionerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Remove Positioner"); +inline constexpr char createFlowActionAreaDisplayName[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Create Flow Action"); +inline constexpr char setFlowStartDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Set Flow Start"); +inline constexpr char removeLayoutDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Remove Layout"); -const char addToGroupItemDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Group in GroupItem"); -const char removeGroupItemDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", - "Remove GroupItem"); +inline constexpr char addToGroupItemDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Group in GroupItem"); +inline constexpr char removeGroupItemDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Remove GroupItem"); -const char addItemToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Add Component"); -const char addTabBarToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Add Tab Bar"); -const char increaseIndexToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Increase Index"); -const char decreaseIndexToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Decrease Index"); +inline constexpr char addItemToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Add Component"); +inline constexpr char addTabBarToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Add Tab Bar"); +inline constexpr char increaseIndexToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Increase Index"); +inline constexpr char decreaseIndexToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Decrease Index"); -const char layoutColumnLayoutDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Column Layout"); -const char layoutRowLayoutDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Row Layout"); -const char layoutGridLayoutDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Grid Layout"); +inline constexpr char layoutColumnLayoutDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Column Layout"); +inline constexpr char layoutRowLayoutDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Row Layout"); +inline constexpr char layoutGridLayoutDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Grid Layout"); -const char layoutFillWidthDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fill Width"); -const char layoutFillHeightDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fill Height"); +inline constexpr char layoutFillWidthDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Fill Width"); +inline constexpr char layoutFillHeightDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Fill Height"); -const char flowAssignEffectDisplayName[] = "Assign FlowEffect "; -const char flowAssignCustomEffectDisplayName[] = "Assign Custom FlowEffect "; +inline constexpr char flowAssignEffectDisplayName[] = "Assign FlowEffect "; +inline constexpr char flowAssignCustomEffectDisplayName[] = "Assign Custom FlowEffect "; -const char raiseToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Raise selected component."); -const char lowerToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Lower selected component."); +inline constexpr char raiseToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Raise selected component."); +inline constexpr char lowerToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Lower selected component."); -const char resetSizeToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset size and use implicit size."); -const char resetPositionTooltip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset position and use implicit position."); -const char copyFormatTooltip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Copy formatting."); -const char applyFormatTooltip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Apply formatting."); +inline constexpr char resetSizeToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Reset size and use implicit size."); +inline constexpr char resetPositionTooltip[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Reset position and use implicit position."); +inline constexpr char copyFormatTooltip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Copy formatting."); +inline constexpr char applyFormatTooltip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Apply formatting."); -const char anchorsFillToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fill selected component to parent."); -const char anchorsResetToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset anchors for selected component."); +inline constexpr char anchorsFillToolTip[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Fill selected component to parent."); +inline constexpr char anchorsResetToolTip[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Reset anchors for selected component."); -const char layoutColumnLayoutToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout selected components in column layout."); -const char layoutRowLayoutToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout selected components in row layout."); -const char layoutGridLayoutToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout selected components in grid layout."); +inline constexpr char layoutColumnLayoutToolTip[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Layout selected components in column layout."); +inline constexpr char layoutRowLayoutToolTip[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Layout selected components in row layout."); +inline constexpr char layoutGridLayoutToolTip[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Layout selected components in grid layout."); -const char increaseIndexOfStackedContainerToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Increase index of stacked container."); -const char decreaseIndexOfStackedContainerToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Decrease index of stacked container."); -const char addItemToStackedContainerToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Add component to stacked container."); -const char addFlowActionToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Add flow action."); +inline constexpr char increaseIndexOfStackedContainerToolTip[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Increase index of stacked container."); +inline constexpr char decreaseIndexOfStackedContainerToolTip[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Decrease index of stacked container."); +inline constexpr char addItemToStackedContainerToolTip[] = QT_TRANSLATE_NOOP( + "QmlDesignerContextMenu", "Add component to stacked container."); +inline constexpr char addFlowActionToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Add flow action."); -const char editListModelDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", - "Edit List Model..."); +inline constexpr char editListModelDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Edit List Model..."); namespace Priorities { enum PrioritiesEnum : int { Top = 0, @@ -241,20 +328,31 @@ enum PrioritiesEnum : int { SignalsDialog, Refactoring, GenericToolBar, - Last + Last, + /******** Section *****************************/ + AddingAssetsSection = 7000, + Add3DToContentLib, + ImportComponent, + ExportComponent, }; }; -const char addImagesDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Image Files"); -const char addFontsDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Font Files"); -const char addSoundsDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Sound Files"); -const char addVideosDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Video Files"); -const char addShadersDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Shader Files"); -const char add3DAssetsDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "3D Assets"); -const char addQt3DSPresentationsDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", - "Qt 3D Studio Presentations"); -const char addCustomEffectDialogDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", - "Effect Composer Files"); +inline constexpr char addImagesDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", + "Image Files"); +inline constexpr char addFontsDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", + "Font Files"); +inline constexpr char addSoundsDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", + "Sound Files"); +inline constexpr char addVideosDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", + "Video Files"); +inline constexpr char addShadersDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", + "Shader Files"); +inline constexpr char add3DAssetsDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", + "3D Assets"); +inline constexpr char addQt3DSPresentationsDisplayString[] = QT_TRANSLATE_NOOP( + "QmlDesignerAddResources", "Qt 3D Studio Presentations"); +inline constexpr char addCustomEffectDialogDisplayString[] = QT_TRANSLATE_NOOP( + "QmlDesignerAddResources", "Effect Composer Files"); } //ComponentCoreConstants diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index bbe64935f61..c39c9b9e68f 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include @@ -733,7 +733,7 @@ public: signalHandler.view() ->emitCustomNotification(EditConnectionNotification, {signalHandler.parentModelNode()}, - {signalHandler.name()}); + {signalHandler.name().toByteArray()}); //ActionEditor::invokeEditor(signalHandler, removeSignal); }); @@ -1978,6 +1978,26 @@ void DesignerActionManager::createDefaultDesignerActions() &singleSelection, &singleSelection)); + addDesignerAction(new ModelNodeContextMenuAction( + importComponentCommandId, + importComponentDisplayName, + contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon + rootCategory, + QKeySequence(), + Priorities::ImportComponent, + &importComponent)); + + addDesignerAction(new ModelNodeContextMenuAction( + exportComponentCommandId, + exportComponentDisplayName, + contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon + rootCategory, + QKeySequence(), + Priorities::ExportComponent, + &exportComponent, + &is3DNode, + &is3DNode)); + addDesignerAction(new ModelNodeContextMenuAction( editMaterialCommandId, editMaterialDisplayName, @@ -1999,6 +2019,17 @@ void DesignerActionManager::createDefaultDesignerActions() [&] (const SelectionContext& context) { mergeWithTemplate(context, m_externalDependencies); }, &SelectionContextFunctors::always)); + addDesignerAction(new ModelNodeContextMenuAction( + addToContentLibraryCommandId, + addToContentLibraryDisplayName, + contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon + rootCategory, + QKeySequence(), + Priorities::Add3DToContentLib, + &add3DAssetToContentLibrary, + &enableAddToContentLib, + &enableAddToContentLib)); + addDesignerAction(new ActionGroup( "", genericToolBarCategory, diff --git a/src/plugins/qmldesigner/components/componentcore/groupitemaction.cpp b/src/plugins/qmldesigner/components/componentcore/groupitemaction.cpp index 7bd2f793d37..69fb52e264a 100644 --- a/src/plugins/qmldesigner/components/componentcore/groupitemaction.cpp +++ b/src/plugins/qmldesigner/components/componentcore/groupitemaction.cpp @@ -3,10 +3,11 @@ #include "groupitemaction.h" +#include "designermcumanager.h" #include "nodeabstractproperty.h" #include "nodelistproperty.h" -#include +#include #include using namespace QmlDesigner; @@ -81,6 +82,10 @@ inline bool itemsAreGrouped(const SelectionContext &selection) bool groupingEnabled(const SelectionContext &selection) { + //StudioComponents.GroupItem is not available in Qt for MCUs + if (DesignerMcuManager::instance().isMCUProject()) + return false; + if (selection.singleNodeIsSelected()) return itemsAreGrouped(selection); else diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.cpp index 4cbebd738df..3297d1a59fd 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.cpp @@ -4,7 +4,7 @@ #include "modelnodecontextmenu_helper.h" #include -#include +#include #include #include #include diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h index 6734bac568b..98ea60f7690 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h @@ -70,6 +70,23 @@ inline bool isModelOrMaterial(const SelectionContext &selectionState) return node.metaInfo().isQtQuick3DModel() || node.metaInfo().isQtQuick3DMaterial(); } +inline bool enableAddToContentLib(const SelectionContext &selectionState) +{ + ModelNode modelNode = selectionState.currentSingleSelectedNode(); + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + bool isInBundle = modelNode.type().startsWith(compUtils.componentBundlesTypePrefix().toLatin1()); + bool isNode3D = modelNode.metaInfo().isQtQuick3DNode(); + + return isNode3D && !isInBundle; +} + +inline bool is3DNode(const SelectionContext &selectionState) +{ + ModelNode modelNode = selectionState.currentSingleSelectedNode(); + + return modelNode.metaInfo().isQtQuick3DNode(); +} + inline bool hasEditableMaterial(const SelectionContext &selectionState) { ModelNode node = selectionState.currentSingleSelectedNode(); diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index bf8e78a2c7c..d114d2dc151 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -797,6 +797,23 @@ void moveToComponent(const SelectionContext &selectionContext) selectionContext.view()->model()->rewriterView()->moveToComponent(modelNode); } +void add3DAssetToContentLibrary(const SelectionContext &selectionContext) +{ + ModelNode node = selectionContext.currentSingleSelectedNode(); + selectionContext.view()->emitCustomNotification("add_3d_to_content_lib", {node}); +} + +void importComponent(const SelectionContext &selectionContext) +{ + selectionContext.view()->emitCustomNotification("import_bundle_to_project"); +} + +void exportComponent(const SelectionContext &selectionContext) +{ + ModelNode node = selectionContext.currentSingleSelectedNode(); + selectionContext.view()->emitCustomNotification("export_item_as_bundle", {node}); +} + void goImplementation(const SelectionContext &selectionState) { addSignalHandlerOrGotoImplementation(selectionState, false); @@ -1622,7 +1639,7 @@ void addMouseAreaFill(const SelectionContext &selectionContext) QmlDesigner::ModelNode mouseAreaNode = selectionContext.view()->createModelNode( "QtQuick.MouseArea", itemMetaInfo.majorVersion(), itemMetaInfo.minorVersion()); #endif - mouseAreaNode.validId(); + mouseAreaNode.ensureIdExists(); modelNode.defaultNodeListProperty().reparentHere(mouseAreaNode); QmlItemNode mouseAreaItemNode(mouseAreaNode); diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h index e1b977a5766..26f688da285 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h @@ -96,6 +96,9 @@ void addSignalHandlerOrGotoImplementation(const SelectionContext &selectionState void removeLayout(const SelectionContext &selectionContext); void removePositioner(const SelectionContext &selectionContext); void moveToComponent(const SelectionContext &selectionContext); +void add3DAssetToContentLibrary(const SelectionContext &selectionContext); +void importComponent(const SelectionContext &selectionContext); +void exportComponent(const SelectionContext &selectionContext); PropertyName getIndexPropertyName(const ModelNode &modelNode); void addItemToStackedContainer(const SelectionContext &selectionContext); void increaseIndexOfStackedContainer(const SelectionContext &selectionContext); diff --git a/src/plugins/qmldesigner/components/componentcore/resourcegenerator.cpp b/src/plugins/qmldesigner/components/componentcore/resourcegenerator.cpp index 24047f650f1..97a00a10f40 100644 --- a/src/plugins/qmldesigner/components/componentcore/resourcegenerator.cpp +++ b/src/plugins/qmldesigner/components/componentcore/resourcegenerator.cpp @@ -13,6 +13,7 @@ #include #include +#include #include @@ -143,41 +144,17 @@ void generateMenuEntry(QObject *parent) exportMenu->addAction(cmd2, QmlProjectManager::Constants::G_EXPORT_GENERATE); } -bool skipSuffix(const QString &fileName) -{ - const QStringList suffixes = {".pri", - ".pro", - ".user", - ".qrc", - ".qds", - "CMakeLists.txt", - ".db", - ".tmp", - ".TMP", - ".metainfo", - ".qtds", - ".db-shm", - ".db-wal"}; - - for (const auto &suffix : suffixes) - if (fileName.endsWith(suffix)) - return true; - - return false; -} - QStringList getProjectFileList() { const ProjectExplorer::Project *project = ProjectExplorer::ProjectManager::startupProject(); const FilePaths paths = project->files(ProjectExplorer::Project::AllFiles); - const QDir dir(project->projectFilePath().parentDir().toString()); QStringList selectedFileList; - + const Utils::FilePath dir(project->projectFilePath().parentDir()); for (const FilePath &path : paths) { - QString relativePath = dir.relativeFilePath(path.toString()); - if (!skipSuffix(relativePath)) - selectedFileList.append(relativePath); + const Utils::FilePath relativePath = path.relativePathFrom(dir); + if (QmlProjectManager::isResource(relativePath)) + selectedFileList.append(relativePath.path()); } return selectedFileList; diff --git a/src/plugins/qmldesigner/components/componentcore/resourcegenerator.h b/src/plugins/qmldesigner/components/componentcore/resourcegenerator.h index de827a468df..e8c0fde0e81 100644 --- a/src/plugins/qmldesigner/components/componentcore/resourcegenerator.h +++ b/src/plugins/qmldesigner/components/componentcore/resourcegenerator.h @@ -11,7 +11,6 @@ namespace QmlDesigner::ResourceGenerator { QMLDESIGNERCOMPONENTS_EXPORT void generateMenuEntry(QObject *parent); QMLDESIGNERCOMPONENTS_EXPORT QStringList getProjectFileList(); -QMLDESIGNERCOMPONENTS_EXPORT bool skipSuffix(const QString &fileName); QMLDESIGNERCOMPONENTS_EXPORT bool createQrcFile(const Utils::FilePath &qrcFilePath); QMLDESIGNERCOMPONENTS_EXPORT bool createQmlrcFile(const Utils::FilePath &qmlrcFilePath); diff --git a/src/plugins/qmldesigner/components/componentcore/theme.cpp b/src/plugins/qmldesigner/components/componentcore/theme.cpp index ef618447e71..6b4e3b3616a 100644 --- a/src/plugins/qmldesigner/components/componentcore/theme.cpp +++ b/src/plugins/qmldesigner/components/componentcore/theme.cpp @@ -34,7 +34,8 @@ Theme::Theme(Utils::Theme *originTheme, QObject *parent) "qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml") .toString(); - QQmlEngine* engine = new QQmlEngine(this); + QQmlEngine *engine = new QQmlEngine(this); + setupTheme(engine); QQmlComponent component(engine, QUrl::fromLocalFile(constantsPath)); if (component.status() == QQmlComponent::Ready) { @@ -153,8 +154,7 @@ QPixmap Theme::getPixmap(const QString &id) QString Theme::getIconUnicode(Theme::Icon i) { - if (!instance()->m_constants) - return QString(); + QTC_ASSERT(instance()->m_constants, return {}); const QMetaObject *m = instance()->metaObject(); const char *enumName = "Icon"; @@ -172,6 +172,7 @@ QString Theme::getIconUnicode(Theme::Icon i) QString Theme::getIconUnicode(const QString &name) { + QTC_ASSERT(instance()->m_constants, return {}); return instance()->m_constants->property(name.toStdString().data()).toString(); } diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp index a56735862f3..3af7b99af13 100644 --- a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp @@ -20,17 +20,19 @@ #include #include #include +#include #include #include #include +#include #include #include #include #include -#include #include +#include #include #include @@ -49,6 +51,7 @@ public: ViewManagerData(AsynchronousImageCache &imageCache, ExternalDependenciesInterface &externalDependencies) : debugView{externalDependencies} + , auxiliaryDataKeyView{auxiliaryDataDatabase, externalDependencies} , designerActionManagerView{externalDependencies} , nodeInstanceView(QCoreApplication::arguments().contains("-capture-puppet-stream") ? capturingConnectionManager @@ -78,6 +81,11 @@ public: CapturingConnectionManager capturingConnectionManager; QmlModelState savedState; Internal::DebugView debugView; + Sqlite::Database auxiliaryDataDatabase{ + Utils::PathString{Core::ICore::userResourcePath("auxiliary_data.db").toString()}, + Sqlite::JournalMode::Wal, + Sqlite::LockingMode::Normal}; + AuxiliaryPropertyStorageView auxiliaryDataKeyView; DesignerActionManagerView designerActionManagerView; NodeInstanceView nodeInstanceView; ContentLibraryView contentLibraryView; @@ -161,7 +169,7 @@ void ViewManager::attachRewriterView() }); currentModel()->setRewriterView(view); - view->reactivateTextMofifierChangeSignals(); + view->reactivateTextModifierChangeSignals(); view->restoreAuxiliaryData(); } @@ -171,7 +179,7 @@ void ViewManager::attachRewriterView() void ViewManager::detachRewriterView() { if (RewriterView *view = currentDesignDocument()->rewriterView()) { - view->deactivateTextMofifierChangeSignals(); + view->deactivateTextModifierChangeSignals(); currentModel()->setRewriterView(nullptr); } } @@ -201,7 +209,8 @@ QList ViewManager::views() const QList ViewManager::standardViews() const { #ifndef QTC_USE_QML_DESIGNER_LITE - QList list = {&d->edit3DView, + QList list = {&d->auxiliaryDataKeyView, + &d->edit3DView, &d->formEditorView, &d->textEditorView, &d->assetsLibraryView, @@ -416,23 +425,9 @@ QList ViewManager::widgetInfos() const widgetInfoList.append(view->widgetInfo()); } - Utils::sort(widgetInfoList, [](const WidgetInfo &firstWidgetInfo, const WidgetInfo &secondWidgetInfo) { - return firstWidgetInfo.placementPriority < secondWidgetInfo.placementPriority; - }); - return widgetInfoList; } -QWidget *ViewManager::widget(const QString &uniqueId) const -{ - const QList widgetInfoList = widgetInfos(); - for (const WidgetInfo &widgetInfo : widgetInfoList) { - if (widgetInfo.uniqueId == uniqueId) - return widgetInfo.widget; - } - return nullptr; -} - void ViewManager::disableWidgets() { for (const auto &view : views()) diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.h b/src/plugins/qmldesigner/components/componentcore/viewmanager.h index db92649c3c5..6a6d281d353 100644 --- a/src/plugins/qmldesigner/components/componentcore/viewmanager.h +++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.h @@ -62,7 +62,6 @@ public: } QList widgetInfos() const; - QWidget *widget(const QString & uniqueId) const; void disableWidgets(); void enableWidgets(); diff --git a/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp index 97c73205b29..398fa968e45 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp @@ -6,6 +6,7 @@ #include "backendmodel.h" #include "bindingproperty.h" +#include "connectioneditorutils.h" #include "connectionview.h" #include "exception.h" #include "nodemetainfo.h" @@ -203,7 +204,7 @@ void BackendModel::addNewBackend() if (dialog.applied()) { QStringList importSplit = dialog.importString().split(" "); if (importSplit.size() != 2) { - qWarning() << Q_FUNC_INFO << "invalid import" << importSplit; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "invalid import" << importSplit; QTC_ASSERT(false, return); } @@ -278,7 +279,7 @@ void BackendModel::updatePropertyName(int rowNumber) rootModelNode.removeProperty(oldName); rootModelNode.bindingProperty(newName).setDynamicTypeNameAndExpression(typeName, expression); } else { - qWarning() << Q_FUNC_INFO << oldName << newName << "failed..."; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << oldName << newName << "failed..."; QTC_ASSERT(false, return); } }); @@ -290,7 +291,7 @@ void BackendModel::handleDataChanged(const QModelIndex &topLeft, const QModelInd return; if (topLeft != bottomRight) { - qWarning() << "BackendModel::handleDataChanged multi edit?"; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "multi edit?"; return; } @@ -307,7 +308,8 @@ void BackendModel::handleDataChanged(const QModelIndex &topLeft, const QModelInd updatePropertyName(currentRow); } break; - default: qWarning() << "BindingModel::handleDataChanged column" << currentColumn; + default: + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "column" << currentColumn; } m_lock = false; diff --git a/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp index 2cee7b0f977..4ef8a4ed378 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp @@ -89,7 +89,7 @@ void BindingModel::add() } } } else { - qWarning() << __FUNCTION__ << " Requires exactly one selected node"; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "Requires exactly one selected node"; } } @@ -211,7 +211,7 @@ QHash BindingModel::roleNames() const std::optional BindingModel::rowForProperty(const AbstractProperty &property) const { - PropertyName name = property.name(); + PropertyNameView name = property.name(); int internalId = property.parentModelNode().internalId(); for (int i = 0; i < rowCount(); ++i) { diff --git a/src/plugins/qmldesigner/components/connectioneditor/bindingmodelitem.cpp b/src/plugins/qmldesigner/components/connectioneditor/bindingmodelitem.cpp index 9e9fd92f528..e5e1372dd65 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/bindingmodelitem.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/bindingmodelitem.cpp @@ -42,7 +42,7 @@ void BindingModelItem::updateProperty(const BindingProperty &property) { setData(property.parentModelNode().internalId(), InternalIdRole); setData(idOrTypeName(property.parentModelNode()), TargetNameRole); - setData(property.name(), TargetPropertyNameRole); + setData(property.name().toByteArray(), TargetPropertyNameRole); // TODO: Make this safe when the new codemodel allows it. if (auto expression = property.expression(); !expression.isEmpty()) { diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectioneditorevaluator.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectioneditorevaluator.cpp index 5bb96390253..7bea5cd2cdd 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectioneditorevaluator.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectioneditorevaluator.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "connectioneditorevaluator.h" +#include "connectioneditorutils.h" #include "qmljs/parser/qmljsast_p.h" #include "qmljs/qmljsdocument.h" @@ -254,7 +255,7 @@ protected: void throwRecursionDepthError() override { checkValidityAndReturn(false, "Recursion depth problem"); - qDebug() << Q_FUNC_INFO << this; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "Recursion depth error"; } void checkAndResetVariable() @@ -477,7 +478,7 @@ protected: void throwRecursionDepthError() override { setFailed(); - qDebug() << Q_FUNC_INFO << this; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "Recursion depth error"; } void checkAndResetCal() @@ -617,7 +618,7 @@ protected: void throwRecursionDepthError() override { m_failed = true; - qDebug() << Q_FUNC_INFO << this; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "Recursion depth error"; } private: @@ -1082,7 +1083,7 @@ void ConnectionEditorEvaluator::endVisit(QmlJS::AST::StatementList * /*statement void ConnectionEditorEvaluator::throwRecursionDepthError() { d->checkValidityAndReturn(false, "Recursion depth problem"); - qDebug() << Q_FUNC_INFO << this; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "Recursion depth error"; } bool ConnectionEditorEvaluatorPrivate::checkValidityAndReturn(bool valid, const QString &parseError) @@ -1091,7 +1092,7 @@ bool ConnectionEditorEvaluatorPrivate::checkValidityAndReturn(bool valid, const if (m_checkStatus != Status::Failed) { setStatus(Status::Failed); m_errorString = parseError; - qDebug() << Q_FUNC_INFO << "Error: " << parseError; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "Parse error" << parseError; } } diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.cpp index 3cbfb8c0383..b96e000f8cd 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.cpp @@ -24,6 +24,8 @@ namespace QmlDesigner { +Q_LOGGING_CATEGORY(ConnectionEditorLog, "qtc.qtquickdesigner.connectioneditor", QtWarningMsg) + void callLater(const std::function &fun) { QTimer::singleShot(0, fun); @@ -78,7 +80,7 @@ NodeMetaInfo dynamicTypeNameToNodeMetaInfo(const TypeName &typeName, Model *mode else if (typeName == "var" || typeName == "variant") return model->metaInfo("QML.variant"); else - qWarning() << __FUNCTION__ << " type " << typeName << "not found"; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "type" << typeName << "not found"; return {}; } @@ -173,7 +175,7 @@ void convertPropertyType(const T &property, const QVariant &value) if (!node.isValid()) return; - PropertyName name = property.name(); + PropertyNameView name = property.name(); TypeName type = property.dynamicTypeName(); node.removeProperty(name); @@ -203,7 +205,8 @@ bool isBindingExpression(const QVariant &value) if (value.metaType().id() != QMetaType::QString) return false; - QRegularExpression regexp("^[a-z_]\\w*|^[A-Z]\\w*\\.{1}([a-z_]\\w*\\.?)+"); + QRegularExpression regexp("^[a-zA-Z_]\\w*\\.{1}([a-z_]\\w*\\.?)+"); + // QRegularExpression regexp("^[a-z_]\\w*|^[A-Z]\\w*\\.{1}([a-z_]\\w*\\.?)+"); QRegularExpressionMatch match = regexp.match(value.toString()); return match.hasMatch(); } @@ -301,13 +304,16 @@ std::vector propertiesFromSingleton(const QString &name, Abstr QList dynamicPropertiesFromNode(const ModelNode &node) { - auto isDynamic = [](const AbstractProperty &p) { return p.isDynamic(); }; + auto isDynamic = [](const AbstractProperty &p) { + return p.isDynamic() || p.isSignalDeclarationProperty(); + }; auto byName = [](const AbstractProperty &a, const AbstractProperty &b) { return a.name() < b.name(); }; QList dynamicProperties = Utils::filtered(node.properties(), isDynamic); Utils::sort(dynamicProperties, byName); + return dynamicProperties; } @@ -326,7 +332,7 @@ QStringList availableTargetProperties(const BindingProperty &bindingProperty) { const ModelNode modelNode = bindingProperty.parentModelNode(); if (!modelNode.isValid()) { - qWarning() << __FUNCTION__ << " invalid model node"; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "invalid model node"; return {}; } @@ -368,7 +374,7 @@ QStringList availableSourceProperties(const QString &id, } else if (auto metaInfo = targetProperty.parentModelNode().metaInfo(); metaInfo.isValid()) { targetType = metaInfo.property(targetProperty.name()).propertyType(); } else - qWarning() << __FUNCTION__ << " no meta info for target node"; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "no meta info for target node"; QStringList possibleProperties; if (!modelNode.isValid()) { @@ -380,7 +386,7 @@ QStringList availableSourceProperties(const QString &id, } return possibleProperties; } - qWarning() << __FUNCTION__ << " invalid model node: " << id; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "invalid model node:" << id; return {}; } @@ -406,7 +412,7 @@ QStringList availableSourceProperties(const QString &id, possibleProperties.push_back(QString::fromUtf8(property.name())); } } else { - qWarning() << __FUNCTION__ << " no meta info for source node"; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "no meta info for source node"; } return possibleProperties; diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.h b/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.h index b81cc97bbae..501968a642a 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.h +++ b/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.h @@ -7,11 +7,14 @@ #include "propertymetainfo.h" #include +#include #include #include namespace QmlDesigner { +Q_DECLARE_LOGGING_CATEGORY(ConnectionEditorLog) + class AbstractView; class AbstractProperty; class BindingProperty; diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp index 2047f7625c1..50782eda7bc 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp @@ -2,13 +2,14 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "connectionmodel.h" +#include "connectioneditorutils.h" #include "connectionview.h" #include "utils/algorithm.h" #include #include #include -#include +#include #include #include #include @@ -201,7 +202,7 @@ void ConnectionModel::updateSignalName(int rowNumber) SignalHandlerProperty newSignalHandlerProperty = connectionNode.signalHandlerProperty(newName); updateCustomData(idItem, newSignalHandlerProperty); } else { - qWarning() << "BindingModel::updatePropertyName invalid property name"; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "invalid property name"; } } @@ -251,14 +252,14 @@ void ConnectionModel::updateTargetNode(int rowNumber) }); } else { - qWarning() << "BindingModel::updatePropertyName invalid target id"; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "invalid target id"; } } void ConnectionModel::updateCustomData(QStandardItem *item, const SignalHandlerProperty &signalHandlerProperty) { item->setData(signalHandlerProperty.parentModelNode().internalId(), UserRoles::InternalIdRole); - item->setData(signalHandlerProperty.name(), UserRoles::TargetPropertyNameRole); + item->setData(signalHandlerProperty.name().toByteArray(), UserRoles::TargetPropertyNameRole); item->setData(signalHandlerProperty.parentModelNode() .bindingProperty("target") .resolveToModelNode() @@ -532,7 +533,7 @@ ConnectionModelBackendDelegate *ConnectionModel::delegate() void ConnectionModel::handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { if (topLeft != bottomRight) { - qWarning() << "ConnectionModel::handleDataChanged multi edit?"; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "multi edit?"; return; } @@ -551,8 +552,8 @@ void ConnectionModel::handleDataChanged(const QModelIndex &topLeft, const QModel case SourceRow: { updateSource(currentRow); } break; - - default: qWarning() << "ConnectionModel::handleDataChanged column" << currentColumn; + default: + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "column" << currentColumn; } m_lock = false; @@ -1694,9 +1695,9 @@ QVariant ConditionListModel::data(const QModelIndex &index, int role) const return m_tokens.at(index.row()).value; } - qWarning() << Q_FUNC_INFO << "invalid role"; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "invalid role"; } else { - qWarning() << Q_FUNC_INFO << "invalid index"; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "invalid index"; } return QVariant(); diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp index 786fd04f1b0..8f0c9ebe62e 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp @@ -303,7 +303,7 @@ WidgetInfo ConnectionView::widgetInfo() return createWidgetInfo(d->connectionViewQuickWidget.get(), QLatin1String("ConnectionView"), WidgetInfo::LeftPane, - 0, + tr("Connections")); } diff --git a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesitem.cpp b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesitem.cpp index ae23fab076d..53e668be65e 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesitem.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesitem.cpp @@ -55,7 +55,7 @@ void DynamicPropertiesItem::updateProperty(const AbstractProperty &property) { setData(property.parentModelNode().internalId(), InternalIdRole); setData(idOrTypeName(property.parentModelNode()), TargetNameRole); - setData(property.name(), PropertyNameRole); + setData(property.name().toByteArray(), PropertyNameRole); setData(property.dynamicTypeName(), PropertyTypeRole); if (property.isVariantProperty()) { diff --git a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp index fa29c6c8a1b..687752b8c98 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp @@ -68,7 +68,7 @@ void DynamicPropertiesModel::add() showErrorMessage(e.description()); } } else { - qWarning() << "DynamicPropertiesModel::add not one node selected"; + qCWarning(ConnectionEditorLog) << __FUNCTION__ << "not one node selected"; } } @@ -136,7 +136,7 @@ void DynamicPropertiesModel::setCurrentProperty(const AbstractProperty &property setCurrentIndex(*index); } -void DynamicPropertiesModel::setCurrent(int internalId, const PropertyName &name) +void DynamicPropertiesModel::setCurrent(int internalId, PropertyNameView name) { if (internalId < 0) return; @@ -195,7 +195,7 @@ AbstractProperty DynamicPropertiesModel::propertyForRow(int row) const return {}; } -std::optional DynamicPropertiesModel::findRow(int nodeId, const PropertyName &name) const +std::optional DynamicPropertiesModel::findRow(int nodeId, PropertyNameView name) const { for (int i = 0; i < rowCount(); ++i) { if (auto *item = itemForRow(i)) { @@ -243,7 +243,7 @@ void DynamicPropertiesModel::addModelNode(const ModelNode &node) void DynamicPropertiesModel::addProperty(const AbstractProperty &property) { - const PropertyName name = property.name(); + const PropertyNameView name = property.name(); for (int i = 0; i < rowCount(); ++i) { if (auto *item = itemForRow(i)) { if (item->propertyName() > name) { @@ -282,7 +282,7 @@ void DynamicPropertiesModel::commitPropertyType(int row, const TypeName &type) } } -void DynamicPropertiesModel::commitPropertyName(int row, const PropertyName &name) +void DynamicPropertiesModel::commitPropertyName(int row, PropertyNameView name) { AbstractProperty property = propertyForRow(row); if (!property.isValid()) @@ -346,7 +346,7 @@ void DynamicPropertiesModel::dispatchPropertyChanges(const AbstractProperty &abs QmlPropertyChanges changes(abstractProperty.parentModelNode()); if (changes.target().isValid()) { const ModelNode target = changes.target(); - const PropertyName propertyName = abstractProperty.name(); + const PropertyNameView propertyName = abstractProperty.name(); const AbstractProperty targetProperty = target.variantProperty(propertyName); if (target.hasProperty(propertyName) && targetProperty.isDynamic()) updateItem(targetProperty); diff --git a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.h b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.h index 071c72bef81..c1afecb0cd6 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.h +++ b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.h @@ -46,13 +46,13 @@ public: void reset(const QList &modelNodes = {}); void setCurrentIndex(int i); void setCurrentProperty(const AbstractProperty &property); - void setCurrent(int internalId, const PropertyName &name); + void setCurrent(int internalId, PropertyNameView name); void updateItem(const AbstractProperty &property); void removeItem(const AbstractProperty &property); void commitPropertyType(int row, const TypeName &type); - void commitPropertyName(int row, const PropertyName &name); + void commitPropertyName(int row, PropertyNameView name); void commitPropertyValue(int row, const QVariant &value); void dispatchPropertyChanges(const AbstractProperty &abstractProperty); @@ -61,7 +61,7 @@ protected: QHash roleNames() const override; private: - std::optional findRow(int nodeId, const PropertyName &name) const; + std::optional findRow(int nodeId, PropertyNameView name) const; DynamicPropertiesItem *itemForRow(int row) const; DynamicPropertiesItem *itemForProperty(const AbstractProperty &property) const; ModelNode modelNodeForItem(DynamicPropertiesItem *item); diff --git a/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.cpp index cefaf69506d..d9d4e04eac7 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -519,47 +519,51 @@ const std::vector PropertyTreeModel::sortedAndFilteredPropertyName const std::vector PropertyTreeModel::getDynamicProperties( const ModelNode &modelNode) const { - QList list = Utils::transform(modelNode.dynamicProperties(), - [](const AbstractProperty &property) { - return property.name(); - }); + auto dynamicProperties = modelNode.dynamicProperties(); + auto dynamicPropertyNames = Utils::transform( + dynamicProperties, [](const AbstractProperty &property) { return property.name(); }); - QList filtered - = Utils::filtered(list, [this, modelNode](const PropertyName &propertyName) { - PropertyName propertyType = modelNode.property(propertyName).dynamicTypeName(); - switch (m_type) { - case AllTypes: - return true; - case NumberType: - return propertyType == "float" || propertyType == "double" - || propertyType == "int"; - case StringType: - return propertyType == "string"; - case UrlType: - return propertyType == "url"; - case ColorType: - return propertyType == "color"; - case BoolType: - return propertyType == "bool"; - default: - break; - } - return true; - }); + auto filtered = Utils::filtered(dynamicPropertyNames, [this, modelNode](PropertyNameView propertyName) { + TypeName propertyType = modelNode.property(propertyName).dynamicTypeName(); + switch (m_type) { + case AllTypes: + return true; + case NumberType: + return propertyType == "float" || propertyType == "double" || propertyType == "int"; + case StringType: + return propertyType == "string"; + case UrlType: + return propertyType == "url"; + case ColorType: + return propertyType == "color"; + case BoolType: + return propertyType == "bool"; + default: + break; + } + return true; + }); - return Utils::sorted(std::vector(filtered.begin(), filtered.end())); + auto sorted = Utils::sorted(filtered); + + return Utils::transform>(sorted, [](PropertyNameView propertyName) { + return propertyName.toByteArray(); + }); } const std::vector PropertyTreeModel::getDynamicSignals(const ModelNode &modelNode) const { - QList list = Utils::transform(modelNode.dynamicProperties(), - [](const AbstractProperty &property) { - if (property.isSignalDeclarationProperty()) - return property.name(); + auto list = Utils::transform>( + modelNode.dynamicProperties(), [](const AbstractProperty &property) -> PropertyName { + if (property.isSignalDeclarationProperty()) + return property.name().toByteArray(); - return PropertyName(property.name() + "Changed"); - }); - return Utils::sorted(std::vector(list.begin(), list.end())); + return property.name().toByteArray() + "Changed"; + }); + + std::sort(list.begin(), list.end()); + + return list; } const std::vector PropertyTreeModel::sortedAndFilteredPropertyNames( diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.cpp index 6388c93fa96..364a092a538 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.cpp @@ -11,7 +11,9 @@ #include #include +#include #include +#include #include #include @@ -21,10 +23,11 @@ using namespace Utils; namespace QmlDesigner { +static constexpr int normalImportDelay = 200; + ContentLibraryBundleImporter::ContentLibraryBundleImporter(QObject *parent) : QObject(parent) { - m_importTimer.setInterval(200); connect(&m_importTimer, &QTimer::timeout, this, &ContentLibraryBundleImporter::handleImportTimer); } @@ -49,19 +52,21 @@ QString ContentLibraryBundleImporter::importComponent(const QString &bundleDir, if (!bundleImportPath.exists() && !bundleImportPath.createDir()) return QStringLiteral("Failed to create bundle import folder: '%1'").arg(bundleImportPath.toString()); + bool doScan = false; + bool doReset = false; FilePath qmldirPath = bundleImportPath.pathAppended("qmldir"); QString qmldirContent = QString::fromUtf8(qmldirPath.fileContents().value_or(QByteArray())); if (qmldirContent.isEmpty()) { qmldirContent.append("module "); qmldirContent.append(module); qmldirContent.append('\n'); + doScan = true; } FilePath qmlSourceFile = bundleImportPath.pathAppended(qmlFile); - const bool qmlFileExists = qmlSourceFile.exists(); const QString qmlType = qmlSourceFile.baseName(); - if (m_pendingTypes.contains(type) && !m_pendingTypes.value(type)) + if (m_pendingImports.contains(type) && !m_pendingImports[type].isImport) return QStringLiteral("Unable to import while unimporting the same type: '%1'").arg(QLatin1String(type)); if (!qmldirContent.contains(qmlFile)) { @@ -70,6 +75,7 @@ QString ContentLibraryBundleImporter::importComponent(const QString &bundleDir, qmldirContent.append(qmlFile); qmldirContent.append('\n'); qmldirPath.writeFileContents(qmldirContent.toUtf8()); + doReset = true; } QStringList allFiles; @@ -104,16 +110,22 @@ QString ContentLibraryBundleImporter::importComponent(const QString &bundleDir, if (writeAssetRefs) writeAssetRefMap(bundleImportPath, assetRefMap); - m_fullReset = !qmlFileExists; auto doc = QmlDesignerPlugin::instance()->currentDesignDocument(); Model *model = doc ? doc->currentModel() : nullptr; if (!model) return "Model not available, cannot add import statement or update code model"; + ImportData data; + data.isImport = true; + data.type = type; + if (doScan) + data.pathToScan = bundleImportPath; + else + data.fullReset = doReset; + Import import = Import::createLibraryImport(module, "1.0"); if (!model->hasImport(import)) { if (model->possibleImports().contains(import)) { - m_pendingImport.clear(); try { model->changeImports({import}, {}); } catch (const RewritingException &) { @@ -123,12 +135,12 @@ QString ContentLibraryBundleImporter::importComponent(const QString &bundleDir, } else { // If import is not yet possible, import statement needs to be added asynchronously to // avoid errors, as code model update takes a while. - m_pendingImport = module; + data.importToAdd = module; } } - m_pendingTypes.insert(type, true); + m_pendingImports.insert(type, data); m_importTimerCount = 0; - m_importTimer.start(); + m_importTimer.start(normalImportDelay); return {}; } @@ -137,21 +149,20 @@ void ContentLibraryBundleImporter::handleImportTimer() { auto handleFailure = [this] { m_importTimer.stop(); - m_fullReset = false; - m_pendingImport.clear(); m_importTimerCount = 0; + disconnect(m_libInfoConnection); + // Emit dummy finished signals for all pending types - const QList pendingTypes = m_pendingTypes.keys(); + const QList pendingTypes = m_pendingImports.keys(); for (const TypeName &pendingType : pendingTypes) { - m_pendingTypes.remove(pendingType); - if (m_pendingTypes.value(pendingType)) + ImportData data = m_pendingImports.take(pendingType); + if (data.isImport) emit importFinished({}, m_bundleId); else emit unimportFinished({}, m_bundleId); - - m_bundleId.clear(); } + m_bundleId.clear(); }; auto doc = QmlDesignerPlugin::instance()->currentDesignDocument(); @@ -161,55 +172,125 @@ void ContentLibraryBundleImporter::handleImportTimer() return; } - if (m_fullReset) { - // Force code model reset to notice changes to existing module - auto modelManager = QmlJS::ModelManagerInterface::instance(); - if (modelManager) - modelManager->resetCodeModel(); - m_fullReset = false; - return; - } - - QmlDesignerPlugin::instance()->documentManager().resetPossibleImports(); - - if (!m_pendingImport.isEmpty()) { - try { - Import import = Import::createLibraryImport(m_pendingImport, "1.0"); - if (model->possibleImports().contains(import)) { - model->changeImports({import}, {}); - m_pendingImport.clear(); + auto modelManager = QmlJS::ModelManagerInterface::instance(); + if (modelManager) { + const QList keys = m_pendingImports.keys(); + int scanDone = 0; + bool refreshImports = false; + for (const TypeName &type : keys) { + ImportData &data = m_pendingImports[type]; + if (data.state == ImportData::Starting) { + if (data.pathToScan.isEmpty()) { + data.state = ImportData::FullReset; + } else { + // A new bundle module was added, so we can scan it without doing full code + // model reset, which is faster + QmlJS::PathsAndLanguages pathToScan; + pathToScan.maybeInsert(data.pathToScan); + data.future = Utils::asyncRun(&QmlJS::ModelManagerInterface::importScan, + modelManager->workingCopy(), + pathToScan, modelManager, + true, true, true); + data.state = ImportData::WaitingForImportScan; + } + } else if (data.state == ImportData::WaitingForImportScan) { + // Import scan is asynchronous, so we need to wait for it to be finished + if ((data.future.isCanceled() || data.future.isFinished())) + data.state = ImportData::RefreshImports; + } else if (data.state >= ImportData::RefreshImports) { + // Do not mode to next stage until all pending scans are done + ++scanDone; + if (data.state == ImportData::RefreshImports) + refreshImports = true; } - } catch (const RewritingException &) { - // Import adding is unlikely to succeed later, either, so just bail out - handleFailure(); } - return; - } + if (scanDone != m_pendingImports.size()) { + return; + } else { + if (refreshImports) { + // The new import is now available in code model, so reset the possible imports + QmlDesignerPlugin::instance()->documentManager().resetPossibleImports(); + model->rewriterView()->forceAmend(); - // Detect when the code model has the new material(s) fully available - const QList pendingTypes = m_pendingTypes.keys(); - for (const TypeName &pendingType : pendingTypes) { - NodeMetaInfo metaInfo = model->metaInfo(pendingType); - const bool isImport = m_pendingTypes.value(pendingType); - const bool typeComplete = metaInfo.isValid() && !metaInfo.prototypes().empty(); - if (isImport == typeComplete) { - m_pendingTypes.remove(pendingType); - if (isImport) + for (const TypeName &type : keys) { + ImportData &data = m_pendingImports[type]; + if (data.state == ImportData::RefreshImports) { + if (!data.importToAdd.isEmpty()) { + try { + RewriterTransaction transaction = model->rewriterView()->beginRewriterTransaction( + QByteArrayLiteral(__FUNCTION__)); + bool success = ModelUtils::addImportWithCheck(data.importToAdd, model); + if (!success) + handleFailure(); + transaction.commit(); + } catch (const RewritingException &) { + handleFailure(); + } + } + } + data.state = ImportData::FullReset; + } + return; + } + + bool fullReset = false; + for (const TypeName &type : keys) { + ImportData &data = m_pendingImports[type]; + if (data.state == ImportData::FullReset) { + if (data.fullReset) + fullReset = true; + data.state = ImportData::Finalize; + } + } + if (fullReset) { + // Force code model reset to notice changes to existing module + auto modelManager = QmlJS::ModelManagerInterface::instance(); + if (modelManager) { + modelManager->resetCodeModel(); + disconnect(m_libInfoConnection); + m_libInfoConnection = connect(modelManager, &QmlJS::ModelManagerInterface::libraryInfoUpdated, + this, [this]() { + // This signal comes for each library in code model, so we need to compress + // it until no more notifications come + m_importTimer.start(1000); + }, Qt::QueuedConnection); + // Stop the import timer for a bit to allow full reset to complete + m_importTimer.stop(); + } + return; + } + + for (const TypeName &type : keys) { + ImportData &data = m_pendingImports[type]; + if (data.state == ImportData::Finalize) { + // Reset delay just in case full reset was done earlier + m_importTimer.start(normalImportDelay); + disconnect(m_libInfoConnection); + model->rewriterView()->forceAmend(); + // Verify that code model has the new material fully available (or removed for unimport) + NodeMetaInfo metaInfo = model->metaInfo(type); + const bool typeComplete = metaInfo.isValid() && !metaInfo.prototypes().empty(); + if (data.isImport == typeComplete) { + m_pendingImports.remove(type); + if (data.isImport) #ifdef QDS_USE_PROJECTSTORAGE - emit importFinished(pendingType, m_bundleId); + emit importFinished(type, m_bundleId); #else - emit importFinished(metaInfo, m_bundleId); + emit importFinished(metaInfo, m_bundleId); #endif - else - emit unimportFinished(metaInfo, m_bundleId); - - m_bundleId.clear(); + else + emit unimportFinished(metaInfo, m_bundleId); + } + } + } } } - if (m_pendingTypes.isEmpty()) { + if (m_pendingImports.isEmpty()) { + m_bundleId.clear(); m_importTimer.stop(); m_importTimerCount = 0; + disconnect(m_libInfoConnection); } } @@ -267,7 +348,7 @@ QString ContentLibraryBundleImporter::unimportComponent(const TypeName &type, co QByteArray newContent; QString qmlType = qmlFilePath.baseName(); - if (m_pendingTypes.contains(type) && m_pendingTypes.value(type)) { + if (m_pendingImports.contains(type) && m_pendingImports[type].isImport) { return QStringLiteral("Unable to unimport while importing the same type: '%1'") .arg(QString::fromLatin1(type)); } @@ -286,8 +367,6 @@ QString ContentLibraryBundleImporter::unimportComponent(const TypeName &type, co } } - m_pendingTypes.insert(type, false); - QVariantHash assetRefMap = loadAssetRefMap(bundleImportPath); bool writeAssetRefs = false; const auto keys = assetRefMap.keys(); @@ -326,9 +405,14 @@ QString ContentLibraryBundleImporter::unimportComponent(const TypeName &type, co } } - m_fullReset = true; + ImportData data; + data.isImport = false; + data.type = type; + data.fullReset = true; + m_pendingImports.insert(type, data); + m_importTimerCount = 0; - m_importTimer.start(); + m_importTimer.start(normalImportDelay); return {}; } diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.h index 8155311e3e4..dc3fdf4c8c8 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.h @@ -7,6 +7,7 @@ #include +#include #include #include @@ -46,10 +47,27 @@ private: QTimer m_importTimer; int m_importTimerCount = 0; - QString m_pendingImport; QString m_bundleId; - bool m_fullReset = false; - QHash m_pendingTypes; // + struct ImportData + { + enum State { + Starting, + WaitingForImportScan, + RefreshImports, + FullReset, + Finalize + }; + bool isImport = true; // false = unimport + TypeName type; + Utils::FilePath pathToScan; // If set, do importScan + QFuture future; + QString importToAdd; // If set, add import to model + bool fullReset = false; // If true, reset the entire code model. + State state = Starting; + }; + + QHash m_pendingImports; + QMetaObject::Connection m_libInfoConnection; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp index e0fe2b6c54e..d9f8bd4950d 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp @@ -93,11 +93,9 @@ QHash ContentLibraryEffectsModel::roleNames() const return roles; } -void ContentLibraryEffectsModel::loadBundle() +void ContentLibraryEffectsModel::loadBundle(bool force) { - auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); - - if (m_probeBundleDir || (m_bundleExists && m_bundleId == compUtils.effectsBundleId())) + if (m_probeBundleDir && !force) return; // clean up @@ -148,6 +146,7 @@ void ContentLibraryEffectsModel::loadBundle() m_bundleObj = bundleJsonDoc.object(); + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); QString bundleType = compUtils.effectsBundleType(); m_bundleId = compUtils.effectsBundleId(); @@ -171,17 +170,14 @@ void ContentLibraryEffectsModel::loadBundle() TypeName type = QLatin1String("%1.%2") .arg(bundleType, qml.chopped(4)).toLatin1(); // chopped(4): remove .qml - auto bundleItem = new ContentLibraryItem(category, itemName, qml, type, icon, files); + auto bundleItem = new ContentLibraryItem(category, itemName, qml, type, icon, files, m_bundleId); category->addBundleItem(bundleItem); } m_bundleCategories.append(category); } - m_bundleSharedFiles.clear(); - const QJsonArray sharedFilesArr = m_bundleObj.value("sharedFiles").toArray(); - for (const QJsonValueConstRef &file : sharedFilesArr) - m_bundleSharedFiles.append(file.toString()); + m_bundleSharedFiles = m_bundleObj.value("sharedFiles").toVariant().toStringList(); m_bundlePath = bundleDir.path(); m_bundleExists = true; diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.h index 5bcb857fca5..2063668ba99 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.h @@ -28,7 +28,7 @@ public: bool setData(const QModelIndex &index, const QVariant &value, int role) override; QHash roleNames() const override; - void loadBundle(); + void loadBundle(bool force = false); void setSearchText(const QString &searchText); void updateImportedState(const QStringList &importedItems); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.cpp index 96102bf8379..f81d8cc6ea0 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.cpp @@ -7,21 +7,18 @@ namespace QmlDesigner { -namespace Internal { - ContentLibraryIconProvider::ContentLibraryIconProvider() : QQuickImageProvider(Pixmap) { - } QPixmap ContentLibraryIconProvider::requestPixmap(const QString &id, QSize *size, [[maybe_unused]] const QSize &requestedSize) { - QString realPath = Core::ICore::resourcePath("qmldesigner/contentLibraryImages/" + id).toString(); + QString imagePath = Core::ICore::resourcePath("qmldesigner/contentLibraryImages/" + id).toFSPathString(); - QPixmap pixmap{realPath}; + QPixmap pixmap{imagePath}; if (size) { size->setWidth(pixmap.width()); @@ -37,6 +34,4 @@ QPixmap ContentLibraryIconProvider::requestPixmap(const QString &id, return pixmap; } -} // namespace Internal - } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.h index 56633959d6a..644d0332120 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.h @@ -5,7 +5,7 @@ #include -namespace QmlDesigner::Internal { +namespace QmlDesigner { class ContentLibraryIconProvider : public QQuickImageProvider { @@ -14,4 +14,4 @@ public: QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override; }; -} // namespace QmlDesigner::Internal +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryitem.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryitem.cpp index 38fb69abbc2..90e80ebadf6 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryitem.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryitem.cpp @@ -10,11 +10,11 @@ ContentLibraryItem::ContentLibraryItem(QObject *parent, const QString &qml, const TypeName &type, const QUrl &icon, - const QStringList &files) - : QObject(parent), m_name(name), m_qml(qml), m_type(type), m_icon(icon), m_files(files) + const QStringList &files, + const QString &bundleId) + : QObject(parent), m_name(name), m_qml(qml), m_type(type), m_icon(icon), m_files(files), + m_bundleId(bundleId) { - m_allFiles = m_files; - m_allFiles.push_back(m_qml); } bool ContentLibraryItem::filter(const QString &searchText) @@ -68,9 +68,9 @@ bool ContentLibraryItem::imported() const return m_imported; } -QStringList ContentLibraryItem::allFiles() const +QString ContentLibraryItem::bundleId() const { - return m_allFiles; + return m_bundleId; } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryitem.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryitem.h index bdf87367281..89d00de1cd5 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryitem.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryitem.h @@ -16,10 +16,9 @@ class ContentLibraryItem : public QObject Q_PROPERTY(QString bundleItemName MEMBER m_name CONSTANT) Q_PROPERTY(QUrl bundleItemIcon MEMBER m_icon CONSTANT) - Q_PROPERTY(QStringList bundleItemFiles READ allFiles CONSTANT) Q_PROPERTY(bool bundleItemVisible MEMBER m_visible NOTIFY itemVisibleChanged) Q_PROPERTY(bool bundleItemImported READ imported WRITE setImported NOTIFY itemImportedChanged) - Q_PROPERTY(QString itemType MEMBER m_itemType CONSTANT) + Q_PROPERTY(QString bundleId READ bundleId CONSTANT) public: ContentLibraryItem(QObject *parent, @@ -27,7 +26,8 @@ public: const QString &qml, const TypeName &type, const QUrl &icon, - const QStringList &files); + const QStringList &files, + const QString &bundleId); bool filter(const QString &searchText); @@ -37,9 +37,10 @@ public: QStringList files() const; bool visible() const; + QString bundleId() const; + bool setImported(bool imported); bool imported() const; - QStringList allFiles() const; signals: void itemVisibleChanged(); @@ -55,8 +56,7 @@ private: bool m_visible = true; bool m_imported = false; - QStringList m_allFiles; - const QString m_itemType = "item"; + const QString m_bundleId; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.cpp index 25d15231991..bb0bd54166f 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.cpp @@ -3,8 +3,6 @@ #include "contentlibrarymaterial.h" -#include - namespace QmlDesigner { ContentLibraryMaterial::ContentLibraryMaterial(QObject *parent, @@ -13,10 +11,9 @@ ContentLibraryMaterial::ContentLibraryMaterial(QObject *parent, const TypeName &type, const QUrl &icon, const QStringList &files, - const QString &downloadPath, - const QString &baseWebUrl) + const QString &bundleId) : QObject(parent), m_name(name), m_qml(qml), m_type(type), m_icon(icon), m_files(files) - , m_downloadPath(downloadPath), m_baseWebUrl(baseWebUrl) + , m_bundleId(bundleId) { m_allFiles = m_files; m_allFiles.push_back(m_qml); @@ -78,25 +75,14 @@ bool ContentLibraryMaterial::imported() const return m_imported; } -bool ContentLibraryMaterial::isDownloaded() const -{ - QString fullPath = qmlFilePath(); - return QFileInfo(fullPath).isFile(); -} - -QString ContentLibraryMaterial::qmlFilePath() const -{ - return m_downloadPath + "/" + m_qml; -} - -QString ContentLibraryMaterial::dirPath() const -{ - return m_downloadPath; -} - QStringList ContentLibraryMaterial::allFiles() const { return m_allFiles; } +QString ContentLibraryMaterial::bundleId() const +{ + return m_bundleId; +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.h index aaaf9517f99..5b6c86b47ef 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.h @@ -18,10 +18,8 @@ class ContentLibraryMaterial : public QObject Q_PROPERTY(QUrl bundleMaterialIcon MEMBER m_icon CONSTANT) Q_PROPERTY(bool bundleMaterialVisible MEMBER m_visible NOTIFY materialVisibleChanged) Q_PROPERTY(bool bundleItemImported READ imported WRITE setImported NOTIFY materialImportedChanged) - Q_PROPERTY(QString bundleMaterialBaseWebUrl MEMBER m_baseWebUrl CONSTANT) - Q_PROPERTY(QString bundleMaterialDirPath READ dirPath CONSTANT) Q_PROPERTY(QStringList bundleMaterialFiles READ allFiles CONSTANT) - Q_PROPERTY(QString itemType MEMBER m_itemType CONSTANT) + Q_PROPERTY(QString bundleId READ bundleId CONSTANT) public: ContentLibraryMaterial(QObject *parent, @@ -30,26 +28,23 @@ public: const TypeName &type, const QUrl &icon, const QStringList &files, - const QString &downloadPath, - const QString &baseWebUrl = {}); + const QString &bundleId); bool filter(const QString &searchText); - Q_INVOKABLE bool isDownloaded() const; - QString name() const; QUrl icon() const; QString qml() const; TypeName type() const; QStringList files() const; bool visible() const; - QString qmlFilePath() const; bool setImported(bool imported); bool imported() const; - QString dirPath() const; QStringList allFiles() const; + QString bundleId() const; + signals: void materialVisibleChanged(); void materialImportedChanged(); @@ -64,10 +59,8 @@ private: bool m_visible = true; bool m_imported = false; - QString m_downloadPath; - QString m_baseWebUrl; QStringList m_allFiles; - const QString m_itemType = "material"; + const QString m_bundleId; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp index adb47108a9a..d162857fbb7 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -33,7 +32,7 @@ ContentLibraryMaterialsModel::ContentLibraryMaterialsModel(ContentLibraryWidget : QAbstractListModel(parent) , m_widget(parent) { - m_downloadPath = Paths::bundlesPathSetting() + "/Materials"; + m_bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/Materials"); m_baseUrl = QmlDesignerPlugin::settings() .value(DesignerSettingsKey::DOWNLOADABLE_BUNDLES_URL) @@ -45,9 +44,8 @@ ContentLibraryMaterialsModel::ContentLibraryMaterialsModel(ContentLibraryWidget void ContentLibraryMaterialsModel::loadBundle() { - QDir bundleDir{m_downloadPath}; - if (fetchBundleMetadata(bundleDir) && fetchBundleIcons(bundleDir)) - loadMaterialBundle(bundleDir); + if (fetchBundleJsonFile() && fetchBundleIcons()) + loadMaterialBundle(); } int ContentLibraryMaterialsModel::rowCount(const QModelIndex &) const @@ -114,13 +112,14 @@ QHash ContentLibraryMaterialsModel::roleNames() const return roles; } -bool ContentLibraryMaterialsModel::fetchBundleIcons(const QDir &bundleDir) +bool ContentLibraryMaterialsModel::fetchBundleIcons() { - QString iconsPath = bundleDir.filePath("icons"); + Utils::FilePath iconsFilePath = m_bundlePath.pathAppended("icons"); - QDir iconsDir(iconsPath); - if (iconsDir.exists() && iconsDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot).length() > 0) + if (iconsFilePath.exists() && iconsFilePath.dirEntries(QDir::Files | QDir::Dirs + | QDir::NoDotAndDotDot).length() > 0) { return true; + } QString zipFileUrl = m_baseUrl + "/icons.zip"; @@ -130,20 +129,20 @@ bool ContentLibraryMaterialsModel::fetchBundleIcons(const QDir &bundleDir) downloader->setDownloadEnabled(true); QObject::connect(downloader, &FileDownloader::finishedChanged, this, - [this, downloader, bundleDir] { + [this, downloader] { FileExtractor *extractor = new FileExtractor(this); extractor->setArchiveName(downloader->completeBaseName()); extractor->setSourceFile(downloader->outputFile()); - extractor->setTargetPath(bundleDir.absolutePath()); + extractor->setTargetPath(m_bundlePath.toFSPathString()); extractor->setAlwaysCreateDir(false); extractor->setClearTargetPathContents(false); QObject::connect(extractor, &FileExtractor::finishedChanged, this, - [this, downloader, bundleDir, extractor] { + [this, downloader, extractor] { downloader->deleteLater(); extractor->deleteLater(); - loadMaterialBundle(bundleDir); + loadMaterialBundle(); }); extractor->extract(); @@ -153,25 +152,25 @@ bool ContentLibraryMaterialsModel::fetchBundleIcons(const QDir &bundleDir) return false; } -bool ContentLibraryMaterialsModel::fetchBundleMetadata(const QDir &bundleDir) +bool ContentLibraryMaterialsModel::fetchBundleJsonFile() { - QString matBundlePath = bundleDir.filePath("material_bundle.json"); + Utils::FilePath jsonFilePath = m_bundlePath.pathAppended("material_bundle.json"); - QFileInfo fi(matBundlePath); - if (fi.exists() && fi.size() > 0) + if (jsonFilePath.exists() && jsonFilePath.fileSize() > 0) return true; - QString metaFileUrl = m_baseUrl + "/material_bundle.json"; + QString bundleJsonUrl = m_baseUrl + "/material_bundle.json"; + FileDownloader *downloader = new FileDownloader(this); - downloader->setUrl(metaFileUrl); + downloader->setUrl(bundleJsonUrl); downloader->setProbeUrl(false); downloader->setDownloadEnabled(true); - downloader->setTargetFilePath(matBundlePath); + downloader->setTargetFilePath(jsonFilePath.toFSPathString()); QObject::connect(downloader, &FileDownloader::finishedChanged, this, - [this, downloader, bundleDir] { - if (fetchBundleIcons(bundleDir)) - loadMaterialBundle(bundleDir); + [this, downloader] { + if (fetchBundleIcons()) + loadMaterialBundle(); downloader->deleteLater(); }); @@ -179,7 +178,7 @@ bool ContentLibraryMaterialsModel::fetchBundleMetadata(const QDir &bundleDir) return false; } -void ContentLibraryMaterialsModel::downloadSharedFiles(const QDir &targetDir, const QStringList &) +void ContentLibraryMaterialsModel::downloadSharedFiles() { QString metaFileUrl = m_baseUrl + "/shared_files.zip"; FileDownloader *downloader = new FileDownloader(this); @@ -188,11 +187,11 @@ void ContentLibraryMaterialsModel::downloadSharedFiles(const QDir &targetDir, co downloader->setDownloadEnabled(true); QObject::connect(downloader, &FileDownloader::finishedChanged, this, - [this, downloader, targetDir] { + [this, downloader] { FileExtractor *extractor = new FileExtractor(this); extractor->setArchiveName(downloader->completeBaseName()); extractor->setSourceFile(downloader->outputFile()); - extractor->setTargetPath(targetDir.absolutePath()); + extractor->setTargetPath(m_bundlePath.toFSPathString()); extractor->setAlwaysCreateDir(false); extractor->setClearTargetPathContents(false); @@ -212,11 +211,11 @@ QString ContentLibraryMaterialsModel::bundleId() const return m_bundleId; } -void ContentLibraryMaterialsModel::loadMaterialBundle(const QDir &bundleDir) +void ContentLibraryMaterialsModel::loadMaterialBundle(bool forceReload) { auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); - if (m_bundleExists && m_bundleId == compUtils.materialsBundleId()) + if (!forceReload && m_bundleExists && m_bundleId == compUtils.materialsBundleId()) return; // clean up @@ -227,18 +226,18 @@ void ContentLibraryMaterialsModel::loadMaterialBundle(const QDir &bundleDir) m_bundleObj = {}; m_bundleId.clear(); - QString bundlePath = bundleDir.filePath("material_bundle.json"); + Utils::FilePath jsonFilePath = m_bundlePath.pathAppended("material_bundle.json"); - QFile bundleFile(bundlePath); - if (!bundleFile.open(QIODevice::ReadOnly)) { - qWarning("Couldn't open material_bundle.json"); + Utils::expected_str jsonContents = jsonFilePath.fileContents(); + if (!jsonContents.has_value()) { + qWarning() << __FUNCTION__ << jsonContents.error(); resetModel(); return; } - QJsonDocument bundleJsonDoc = QJsonDocument::fromJson(bundleFile.readAll()); + QJsonDocument bundleJsonDoc = QJsonDocument::fromJson(jsonContents.value()); if (bundleJsonDoc.isNull()) { - qWarning("Invalid material_bundle.json file"); + qWarning() << __FUNCTION__ << "Invalid json file" << jsonFilePath; resetModel(); return; } @@ -258,38 +257,38 @@ void ContentLibraryMaterialsModel::loadMaterialBundle(const QDir &bundleDir) for (const QString &matName : matsNames) { const QJsonObject matObj = matsObj.value(matName).toObject(); + if (matObj.contains("minQtVersion")) { + const Version minQtVersion = Version::fromString( + matObj.value("minQtVersion").toString()); + if (minQtVersion > m_quick3dVersion) + continue; + } + QStringList files; const QJsonArray assetsArr = matObj.value("files").toArray(); for (const QJsonValueConstRef &asset : assetsArr) files.append(asset.toString()); - QUrl icon = QUrl::fromLocalFile(bundleDir.filePath(matObj.value("icon").toString())); + QUrl icon = m_bundlePath.pathAppended(matObj.value("icon").toString()).toUrl(); QString qml = matObj.value("qml").toString(); - TypeName type = QLatin1String("%1.%2") - .arg(bundleType, qml.chopped(4)).toLatin1(); // chopped(4): remove .qml + TypeName type = QLatin1String("%1.%2").arg(bundleType, qml.chopped(4)).toLatin1(); // chopped(4): remove .qml auto bundleMat = new ContentLibraryMaterial(category, matName, qml, type, icon, files, - m_downloadPath, m_baseUrl); + m_bundleId); category->addBundleMaterial(bundleMat); } m_bundleCategories.append(category); } - m_bundleSharedFiles.clear(); - const QJsonArray sharedFilesArr = m_bundleObj.value("sharedFiles").toArray(); - for (const QJsonValueConstRef &file : sharedFilesArr) - m_bundleSharedFiles.append(file.toString()); - - QStringList missingSharedFiles; - for (const QString &s : std::as_const(m_bundleSharedFiles)) { - if (!QFileInfo::exists(bundleDir.filePath(s))) - missingSharedFiles.push_back(s); + m_bundleSharedFiles = m_bundleObj.value("sharedFiles").toVariant().toStringList(); + for (const QString &file : std::as_const(m_bundleSharedFiles)) { + if (!m_bundlePath.pathAppended(file).exists()) { + downloadSharedFiles(); + break; + } } - if (missingSharedFiles.length() > 0) - downloadSharedFiles(bundleDir, missingSharedFiles); - m_bundleExists = true; updateIsEmpty(); resetModel(); @@ -297,7 +296,7 @@ void ContentLibraryMaterialsModel::loadMaterialBundle(const QDir &bundleDir) bool ContentLibraryMaterialsModel::hasRequiredQuick3DImport() const { - return m_widget->hasQuick3DImport() && m_quick3dMajorVersion == 6 && m_quick3dMinorVersion >= 3; + return m_widget->hasQuick3DImport() && m_quick3dVersion >= Version{6, 3}; } bool ContentLibraryMaterialsModel::matBundleExists() const @@ -305,6 +304,11 @@ bool ContentLibraryMaterialsModel::matBundleExists() const return m_bundleExists; } +QString ContentLibraryMaterialsModel::bundlePath() const +{ + return m_bundlePath.toFSPathString(); +} + void ContentLibraryMaterialsModel::setSearchText(const QString &searchText) { QString lowerSearchText = searchText.toLower(); @@ -338,8 +342,11 @@ void ContentLibraryMaterialsModel::setQuick3DImportVersion(int major, int minor) { bool oldRequiredImport = hasRequiredQuick3DImport(); - m_quick3dMajorVersion = major; - m_quick3dMinorVersion = minor; + const Version newVersion{major, minor}; + if (m_quick3dVersion != newVersion) { + m_quick3dVersion = newVersion; + loadMaterialBundle(true); + } bool newRequiredImport = hasRequiredQuick3DImport(); @@ -364,8 +371,8 @@ void ContentLibraryMaterialsModel::applyToSelected(ContentLibraryMaterial *mat, void ContentLibraryMaterialsModel::addToProject(ContentLibraryMaterial *mat) { - QString err = m_widget->importer()->importComponent(mat->dirPath(), mat->type(), mat->qml(), - mat->files() + m_bundleSharedFiles); + QString err = m_widget->importer()->importComponent(m_bundlePath.toFSPathString(), mat->type(), + mat->qml(), mat->files() + m_bundleSharedFiles); if (err.isEmpty()) m_widget->setImporterRunning(true); @@ -383,4 +390,9 @@ void ContentLibraryMaterialsModel::removeFromProject(ContentLibraryMaterial *mat qWarning() << __FUNCTION__ << err; } +bool ContentLibraryMaterialsModel::isMaterialDownloaded(ContentLibraryMaterial *mat) const +{ + return m_bundlePath.pathAppended(mat->qml()).exists(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h index c0840dc3cc7..68c79607941 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h @@ -3,11 +3,12 @@ #pragma once +#include +#include + #include #include -QT_FORWARD_DECLARE_CLASS(QDir) - namespace QmlDesigner { class ContentLibraryMaterial; @@ -21,6 +22,8 @@ class ContentLibraryMaterialsModel : public QAbstractListModel Q_PROPERTY(bool matBundleExists READ matBundleExists NOTIFY matBundleExistsChanged) Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged) Q_PROPERTY(bool hasRequiredQuick3DImport READ hasRequiredQuick3DImport NOTIFY hasRequiredQuick3DImportChanged) + Q_PROPERTY(QString baseWebUrl MEMBER m_baseUrl CONSTANT) + Q_PROPERTY(QString bundlePath READ bundlePath CONSTANT) public: ContentLibraryMaterialsModel(ContentLibraryWidget *parent = nullptr); @@ -37,6 +40,8 @@ public: bool hasRequiredQuick3DImport() const; bool matBundleExists() const; + QString bundlePath() const; + void resetModel(); void updateIsEmpty(); void loadBundle(); @@ -44,6 +49,7 @@ public: Q_INVOKABLE void applyToSelected(QmlDesigner::ContentLibraryMaterial *mat, bool add = false); Q_INVOKABLE void addToProject(QmlDesigner::ContentLibraryMaterial *mat); Q_INVOKABLE void removeFromProject(QmlDesigner::ContentLibraryMaterial *mat); + Q_INVOKABLE bool isMaterialDownloaded(QmlDesigner::ContentLibraryMaterial *mat) const; QString bundleId() const; @@ -55,11 +61,11 @@ signals: void matBundleExistsChanged(); private: - void loadMaterialBundle(const QDir &matBundleDir); - bool fetchBundleIcons(const QDir &bundleDir); - bool fetchBundleMetadata(const QDir &bundleDir); + void loadMaterialBundle(bool forceReload = false); + bool fetchBundleIcons(); + bool fetchBundleJsonFile(); bool isValidIndex(int idx) const; - void downloadSharedFiles(const QDir &targetDir, const QStringList &files); + void downloadSharedFiles(); ContentLibraryWidget *m_widget = nullptr; QString m_searchText; @@ -71,10 +77,8 @@ private: bool m_isEmpty = true; bool m_bundleExists = false; - int m_quick3dMajorVersion = -1; - int m_quick3dMinorVersion = -1; - - QString m_downloadPath; + Version m_quick3dVersion; + Utils::FilePath m_bundlePath; QString m_baseUrl; }; diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp index d2c2df2baaf..90ab7698a77 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp @@ -78,17 +78,17 @@ QString ContentLibraryTexture::resolveToolTipText() if (m_suffix.isEmpty()) return m_baseName; // empty suffix means we have just the icon and no other data - QString fileName = m_baseName + m_suffix; + QString texFileName = fileName(); QString imageInfo; if (!m_isDownloaded && m_sizeInBytes > 0 && !m_dimensions.isNull()) { imageInfo = ImageUtils::imageInfoString(m_dimensions, m_sizeInBytes); } else { - QString fullDownloadPath = m_dirPath + '/' + fileName; + QString fullDownloadPath = m_dirPath + '/' + texFileName; imageInfo = ImageUtils::imageInfoString(fullDownloadPath); } - return QString("%1\n%2").arg(fileName, imageInfo); + return QString("%1\n%2").arg(texFileName, imageInfo); } bool ContentLibraryTexture::isDownloaded() const @@ -98,7 +98,7 @@ bool ContentLibraryTexture::isDownloaded() const QString ContentLibraryTexture::texturePath() const { - return m_dirPath + '/' + m_baseName + m_suffix; + return m_dirPath + '/' + fileName(); } void ContentLibraryTexture::setDownloaded() @@ -135,6 +135,11 @@ QString ContentLibraryTexture::textureKey() const return m_textureKey; } +QString ContentLibraryTexture::fileName() const +{ + return m_baseName + m_suffix; +} + void ContentLibraryTexture::setHasUpdate(bool value) { if (m_hasUpdate != value) { diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.h index 7f5db6d7d60..bc7c667dd40 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.h @@ -24,7 +24,7 @@ class ContentLibraryTexture : public QObject Q_PROPERTY(bool textureHasUpdate WRITE setHasUpdate READ hasUpdate NOTIFY hasUpdateChanged) Q_PROPERTY(bool textureIsNew MEMBER m_isNew CONSTANT) Q_PROPERTY(QString textureKey MEMBER m_textureKey CONSTANT) - Q_PROPERTY(QString itemType MEMBER m_itemType CONSTANT) + Q_PROPERTY(QString bundleId MEMBER m_bundleId CONSTANT) public: ContentLibraryTexture(QObject *parent, const QFileInfo &iconFileInfo, const QString &dirPath, @@ -42,6 +42,7 @@ public: QString texturePath() const; QString parentDirPath() const; QString textureKey() const; + QString fileName() const; void setHasUpdate(bool value); bool hasUpdate() const; @@ -74,7 +75,7 @@ private: bool m_visible = true; bool m_hasUpdate = false; bool m_isNew = false; - const QString m_itemType = "texture"; + const QString m_bundleId = "UserTextures"; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp index 8dcf4575f78..89fb4a0a7d1 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp @@ -2,11 +2,11 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "contentlibraryusermodel.h" +#include "useritemcategory.h" +#include "usertexturecategory.h" #include "contentlibrarybundleimporter.h" #include "contentlibraryitem.h" -#include "contentlibrarymaterial.h" -#include "contentlibrarymaterialscategory.h" #include "contentlibrarytexture.h" #include "contentlibrarywidget.h" @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -30,7 +29,7 @@ ContentLibraryUserModel::ContentLibraryUserModel(ContentLibraryWidget *parent) : QAbstractListModel(parent) , m_widget(parent) { - m_userCategories = {tr("Materials"), tr("Textures"), tr("3D"), /*tr("Effects"), tr("2D components")*/}; // TODO + createCategories(); } int ContentLibraryUserModel::rowCount(const QModelIndex &) const @@ -43,218 +42,147 @@ QVariant ContentLibraryUserModel::data(const QModelIndex &index, int role) const QTC_ASSERT(index.isValid() && index.row() < m_userCategories.size(), return {}); QTC_ASSERT(roleNames().contains(role), return {}); - if (role == NameRole) - return m_userCategories.at(index.row()); + UserCategory *currCat = m_userCategories.at(index.row()); - if (role == ItemsRole) { - if (index.row() == MaterialsSectionIdx) - return QVariant::fromValue(m_userMaterials); - if (index.row() == TexturesSectionIdx) - return QVariant::fromValue(m_userTextures); - if (index.row() == Items3DSectionIdx) - return QVariant::fromValue(m_user3DItems); - if (index.row() == EffectsSectionIdx) - return QVariant::fromValue(m_userEffects); - } + if (role == TitleRole) + return currCat->title(); - if (role == NoMatchRole) { - if (index.row() == MaterialsSectionIdx) - return m_noMatchMaterials; - if (index.row() == TexturesSectionIdx) - return m_noMatchTextures; - if (index.row() == Items3DSectionIdx) - return m_noMatch3D; - if (index.row() == EffectsSectionIdx) - return m_noMatchEffects; - } + if (role == ItemsRole) + return QVariant::fromValue(currCat->items()); - if (role == VisibleRole) { - if (index.row() == MaterialsSectionIdx) - return !m_userMaterials.isEmpty(); - if (index.row() == TexturesSectionIdx) - return !m_userTextures.isEmpty(); - if (index.row() == Items3DSectionIdx) - return !m_user3DItems.isEmpty(); - if (index.row() == EffectsSectionIdx) - return !m_userEffects.isEmpty(); - } + if (role == NoMatchRole) + return currCat->noMatch(); + + if (role == EmptyRole) + return currCat->isEmpty(); return {}; } -bool ContentLibraryUserModel::isValidIndex(int idx) const +void ContentLibraryUserModel::createCategories() { - return idx > -1 && idx < rowCount(); + QTC_ASSERT(m_userCategories.isEmpty(), return); + + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + auto userBundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User"); + + auto catMaterial = new UserItemCategory{tr("Materials"), + userBundlePath.pathAppended("materials"), + compUtils.userMaterialsBundleId()}; + + auto catTexture = new UserTextureCategory{tr("Textures"), userBundlePath.pathAppended("textures")}; + + auto cat3D = new UserItemCategory{tr("3D"), userBundlePath.pathAppended("3d"), + compUtils.user3DBundleId()}; + + m_userCategories << catMaterial << catTexture << cat3D; } -void ContentLibraryUserModel::updateNoMatchMaterials() -{ - m_noMatchMaterials = Utils::allOf(m_userMaterials, [&](ContentLibraryMaterial *item) { - return !item->visible(); - }); -} - -void ContentLibraryUserModel::updateNoMatchTextures() -{ - m_noMatchTextures = Utils::allOf(m_userTextures, [&](ContentLibraryTexture *item) { - return !item->visible(); - }); -} - -void ContentLibraryUserModel::updateNoMatch3D() -{ - m_noMatch3D = Utils::allOf(m_user3DItems, [&](ContentLibraryItem *item) { - return !item->visible(); - }); -} - -void ContentLibraryUserModel::addMaterial(const QString &name, const QString &qml, - const QUrl &icon, const QStringList &files) +void ContentLibraryUserModel::addItem(const QString &bundleId, const QString &name, + const QString &qml, const QUrl &icon, const QStringList &files) { auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); - QString typePrefix = compUtils.userMaterialsBundleType(); + QString typePrefix = compUtils.userBundleType(bundleId); TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.chopped(4)).toLatin1(); - auto libMat = new ContentLibraryMaterial(this, name, qml, type, icon, files, - Paths::bundlesPathSetting().append("/User/materials")); - m_userMaterials.append(libMat); + SectionIndex sectionIndex = bundleIdToSectionIndex(bundleId); - emit dataChanged(index(MaterialsSectionIdx), index(MaterialsSectionIdx)); + UserCategory *cat = m_userCategories[sectionIndex]; + cat->addItem(new ContentLibraryItem(cat, name, qml, type, icon, files, bundleId)); + updateIsEmpty(); } -void ContentLibraryUserModel::add3DItem(const QString &name, const QString &qml, - const QUrl &icon, const QStringList &files) +void ContentLibraryUserModel::refreshSection(const QString &bundleId) { - auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); - - QString typePrefix = compUtils.user3DBundleType(); - TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.chopped(4)).toLatin1(); - - m_user3DItems.append(new ContentLibraryItem(this, name, qml, type, icon, files)); + SectionIndex sectionIdx = bundleIdToSectionIndex(bundleId); + emit dataChanged(index(sectionIdx), index(sectionIdx), {ItemsRole, EmptyRole}); + updateIsEmpty(); } -void ContentLibraryUserModel::refresh3DSection() +void ContentLibraryUserModel::addTextures(const Utils::FilePaths &paths) { - emit dataChanged(index(Items3DSectionIdx), index(Items3DSectionIdx)); + auto texCat = qobject_cast(m_userCategories[TexturesSectionIdx]); + QTC_ASSERT(texCat, return); + + texCat->addItems(paths); + + emit dataChanged(index(TexturesSectionIdx), index(TexturesSectionIdx), {ItemsRole, EmptyRole}); + updateIsEmpty(); } -void ContentLibraryUserModel::addTextures(const QStringList &paths) +void ContentLibraryUserModel::removeTextures(const QStringList &fileNames) { - QDir bundleDir{Paths::bundlesPathSetting() + "/User/textures"}; - bundleDir.mkpath("."); - bundleDir.mkdir("icons"); + // note: this method doesn't refresh the model after textures removal - for (const QString &path : paths) { - QFileInfo fileInfo(path); - QString suffix = '.' + fileInfo.suffix(); - auto iconFileInfo = QFileInfo(fileInfo.path().append("/icons/").append(fileInfo.baseName() + ".png")); - QPair info = ImageUtils::imageInfo(path); - QString dirPath = fileInfo.path(); - QSize imgDims = info.first; - qint64 imgFileSize = info.second; + auto texCat = qobject_cast(m_userCategories[TexturesSectionIdx]); + QTC_ASSERT(texCat, return); - auto tex = new ContentLibraryTexture(this, iconFileInfo, dirPath, suffix, imgDims, imgFileSize); - m_userTextures.append(tex); + const QObjectList items = texCat->items(); + for (QObject *item : items) { + ContentLibraryTexture *castedItem = qobject_cast(item); + QTC_ASSERT(castedItem, continue); + + if (fileNames.contains(castedItem->fileName())) + removeTexture(castedItem, false); } - - emit dataChanged(index(TexturesSectionIdx), index(TexturesSectionIdx)); } -void ContentLibraryUserModel::add3DInstance(ContentLibraryItem *bundleItem) -{ - QString err = m_widget->importer()->importComponent(m_bundlePath3D.path(), bundleItem->type(), - bundleItem->qml(), - bundleItem->files() + m_bundle3DSharedFiles); - - if (err.isEmpty()) - m_widget->setImporterRunning(true); - else - qWarning() << __FUNCTION__ << err; -} - -void ContentLibraryUserModel::removeTexture(ContentLibraryTexture *tex) +void ContentLibraryUserModel::removeTexture(ContentLibraryTexture *tex, bool refresh) { // remove resources Utils::FilePath::fromString(tex->texturePath()).removeFile(); Utils::FilePath::fromString(tex->iconPath()).removeFile(); // remove from model - m_userTextures.removeOne(tex); - tex->deleteLater(); + m_userCategories[TexturesSectionIdx]->removeItem(tex); // update model - emit dataChanged(index(TexturesSectionIdx), index(TexturesSectionIdx)); + if (refresh) { + emit dataChanged(index(TexturesSectionIdx), index(TexturesSectionIdx)); + updateIsEmpty(); + } } void ContentLibraryUserModel::removeFromContentLib(QObject *item) { - if (auto mat = qobject_cast(item)) - removeMaterialFromContentLib(mat); - else if (auto itm = qobject_cast(item)) - remove3DFromContentLib(itm); + auto castedItem = qobject_cast(item); + QTC_ASSERT(castedItem, return); + + removeItem(castedItem); } -void ContentLibraryUserModel::removeMaterialFromContentLib(ContentLibraryMaterial *item) +void ContentLibraryUserModel::removeItemByName(const QString &qmlFileName, const QString &bundleId) { - auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/materials/"); + ContentLibraryItem *itemToRemove = nullptr; + const QObjectList items = m_userCategories[bundleIdToSectionIndex(bundleId)]->items(); - QJsonArray itemsArr = m_bundleObjMaterial.value("items").toArray(); + for (QObject *item : items) { + ContentLibraryItem *castedItem = qobject_cast(item); + QTC_ASSERT(castedItem, return); - // remove qml and icon files - Utils::FilePath::fromString(item->qmlFilePath()).removeFile(); - Utils::FilePath::fromUrl(item->icon()).removeFile(); - - // remove from the bundle json file - for (int i = 0; i < itemsArr.size(); ++i) { - if (itemsArr.at(i).toObject().value("qml") == item->qml()) { - itemsArr.removeAt(i); + if (castedItem->qml() == qmlFileName) { + itemToRemove = castedItem; break; } } - m_bundleObjMaterial.insert("items", itemsArr); - - auto result = bundlePath.pathAppended(Constants::BUNDLE_JSON_FILENAME) - .writeFileContents(QJsonDocument(m_bundleObjMaterial).toJson()); - if (!result) - qWarning() << __FUNCTION__ << result.error(); - - // delete dependency files if they are only used by the deleted material - QStringList allFiles; - for (const QJsonValueConstRef &itemRef : std::as_const(itemsArr)) - allFiles.append(itemRef.toObject().value("files").toVariant().toStringList()); - - const QStringList itemFiles = item->files(); - for (const QString &file : itemFiles) { - if (allFiles.count(file) == 0) // only used by the deleted item - bundlePath.pathAppended(file).removeFile(); - } - - // remove from model - m_userMaterials.removeOne(item); - item->deleteLater(); - - // update model - emit dataChanged(index(MaterialsSectionIdx), index(MaterialsSectionIdx)); -} - -void ContentLibraryUserModel::remove3DFromContentLibByName(const QString &qmlFileName) -{ - ContentLibraryItem *itemToRemove = Utils::findOr(m_user3DItems, nullptr, - [&qmlFileName](ContentLibraryItem *item) { - return item->qml() == qmlFileName; - }); if (itemToRemove) - remove3DFromContentLib(itemToRemove); + removeItem(itemToRemove); } -void ContentLibraryUserModel::remove3DFromContentLib(ContentLibraryItem *item) +void ContentLibraryUserModel::removeItem(ContentLibraryItem *item) { - QJsonArray itemsArr = m_bundleObj3D.value("items").toArray(); + UserItemCategory *itemCat = qobject_cast(item->parent()); + QTC_ASSERT(itemCat, return); + + Utils::FilePath bundlePath = itemCat->bundlePath(); + QJsonObject &bundleObj = itemCat->bundleObjRef(); + + QJsonArray itemsArr = bundleObj.value("items").toArray(); // remove qml and icon files - m_bundlePath3D.pathAppended(item->qml()).removeFile(); + bundlePath.pathAppended(item->qml()).removeFile(); Utils::FilePath::fromUrl(item->icon()).removeFile(); // remove from the bundle json file @@ -264,10 +192,10 @@ void ContentLibraryUserModel::remove3DFromContentLib(ContentLibraryItem *item) break; } } - m_bundleObj3D.insert("items", itemsArr); + bundleObj.insert("items", itemsArr); - auto result = m_bundlePath3D.pathAppended(Constants::BUNDLE_JSON_FILENAME) - .writeFileContents(QJsonDocument(m_bundleObj3D).toJson()); + auto result = bundlePath.pathAppended(Constants::BUNDLE_JSON_FILENAME) + .writeFileContents(QJsonDocument(bundleObj).toJson()); if (!result) qWarning() << __FUNCTION__ << result.error(); @@ -279,276 +207,60 @@ void ContentLibraryUserModel::remove3DFromContentLib(ContentLibraryItem *item) const QStringList itemFiles = item->files(); for (const QString &file : itemFiles) { if (allFiles.count(file) == 0) // only used by the deleted item - m_bundlePath3D.pathAppended(file).removeFile(); + bundlePath.pathAppended(file).removeFile(); } // remove from model - m_user3DItems.removeOne(item); - item->deleteLater(); + itemCat->removeItem(item); // update model - emit dataChanged(index(Items3DSectionIdx), index(Items3DSectionIdx)); + SectionIndex sectionIdx = bundleIdToSectionIndex(item->bundleId()); + emit dataChanged(index(sectionIdx), index(sectionIdx), {ItemsRole, EmptyRole}); + updateIsEmpty(); } -/** - * @brief Gets unique Qml component and icon file material names from a given name - * @param defaultName input name - * @return file names - */ -QPair ContentLibraryUserModel::getUniqueLibMaterialNames(const QString &defaultName) const +ContentLibraryUserModel::SectionIndex ContentLibraryUserModel::bundleIdToSectionIndex( + const QString &bundleId) const { - return getUniqueLibItemNames(defaultName, m_bundleObjMaterial); -} + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); -/** - * @brief Gets unique Qml component and icon file 3d item names from a given name - * @param defaultName input name - * @return file names - */ -QPair ContentLibraryUserModel::getUniqueLib3DNames(const QString &defaultName) const -{ - return getUniqueLibItemNames(defaultName, m_bundleObj3D); -} + if (bundleId == compUtils.userMaterialsBundleId()) + return MaterialsSectionIdx; -QPair ContentLibraryUserModel::getUniqueLibItemNames(const QString &defaultName, - const QJsonObject &bundleObj) const -{ - QTC_ASSERT(!bundleObj.isEmpty(), return {}); + if (bundleId == compUtils.user3DBundleId()) + return Items3DSectionIdx; - const QJsonArray itemsArr = bundleObj.value("items").toArray(); + if (bundleId == compUtils.userEffectsBundleId()) + return EffectsSectionIdx; - QStringList itemQmls, itemIcons; - for (const QJsonValueConstRef &itemRef : itemsArr) { - const QJsonObject &obj = itemRef.toObject(); - itemQmls.append(obj.value("qml").toString().chopped(4)); // remove .qml - itemIcons.append(QFileInfo(obj.value("icon").toString()).baseName()); - } - - QString baseQml = UniqueName::generateId(defaultName); - baseQml[0] = baseQml.at(0).toUpper(); - baseQml.prepend("My"); - - QString uniqueQml = UniqueName::generate(baseQml, [&] (const QString &name) { - return itemQmls.contains(name); - }); - - QString uniqueIcon = UniqueName::generate(defaultName, [&] (const QString &name) { - return itemIcons.contains(name); - }); - - return {uniqueQml + ".qml", uniqueIcon + ".png"}; + qWarning() << __FUNCTION__ << "Invalid section index for bundleId:" << bundleId; + return {}; } QHash ContentLibraryUserModel::roleNames() const { static const QHash roles { - {NameRole, "categoryName"}, - {VisibleRole, "categoryVisible"}, + {TitleRole, "categoryTitle"}, + {EmptyRole, "categoryEmpty"}, {ItemsRole, "categoryItems"}, {NoMatchRole, "categoryNoMatch"} }; return roles; } -QJsonObject &ContentLibraryUserModel::bundleJsonMaterialObjectRef() +QJsonObject &ContentLibraryUserModel::bundleObjectRef(const QString &bundleId) { - return m_bundleObjMaterial; + auto secIdx = bundleIdToSectionIndex(bundleId); + return qobject_cast(m_userCategories[secIdx])->bundleObjRef(); } -QJsonObject &ContentLibraryUserModel::bundleJson3DObjectRef() +void ContentLibraryUserModel::loadBundles(bool force) { - return m_bundleObj3D; -} + for (UserCategory *cat : std::as_const(m_userCategories)) + cat->loadBundle(force); -void ContentLibraryUserModel::loadBundles() -{ - loadMaterialBundle(); - load3DBundle(); - loadTextureBundle(); -} - -void ContentLibraryUserModel::loadMaterialBundle() -{ - auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); - if (m_matBundleExists && m_bundleIdMaterial == compUtils.userMaterialsBundleId()) - return; - - // clean up - qDeleteAll(m_userMaterials); - m_userMaterials.clear(); - m_matBundleExists = false; - m_noMatchMaterials = true; - m_bundleObjMaterial = {}; - m_bundleIdMaterial.clear(); - - m_bundlePathMaterial = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/materials"); - m_bundlePathMaterial.ensureWritableDir(); - m_bundlePathMaterial.pathAppended("icons").ensureWritableDir(); - - auto jsonFilePath = m_bundlePathMaterial.pathAppended(Constants::BUNDLE_JSON_FILENAME); - if (!jsonFilePath.exists()) { - QString jsonContent = "{\n"; - jsonContent += " \"id\": \"UserMaterials\",\n"; - jsonContent += " \"items\": []\n"; - jsonContent += "}"; - Utils::expected_str res = jsonFilePath.writeFileContents(jsonContent.toLatin1()); - if (!res.has_value()) { - qWarning() << __FUNCTION__ << res.error(); - emit dataChanged(index(MaterialsSectionIdx), index(MaterialsSectionIdx)); - return; - } - } - - Utils::expected_str jsonContents = jsonFilePath.fileContents(); - if (!jsonContents.has_value()) { - qWarning() << __FUNCTION__ << jsonContents.error(); - emit dataChanged(index(MaterialsSectionIdx), index(MaterialsSectionIdx)); - return; - } - - QJsonDocument bundleJsonDoc = QJsonDocument::fromJson(jsonContents.value()); - if (bundleJsonDoc.isNull()) { - qWarning() << __FUNCTION__ << "Invalid json file" << jsonFilePath; - emit dataChanged(index(MaterialsSectionIdx), index(MaterialsSectionIdx)); - return; - } - - m_bundleIdMaterial = compUtils.userMaterialsBundleId(); - m_bundleObjMaterial = bundleJsonDoc.object(); - m_bundleObjMaterial["id"] = m_bundleIdMaterial; - - // parse items - QString typePrefix = compUtils.userMaterialsBundleType(); - const QJsonArray itemsArr = m_bundleObjMaterial.value("items").toArray(); - for (const QJsonValueConstRef &itemRef : itemsArr) { - const QJsonObject itemObj = itemRef.toObject(); - - QString name = itemObj.value("name").toString(); - QString qml = itemObj.value("qml").toString(); - TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.chopped(4)).toLatin1(); - QUrl icon = m_bundlePathMaterial.pathAppended(itemObj.value("icon").toString()).toUrl(); - QStringList files; - const QJsonArray assetsArr = itemObj.value("files").toArray(); - for (const QJsonValueConstRef &asset : assetsArr) - files.append(asset.toString()); - - m_userMaterials.append(new ContentLibraryMaterial(this, name, qml, type, icon, files, - m_bundlePathMaterial.path(), "")); - } - - m_bundleMaterialSharedFiles.clear(); - const QJsonArray sharedFilesArr = m_bundleObjMaterial.value("sharedFiles").toArray(); - for (const QJsonValueConstRef &file : sharedFilesArr) - m_bundleMaterialSharedFiles.append(file.toString()); - - m_matBundleExists = true; - updateNoMatchMaterials(); - emit dataChanged(index(MaterialsSectionIdx), index(MaterialsSectionIdx)); -} - -void ContentLibraryUserModel::load3DBundle() -{ - auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); - - if (m_bundle3DExists && m_bundleId3D == compUtils.user3DBundleId()) - return; - - // clean up - qDeleteAll(m_user3DItems); - m_user3DItems.clear(); - m_bundle3DExists = false; - m_noMatch3D = true; - m_bundleObj3D = {}; - m_bundleId3D.clear(); - - m_bundlePath3D = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/3d"); - m_bundlePath3D.ensureWritableDir(); - m_bundlePath3D.pathAppended("icons").ensureWritableDir(); - - auto jsonFilePath = m_bundlePath3D.pathAppended(Constants::BUNDLE_JSON_FILENAME); - if (!jsonFilePath.exists()) { - QByteArray jsonContent = "{\n"; - jsonContent += " \"id\": \"User3D\",\n"; - jsonContent += " \"items\": []\n"; - jsonContent += "}"; - Utils::expected_str res = jsonFilePath.writeFileContents(jsonContent); - if (!res.has_value()) { - qWarning() << __FUNCTION__ << res.error(); - emit dataChanged(index(Items3DSectionIdx), index(Items3DSectionIdx)); - return; - } - } - - Utils::expected_str jsonContents = jsonFilePath.fileContents(); - if (!jsonContents.has_value()) { - qWarning() << __FUNCTION__ << jsonContents.error(); - emit dataChanged(index(Items3DSectionIdx), index(Items3DSectionIdx)); - return; - } - - QJsonDocument bundleJsonDoc = QJsonDocument::fromJson(jsonContents.value()); - if (bundleJsonDoc.isNull()) { - qWarning() << __FUNCTION__ << "Invalid json file" << jsonFilePath; - emit dataChanged(index(Items3DSectionIdx), index(Items3DSectionIdx)); - return; - } - - m_bundleId3D = compUtils.user3DBundleId(); - m_bundleObj3D = bundleJsonDoc.object(); - m_bundleObj3D["id"] = m_bundleId3D; - - // parse items - QString typePrefix = compUtils.user3DBundleType(); - const QJsonArray itemsArr = m_bundleObj3D.value("items").toArray(); - for (const QJsonValueConstRef &itemRef : itemsArr) { - const QJsonObject itemObj = itemRef.toObject(); - - QString name = itemObj.value("name").toString(); - QString qml = itemObj.value("qml").toString(); - TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.chopped(4)).toLatin1(); - QUrl icon = m_bundlePath3D.pathAppended(itemObj.value("icon").toString()).toUrl(); - QStringList files; - const QJsonArray assetsArr = itemObj.value("files").toArray(); - for (const QJsonValueConstRef &asset : assetsArr) - files.append(asset.toString()); - - m_user3DItems.append(new ContentLibraryItem(nullptr, name, qml, type, icon, files)); - } - - m_bundle3DSharedFiles.clear(); - const QJsonArray sharedFilesArr = m_bundleObj3D.value("sharedFiles").toArray(); - for (const QJsonValueConstRef &file : sharedFilesArr) - m_bundle3DSharedFiles.append(file.toString()); - - m_bundle3DExists = true; - updateNoMatch3D(); - emit dataChanged(index(Items3DSectionIdx), index(Items3DSectionIdx)); -} - -void ContentLibraryUserModel::loadTextureBundle() -{ - if (!m_userTextures.isEmpty()) - return; - - QDir bundleDir{Paths::bundlesPathSetting() + "/User/textures"}; - bundleDir.mkpath("."); - bundleDir.mkdir("icons"); - - const QFileInfoList fileInfos = bundleDir.entryInfoList(QDir::Files); - for (const QFileInfo &fileInfo : fileInfos) { - QString suffix = '.' + fileInfo.suffix(); - auto iconFileInfo = QFileInfo(fileInfo.path().append("/icons/").append(fileInfo.baseName() + ".png")); - QPair info = ImageUtils::imageInfo(fileInfo.path()); - QString dirPath = fileInfo.path(); - QSize imgDims = info.first; - qint64 imgFileSize = info.second; - - auto tex = new ContentLibraryTexture(this, iconFileInfo, dirPath, suffix, imgDims, imgFileSize); - m_userTextures.append(tex); - } - - updateNoMatchTextures(); - emit dataChanged(index(TexturesSectionIdx), index(TexturesSectionIdx)); + resetModel(); + updateIsEmpty(); } bool ContentLibraryUserModel::hasRequiredQuick3DImport() const @@ -556,9 +268,17 @@ bool ContentLibraryUserModel::hasRequiredQuick3DImport() const return m_widget->hasQuick3DImport() && m_quick3dMajorVersion == 6 && m_quick3dMinorVersion >= 3; } -bool ContentLibraryUserModel::matBundleExists() const -{ - return m_matBundleExists; +void ContentLibraryUserModel::updateIsEmpty() { + + bool newIsEmpty = Utils::allOf(std::as_const(m_userCategories), [](UserCategory *cat) { + return cat->isEmpty(); + }); + + if (m_isEmpty == newIsEmpty) + return; + + m_isEmpty = newIsEmpty; + emit isEmptyChanged(); } void ContentLibraryUserModel::setSearchText(const QString &searchText) @@ -570,39 +290,46 @@ void ContentLibraryUserModel::setSearchText(const QString &searchText) m_searchText = lowerSearchText; - for (ContentLibraryMaterial *item : std::as_const(m_userMaterials)) - item->filter(m_searchText); + for (UserCategory *cat : std::as_const(m_userCategories)) + cat->filter(m_searchText); - for (ContentLibraryTexture *item : std::as_const(m_userTextures)) - item->filter(m_searchText); - - for (ContentLibraryItem *item : std::as_const(m_user3DItems)) - item->filter(m_searchText); - - updateNoMatchMaterials(); - updateNoMatchTextures(); - updateNoMatch3D(); resetModel(); } -void ContentLibraryUserModel::updateMaterialsImportedState(const QStringList &importedItems) +void ContentLibraryUserModel::updateImportedState(const QStringList &importedItems, + const QString &bundleId) { + SectionIndex secIdx = bundleIdToSectionIndex(bundleId); + UserItemCategory *cat = qobject_cast(m_userCategories.at(secIdx)); + const QObjectList items = cat->items(); + bool changed = false; - for (ContentLibraryMaterial *mat : std::as_const(m_userMaterials)) - changed |= mat->setImported(importedItems.contains(mat->qml().chopped(4))); + for (QObject *item : items) { + ContentLibraryItem *castedItem = qobject_cast(item); + changed |= castedItem->setImported(importedItems.contains(castedItem->qml().chopped(4))); + } if (changed) - emit dataChanged(index(MaterialsSectionIdx), index(MaterialsSectionIdx)); + emit dataChanged(index(secIdx), index(secIdx), {ItemsRole}); } -void ContentLibraryUserModel::update3DImportedState(const QStringList &importedItems) +bool ContentLibraryUserModel::jsonPropertyExists(const QString &propName, const QString &propValue, + const QString &bundleId) const { - bool changed = false; - for (ContentLibraryItem *item : std::as_const(m_user3DItems)) - changed |= item->setImported(importedItems.contains(item->qml().chopped(4))); + SectionIndex secIdx = bundleIdToSectionIndex(bundleId); + UserItemCategory *cat = qobject_cast(m_userCategories.at(secIdx)); + QTC_ASSERT(cat, return false); - if (changed) - emit dataChanged(index(Items3DSectionIdx), index(Items3DSectionIdx)); + QJsonObject &bundleObj = cat->bundleObjRef(); + const QJsonArray itemsArr = bundleObj.value("items").toArray(); + + for (const QJsonValueConstRef &itemRef : itemsArr) { + const QJsonObject &obj = itemRef.toObject(); + if (obj.value(propName).toString() == propValue) + return true; + } + + return false; } void ContentLibraryUserModel::setQuick3DImportVersion(int major, int minor) @@ -626,33 +353,22 @@ void ContentLibraryUserModel::resetModel() endResetModel(); } -void ContentLibraryUserModel::applyToSelected(ContentLibraryMaterial *mat, bool add) +void ContentLibraryUserModel::applyToSelected(ContentLibraryItem *mat, bool add) { emit applyToSelectedTriggered(mat, add); } -void ContentLibraryUserModel::addToProject(QObject *item) +void ContentLibraryUserModel::addToProject(ContentLibraryItem *item) { - QString bundleDir; - TypeName type; - QString qmlFile; - QStringList files; - if (auto mat = qobject_cast(item)) { - bundleDir = mat->dirPath(); - type = mat->type(); - qmlFile = mat->qml(); - files = mat->files() + m_bundleMaterialSharedFiles; - } else if (auto itm = qobject_cast(item)) { - bundleDir = m_bundlePath3D.toString(); - type = itm->type(); - qmlFile = itm->qml(); - files = itm->files() + m_bundle3DSharedFiles; - } else { - qWarning() << __FUNCTION__ << "Unsupported Item"; - return; - } + UserItemCategory *itemCat = qobject_cast(item->parent()); + QTC_ASSERT(itemCat, return); - QString err = m_widget->importer()->importComponent(bundleDir, type, qmlFile, files); + QString bundlePath = itemCat->bundlePath().toFSPathString(); + TypeName type = item->type(); + QString qmlFile = item->qml(); + QStringList files = item->files() + itemCat->sharedFiles(); + + QString err = m_widget->importer()->importComponent(bundlePath, type, qmlFile, files); if (err.isEmpty()) m_widget->setImporterRunning(true); @@ -662,20 +378,8 @@ void ContentLibraryUserModel::addToProject(QObject *item) void ContentLibraryUserModel::removeFromProject(QObject *item) { - TypeName type; - QString qml; - if (auto mat = qobject_cast(item)) { - type = mat->type(); - qml = mat->qml(); - } else if (auto itm = qobject_cast(item)) { - type = itm->type(); - qml = itm->qml(); - } else { - qWarning() << __FUNCTION__ << "Unsupported Item"; - return; - } - - QString err = m_widget->importer()->unimportComponent(type, qml); + auto castedItem = qobject_cast(item); + QString err = m_widget->importer()->unimportComponent(castedItem->type(), castedItem->qml()); if (err.isEmpty()) m_widget->setImporterRunning(true); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.h index 2a7f9a66f30..172bad093a3 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.h @@ -3,6 +3,8 @@ #pragma once +#include "usercategory.h" + #include #include @@ -13,7 +15,6 @@ QT_FORWARD_DECLARE_CLASS(QUrl) namespace QmlDesigner { class ContentLibraryItem; -class ContentLibraryMaterial; class ContentLibraryTexture; class ContentLibraryWidget; class NodeMetaInfo; @@ -22,13 +23,8 @@ class ContentLibraryUserModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(bool matBundleExists READ matBundleExists NOTIFY matBundleExistsChanged) - Q_PROPERTY(bool bundle3DExists MEMBER m_bundle3DExists NOTIFY bundle3DExistsChanged) Q_PROPERTY(bool hasRequiredQuick3DImport READ hasRequiredQuick3DImport NOTIFY hasRequiredQuick3DImportChanged) - Q_PROPERTY(QList userMaterials MEMBER m_userMaterials NOTIFY userMaterialsChanged) - Q_PROPERTY(QList userTextures MEMBER m_userTextures NOTIFY userTexturesChanged) - Q_PROPERTY(QList user3DItems MEMBER m_user3DItems NOTIFY user3DItemsChanged) - Q_PROPERTY(QList userEffects MEMBER m_userEffects NOTIFY userEffectsChanged) + Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged) public: ContentLibraryUserModel(ContentLibraryWidget *parent = nullptr); @@ -38,98 +34,68 @@ public: QHash roleNames() const override; void setSearchText(const QString &searchText); - void updateMaterialsImportedState(const QStringList &importedItems); - void update3DImportedState(const QStringList &importedItems); + void updateImportedState(const QStringList &importedItems, const QString &bundleId); - QPair getUniqueLibMaterialNames(const QString &defaultName = "Material") const; - QPair getUniqueLib3DNames(const QString &defaultName = "Item") const; + bool jsonPropertyExists(const QString &propName, const QString &propValue, + const QString &bundleId) const; void setQuick3DImportVersion(int major, int minor); bool hasRequiredQuick3DImport() const; - bool matBundleExists() const; + void updateIsEmpty(); void resetModel(); - void updateNoMatchMaterials(); - void updateNoMatchTextures(); - void updateNoMatch3D(); - void addMaterial(const QString &name, const QString &qml, const QUrl &icon, const QStringList &files); - void add3DItem(const QString &name, const QString &qml, const QUrl &icon, const QStringList &files); - void refresh3DSection(); - void addTextures(const QStringList &paths); + void addItem(const QString &bundleId, const QString &name, const QString &qml,const QUrl &icon, + const QStringList &files); + void refreshSection(const QString &bundleId); + void addTextures(const Utils::FilePaths &paths); + void removeTextures(const QStringList &fileNames); - void add3DInstance(ContentLibraryItem *bundleItem); - - void remove3DFromContentLibByName(const QString &qmlFileName); + void removeItemByName(const QString &qmlFileName, const QString &bundleId); void setBundleObj(const QJsonObject &newBundleObj); - QJsonObject &bundleJsonMaterialObjectRef(); - QJsonObject &bundleJson3DObjectRef(); + QJsonObject &bundleObjectRef(const QString &bundleId); - void loadBundles(); + void loadBundles(bool force = false); - Q_INVOKABLE void applyToSelected(QmlDesigner::ContentLibraryMaterial *mat, bool add = false); - Q_INVOKABLE void addToProject(QObject *item); + Q_INVOKABLE void applyToSelected(QmlDesigner::ContentLibraryItem *mat, bool add = false); + Q_INVOKABLE void addToProject(ContentLibraryItem *item); Q_INVOKABLE void removeFromProject(QObject *item); - Q_INVOKABLE void removeTexture(QmlDesigner::ContentLibraryTexture *tex); + Q_INVOKABLE void removeTexture(QmlDesigner::ContentLibraryTexture *tex, bool refresh = true); Q_INVOKABLE void removeFromContentLib(QObject *item); signals: void hasRequiredQuick3DImportChanged(); - void userMaterialsChanged(); - void userTexturesChanged(); - void user3DItemsChanged(); - void userEffectsChanged(); - void applyToSelectedTriggered(QmlDesigner::ContentLibraryMaterial *mat, bool add = false); - void matBundleExistsChanged(); - void bundle3DExistsChanged(); + void isEmptyChanged(); + void applyToSelectedTriggered(QmlDesigner::ContentLibraryItem *mat, bool add = false); private: + // section indices must match the order in initModel() enum SectionIndex { MaterialsSectionIdx = 0, TexturesSectionIdx, Items3DSectionIdx, EffectsSectionIdx }; + void createCategories(); void loadMaterialBundle(); void load3DBundle(); void loadTextureBundle(); - bool isValidIndex(int idx) const; - void removeMaterialFromContentLib(ContentLibraryMaterial *mat); - void remove3DFromContentLib(ContentLibraryItem *item); - QPair getUniqueLibItemNames(const QString &defaultName, - const QJsonObject &bundleObj) const; + void removeItem(ContentLibraryItem *item); + SectionIndex bundleIdToSectionIndex(const QString &bundleId) const; ContentLibraryWidget *m_widget = nullptr; QString m_searchText; - QString m_bundleIdMaterial; - QString m_bundleId3D; - QStringList m_bundleMaterialSharedFiles; - QStringList m_bundle3DSharedFiles; - Utils::FilePath m_bundlePathMaterial; - Utils::FilePath m_bundlePath3D; - QList m_userMaterials; - QList m_userTextures; - QList m_userEffects; - QList m_user3DItems; - QStringList m_userCategories; + QList m_userCategories; - QJsonObject m_bundleObjMaterial; - QJsonObject m_bundleObj3D; - - bool m_noMatchMaterials = true; - bool m_noMatchTextures = true; - bool m_noMatch3D = true; - bool m_noMatchEffects = true; - bool m_matBundleExists = false; - bool m_bundle3DExists = false; + bool m_isEmpty = true; int m_quick3dMajorVersion = -1; int m_quick3dMinorVersion = -1; - enum Roles { NameRole = Qt::UserRole + 1, VisibleRole, ItemsRole, NoMatchRole }; + enum Roles { TitleRole = Qt::UserRole + 1, ItemsRole, EmptyRole, NoMatchRole }; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index 04764e7552e..37ac6f07271 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -4,6 +4,7 @@ #include "contentlibraryview.h" #include "contentlibrarybundleimporter.h" +#include "contentlibraryiconprovider.h" #include "contentlibraryitem.h" #include "contentlibraryeffectsmodel.h" #include "contentlibrarymaterial.h" @@ -19,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -27,6 +30,9 @@ #include #include +#include +#include + #include #ifndef QMLDESIGNER_TEST @@ -37,11 +43,14 @@ #include #endif +#include +#include #include #include #include #include #include +#include #include namespace QmlDesigner { @@ -93,6 +102,9 @@ WidgetInfo ContentLibraryView::widgetInfo() m_widget->environmentsModel()->setHasSceneEnv(sceneEnvExists); }); + connect(m_widget, &ContentLibraryWidget::importBundle, this, + &ContentLibraryView::importBundleToContentLib); + connect(m_widget->materialsModel(), &ContentLibraryMaterialsModel::applyToSelectedTriggered, this, @@ -113,7 +125,7 @@ WidgetInfo ContentLibraryView::widgetInfo() connect(m_widget->userModel(), &ContentLibraryUserModel::applyToSelectedTriggered, this, - [&](ContentLibraryMaterial *bundleMat, bool add) { + [&](ContentLibraryItem *bundleMat, bool add) { if (m_selectedModels.isEmpty()) return; @@ -133,7 +145,6 @@ WidgetInfo ContentLibraryView::widgetInfo() return createWidgetInfo(m_widget.data(), "ContentLibrary", WidgetInfo::LeftPane, - 0, tr("Content Library")); } @@ -177,6 +188,8 @@ void ContentLibraryView::connectImporter() } else if (isItemBundle(bundleId)) { if (!m_bundleItemTarget) m_bundleItemTarget = Utils3D::active3DSceneNode(this); + if (!m_bundleItemTarget) + m_bundleItemTarget = rootModelNode(); QTC_ASSERT(m_bundleItemTarget, return); @@ -189,6 +202,8 @@ void ContentLibraryView::connectImporter() {"y", pos.y()}, {"z", pos.z()}}); m_bundleItemTarget.defaultNodeListProperty().reparentHere(newNode); + newNode.setIdWithoutRefactoring(model()->generateNewId( + newNode.simplifiedTypeName(), "node")); clearSelectedModelNodes(); selectModelNode(newNode); }); @@ -259,15 +274,20 @@ void ContentLibraryView::modelAttached(Model *model) // bundles loading has to happen here, otherwise project path is not ready which will // cause bundle items types to resolve incorrectly - m_widget->materialsModel()->loadBundle(); - m_widget->effectsModel()->loadBundle(); - m_widget->userModel()->loadBundles(); - auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + QString genFolderName = compUtils.generatedComponentsPath().fileName(); + bool forceReload = m_generatedFolderName != genFolderName; + + m_widget->materialsModel()->loadBundle(); + m_widget->effectsModel()->loadBundle(forceReload); + m_widget->userModel()->loadBundles(forceReload); + m_widget->updateImportedState(compUtils.materialsBundleId()); m_widget->updateImportedState(compUtils.effectsBundleId()); m_widget->updateImportedState(compUtils.userMaterialsBundleId()); m_widget->updateImportedState(compUtils.user3DBundleId()); + + m_generatedFolderName = genFolderName; } void ContentLibraryView::modelAboutToBeDetached(Model *model) @@ -358,21 +378,31 @@ void ContentLibraryView::customNotification(const AbstractView *view, m_bundleItemPos = data.size() == 1 ? data.first() : QVariant(); if (is3D) - m_widget->userModel()->add3DInstance(m_draggedBundleItem); + m_widget->userModel()->addToProject(m_draggedBundleItem); else m_widget->effectsModel()->addInstance(m_draggedBundleItem); m_bundleItemTarget = nodeList.first() ? nodeList.first() : Utils3D::active3DSceneNode(this); } else if (identifier == "add_material_to_content_lib") { QTC_ASSERT(nodeList.size() == 1 && data.size() == 1, return); - addLibMaterial(nodeList.first(), data.first().value()); + addLibItem(nodeList.first(), data.first().value()); } else if (identifier == "add_assets_to_content_lib") { addLibAssets(data.first().toStringList()); } else if (identifier == "add_3d_to_content_lib") { if (nodeList.first().isComponent()) addLib3DComponent(nodeList.first()); else - addLib3DItem(nodeList.first()); + addLibItem(nodeList.first()); + } else if (identifier == "export_item_as_bundle") { + // TODO: support exporting 2D items + if (nodeList.first().isComponent()) + exportLib3DComponent(nodeList.first()); + else + exportLibItem(nodeList.first()); + } else if (identifier == "export_material_as_bundle") { + exportLibItem(nodeList.first(), data.first().value()); + } else if (identifier == "import_bundle_to_project") { + importBundleToProject(); } } @@ -399,6 +429,16 @@ void ContentLibraryView::auxiliaryDataChanged(const ModelNode &, active3DSceneChanged(data.toInt()); } +void ContentLibraryView::modelNodePreviewPixmapChanged(const ModelNode &, + const QPixmap &pixmap, + const QByteArray &requestId) +{ + if (requestId == ADD_ITEM_REQ_ID) + saveIconToBundle(pixmap); + else if (requestId == EXPORT_ITEM_REQ_ID) + addIconAndCloseZip(pixmap); +} + #ifdef QDS_USE_PROJECTSTORAGE void ContentLibraryView::applyBundleMaterialToDropTarget(const ModelNode &bundleMat, const TypeName &typeName) @@ -408,36 +448,14 @@ void ContentLibraryView::applyBundleMaterialToDropTarget(const ModelNode &bundle executeInTransaction("ContentLibraryView::applyBundleMaterialToDropTarget", [&] { ModelNode newMatNode = typeName.size() ? createMaterial(typeName) : bundleMat; - - // TODO: unify this logic as it exist elsewhere also - auto expToList = [](const QString &exp) { - QString copy = exp; - copy = copy.remove("[").remove("]"); - - QStringList tmp = copy.split(',', Qt::SkipEmptyParts); - for (QString &str : tmp) - str = str.trimmed(); - - return tmp; - }; - - auto listToExp = [](QStringList &stringList) { - if (stringList.size() > 1) - return QString("[" + stringList.join(",") + "]"); - - if (stringList.size() == 1) - return stringList.first(); - - return QString(); - }; - for (const ModelNode &target : std::as_const(m_bundleMaterialTargets)) { if (target.isValid() && target.metaInfo().isQtQuick3DModel()) { QmlObjectNode qmlObjNode(target); if (m_bundleMaterialAddToSelected) { - QStringList matList = expToList(qmlObjNode.expression("materials")); + QStringList matList = ModelUtils::expressionToList( + qmlObjNode.expression("materials")); matList.append(newMatNode.id()); - QString updatedExp = listToExp(matList); + QString updatedExp = ModelUtils::listToExpression(matList); qmlObjNode.setBindingProperty("materials", updatedExp); } else { qmlObjNode.setBindingProperty("materials", newMatNode.id()); @@ -459,35 +477,14 @@ void ContentLibraryView::applyBundleMaterialToDropTarget(const ModelNode &bundle executeInTransaction("ContentLibraryView::applyBundleMaterialToDropTarget", [&] { ModelNode newMatNode = metaInfo.isValid() ? createMaterial(metaInfo) : bundleMat; - // TODO: unify this logic as it exist elsewhere also - auto expToList = [](const QString &exp) { - QString copy = exp; - copy = copy.remove("[").remove("]"); - - QStringList tmp = copy.split(',', Qt::SkipEmptyParts); - for (QString &str : tmp) - str = str.trimmed(); - - return tmp; - }; - - auto listToExp = [](QStringList &stringList) { - if (stringList.size() > 1) - return QString("[" + stringList.join(",") + "]"); - - if (stringList.size() == 1) - return stringList.first(); - - return QString(); - }; - for (const ModelNode &target : std::as_const(m_bundleMaterialTargets)) { if (target.isValid() && target.metaInfo().isQtQuick3DModel()) { QmlObjectNode qmlObjNode(target); if (m_bundleMaterialAddToSelected) { - QStringList matList = expToList(qmlObjNode.expression("materials")); + QStringList matList = ModelUtils::expressionToList( + qmlObjNode.expression("materials")); matList.append(newMatNode.id()); - QString updatedExp = listToExp(matList); + QString updatedExp = ModelUtils::listToExpression(matList); qmlObjNode.setBindingProperty("materials", updatedExp); } else { qmlObjNode.setBindingProperty("materials", newMatNode.id()); @@ -501,82 +498,30 @@ void ContentLibraryView::applyBundleMaterialToDropTarget(const ModelNode &bundle } #endif -// Add a project material to Content Library's user tab -void ContentLibraryView::addLibMaterial(const ModelNode &node, const QPixmap &iconPixmap) +namespace { +Utils::FilePath componentPath([[maybe_unused]] const NodeMetaInfo &metaInfo) { - auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/materials/"); - - QString name = node.variantProperty("objectName").value().toString(); - auto [qml, icon] = m_widget->userModel()->getUniqueLibMaterialNames(node.id()); - - QString iconPath = QLatin1String("icons/%1").arg(icon); - QString fullIconPath = bundlePath.pathAppended(iconPath).toString(); - - // save icon - bool iconSaved = iconPixmap.save(fullIconPath); - if (!iconSaved) - qWarning() << __FUNCTION__ << "icon save failed"; - - // generate and save material Qml file - const QStringList depAssets = writeLibItemQml(node, qml); - - // add the material to the bundle json - QJsonObject &jsonRef = m_widget->userModel()->bundleJsonMaterialObjectRef(); - QJsonArray itemsArr = jsonRef.value("items").toArray(); - QJsonObject itemObj; - itemObj.insert("name", name); - itemObj.insert("qml", qml); - itemObj.insert("icon", iconPath); - QJsonArray filesArr; - for (const QString &assetPath : depAssets) - filesArr.append(assetPath); - itemObj.insert("files", filesArr); - - itemsArr.append(itemObj); - jsonRef["items"] = itemsArr; - - auto result = bundlePath.pathAppended(Constants::BUNDLE_JSON_FILENAME) - .writeFileContents(QJsonDocument(jsonRef).toJson()); - if (!result) - qWarning() << __FUNCTION__ << result.error(); - - // copy material assets to bundle folder - for (const QString &assetPath : depAssets) { - Utils::FilePath assetPathSource = DocumentManager::currentResourcePath().pathAppended(assetPath); - Utils::FilePath assetPathTarget = bundlePath.pathAppended(assetPath); - assetPathTarget.parentDir().ensureWritableDir(); - - auto result = assetPathSource.copyFile(assetPathTarget); - if (!result) - qWarning() << __FUNCTION__ << result.error(); - } - - m_widget->userModel()->addMaterial(name, qml, QUrl::fromLocalFile(fullIconPath), depAssets); +#ifdef QDS_USE_PROJECTSTORAGE + // TODO + return {}; +#else + return Utils::FilePath::fromString(metaInfo.importDirectoryPath()); +#endif } -QStringList ContentLibraryView::writeLibItemQml(const ModelNode &node, const QString &qml) +} // namespace + +QPair> ContentLibraryView::modelNodeToQmlString(const ModelNode &node, int depth) { - QStringList depListIds; - auto [qmlString, assets] = modelNodeToQmlString(node, depListIds); + static QStringList depListIds; - qmlString.prepend("import QtQuick\nimport QtQuick3D\n\n"); - - QString itemType = QLatin1String(node.metaInfo().isQtQuick3DMaterial() ? "materials" : "3d"); - auto qmlPath = Utils::FilePath::fromString(QLatin1String("%1/User/%2/%3") - .arg(Paths::bundlesPathSetting(), itemType, qml)); - auto result = qmlPath.writeFileContents(qmlString.toUtf8()); - if (!result) - qWarning() << __FUNCTION__ << result.error(); - - return assets.values(); -} - -QPair> ContentLibraryView::modelNodeToQmlString(const ModelNode &node, - QStringList &depListIds, - int depth) -{ QString qml; - QSet assets; + QSet assets; + + if (depth == 0) { + qml.append("import QtQuick\nimport QtQuick3D\n\n"); + depListIds.clear(); + } QString indent = QString(" ").repeated(depth * 4); @@ -597,87 +542,145 @@ QPair> ContentLibraryView::modelNodeToQmlString(const Mod if (p.isVariantProperty()) { QVariant pValue = p.toVariantProperty().value(); QString val; - if (strcmp(pValue.typeName(), "QString") == 0 || strcmp(pValue.typeName(), "QColor") == 0) { + + if (!pValue.typeName()) { + // dynamic property with no value assigned + } else if (strcmp(pValue.typeName(), "QString") == 0 || strcmp(pValue.typeName(), "QColor") == 0) { val = QLatin1String("\"%1\"").arg(pValue.toString()); } else if (strcmp(pValue.typeName(), "QUrl") == 0) { QString pValueStr = pValue.toString(); val = QLatin1String("\"%1\"").arg(pValueStr); - if (!pValueStr.startsWith("#")) - assets.insert(pValue.toString()); + if (!pValueStr.startsWith("#")) { + assets.insert({DocumentManager::currentResourcePath().toFSPathString(), + pValue.toString()}); + } } else if (strcmp(pValue.typeName(), "QmlDesigner::Enumeration") == 0) { val = pValue.value().toString(); } else { val = pValue.toString(); } - - qml += indent + p.name() + ": " + val + "\n"; + if (p.isDynamic()) { + QString valWithColon = val.isEmpty() ? QString() : (": " + val); + qml += indent + "property " + p.dynamicTypeName() + " " + p.name() + valWithColon + "\n"; + } else { + qml += indent + p.name() + ": " + val + "\n"; + } } else if (p.isBindingProperty()) { - qml += indent + p.name() + ": " + p.toBindingProperty().expression() + "\n"; - ModelNode depNode = modelNodeForId(p.toBindingProperty().expression()); + QTC_ASSERT(depNode.isValid(), continue); + + if (p.isDynamic()) + qml += indent + "property " + p.dynamicTypeName() + " " + p.name() + ": " + depNode.id() + "\n"; + else + qml += indent + p.name() + ": " + depNode.id() + "\n"; if (depNode && !depListIds.contains(depNode.id())) { depListIds.append(depNode.id()); - auto [depQml, depAssets] = modelNodeToQmlString(depNode, depListIds, depth + 1); + auto [depQml, depAssets] = modelNodeToQmlString(depNode, depth + 1); qml += "\n" + depQml + "\n"; assets.unite(depAssets); } } } + // add child nodes + const ModelNodes nodeChildren = node.directSubModelNodes(); + for (const ModelNode &childNode : nodeChildren) { + if (childNode && !depListIds.contains(childNode.id())) { + depListIds.append(childNode.id()); + auto [depQml, depAssets] = modelNodeToQmlString(childNode, depth + 1); + qml += "\n" + depQml + "\n"; + assets.unite(depAssets); + } + } + indent = QString(" ").repeated(depth * 4); qml += indent + "}\n"; + if (node.isComponent()) { + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + bool isBundle = node.type().startsWith(compUtils.componentBundlesTypePrefix().toLatin1()); + + if (depth > 0) { + // add component file to the dependency assets + Utils::FilePath compFilePath = componentPath(node.metaInfo()); + assets.insert({compFilePath.parentDir().path(), compFilePath.fileName()}); + } + + if (isBundle) + assets.unite(getBundleComponentDependencies(node)); + } + return {qml, assets}; } void ContentLibraryView::addLibAssets(const QStringList &paths) { auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/textures"); - QStringList pathsInBundle; + Utils::FilePaths sourcePathsToAdd; + Utils::FilePaths targetPathsToAdd; + QStringList fileNamesToRemove; - const QStringList existingTextures = Utils::transform(bundlePath.dirEntries(QDir::Files), + const QStringList existingAssetsFileNames = Utils::transform(bundlePath.dirEntries(QDir::Files), [](const Utils::FilePath &path) { return path.fileName(); }); for (const QString &path : paths) { auto assetFilePath = Utils::FilePath::fromString(path); - if (existingTextures.contains(assetFilePath.fileName())) - continue; + QString assetFileName = assetFilePath.fileName(); - Asset asset(path); + // confirm overwrite if an item with same name exists + if (existingAssetsFileNames.contains(assetFileName)) { + QMessageBox::StandardButton reply = QMessageBox::question(m_widget, tr("Texture Exists"), + tr("A texture with the same name '%1' already exists in the Content Library, are you sure you want to overwrite it?") + .arg(assetFileName), QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::No) + continue; + + fileNamesToRemove.append(assetFileName); + } + + sourcePathsToAdd.append(assetFilePath); + } + + // remove the to-be-overwritten resources from target bundle path + m_widget->userModel()->removeTextures(fileNamesToRemove); + + // copy resources to target bundle path + for (const Utils::FilePath &sourcePath : sourcePathsToAdd) { + Utils::FilePath targetPath = bundlePath.pathAppended(sourcePath.fileName()); + Asset asset{sourcePath.toFSPathString()}; // save icon - QString iconSavePath = bundlePath.pathAppended("icons/" + assetFilePath.baseName() + ".png") - .toString(); + QString iconSavePath = bundlePath.pathAppended("icons/" + sourcePath.baseName() + ".png") + .toFSPathString(); QPixmap icon = asset.pixmap({120, 120}); bool iconSaved = icon.save(iconSavePath); if (!iconSaved) qWarning() << __FUNCTION__ << "icon save failed"; // save asset - auto result = assetFilePath.copyFile(bundlePath.pathAppended(asset.fileName())); - if (!result) - qWarning() << __FUNCTION__ << result.error(); + auto result = sourcePath.copyFile(targetPath); + QTC_ASSERT_EXPECTED(result,); - pathsInBundle.append(bundlePath.pathAppended(asset.fileName()).toString()); + targetPathsToAdd.append(targetPath); } - m_widget->userModel()->addTextures(pathsInBundle); + m_widget->userModel()->addTextures(targetPathsToAdd); } void ContentLibraryView::addLib3DComponent(const ModelNode &node) { auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + m_bundleId = compUtils.user3DBundleId(); + QString compBaseName = node.simplifiedTypeName(); QString compFileName = compBaseName + ".qml"; - Utils::FilePath compDir = DocumentManager::currentProjectDirPath() - .pathAppended(compUtils.import3dTypePath() + '/' + compBaseName); - + auto compDir = Utils::FilePath::fromString(ModelUtils::componentFilePath(node)).parentDir(); auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/3d/"); // confirm overwrite if an item with same name exists @@ -690,13 +693,16 @@ void ContentLibraryView::addLib3DComponent(const ModelNode &node) return; // before overwriting remove old item (to avoid partial items and dangling assets) - m_widget->userModel()->remove3DFromContentLibByName(compFileName); + m_widget->userModel()->removeItemByName(compFileName, m_bundleId); } // generate and save icon QString iconPath = QLatin1String("icons/%1").arg(UniqueName::generateId(compBaseName) + ".png"); - QString fullIconPath = bundlePath.pathAppended(iconPath).toString(); - genAndSaveIcon(compDir.pathAppended(compFileName).path(), fullIconPath); + m_iconSavePath = bundlePath.pathAppended(iconPath); + m_iconSavePath.parentDir().ensureWritableDir(); + getImageFromCache(compDir.pathAppended(compFileName).path(), [&](const QImage &image) { + saveIconToBundle(image); + }); const Utils::FilePaths sourceFiles = compDir.dirEntries({{}, QDir::Files, QDirIterator::Subdirectories}); const QStringList ignoreList {"_importdata.json", "qmldir", compBaseName + ".hints"}; @@ -712,15 +718,14 @@ void ContentLibraryView::addLib3DComponent(const ModelNode &node) // copy item from project to user bundle auto result = sourcePath.copyFile(targetPath); - if (!result) - qWarning() << __FUNCTION__ << result.error(); + QTC_ASSERT_EXPECTED(result,); if (sourcePath.fileName() != compFileName) // skip component file (only collect dependencies) filesList.append(relativePath.path()); } // add the item to the bundle json - QJsonObject &jsonRef = m_widget->userModel()->bundleJson3DObjectRef(); + QJsonObject &jsonRef = m_widget->userModel()->bundleObjectRef(m_bundleId); QJsonArray itemsArr = jsonRef.value("items").toArray(); itemsArr.append(QJsonObject { {"name", node.simplifiedTypeName()}, @@ -733,61 +738,482 @@ void ContentLibraryView::addLib3DComponent(const ModelNode &node) auto result = bundlePath.pathAppended(Constants::BUNDLE_JSON_FILENAME) .writeFileContents(QJsonDocument(jsonRef).toJson()); - if (!result) - qWarning() << __FUNCTION__ << result.error(); + QTC_ASSERT_EXPECTED(result,); - m_widget->userModel()->add3DItem(compBaseName, compFileName, QUrl::fromLocalFile(fullIconPath), - filesList); + m_widget->userModel()->addItem(m_bundleId, compBaseName, compFileName, m_iconSavePath.toUrl(), + filesList); } -void ContentLibraryView::addLib3DItem(const ModelNode &node) +void ContentLibraryView::exportLib3DComponent(const ModelNode &node) { - auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/3d/"); + QString exportPath = getExportPath(node); + if (exportPath.isEmpty()) + return; - QString name = node.variantProperty("objectName").value().toString(); - auto [qml, icon] = m_widget->userModel()->getUniqueLib3DNames(node.id()); - QString iconPath = QLatin1String("icons/%1").arg(icon); + // targetPath is a temp path for collecting and zipping assets, actual export target is where + // the user chose to export (i.e. exportPath) + QTemporaryDir tempDir; + QTC_ASSERT(tempDir.isValid(), return); + auto targetPath = Utils::FilePath::fromString(tempDir.path()); - if (name.isEmpty()) - name = node.id(); + m_zipWriter = std::make_unique(exportPath); - // generate and save item Qml file - const QStringList depAssets = writeLibItemQml(node, qml); + QString compBaseName = node.simplifiedTypeName(); + QString compFileName = compBaseName + ".qml"; - // generate and save icon - QString qmlPath = QLatin1String("%1/User/3d/%2").arg(Paths::bundlesPathSetting(), qml); - QString fullIconPath = bundlePath.pathAppended(iconPath).toString(); - genAndSaveIcon(qmlPath, fullIconPath); + auto compDir = Utils::FilePath::fromString(ModelUtils::componentFilePath(node)).parentDir(); + + QString iconPath = QLatin1String("icons/%1").arg(UniqueName::generateId(compBaseName) + ".png"); + + const Utils::FilePaths sourceFiles = compDir.dirEntries({{}, QDir::Files, QDirIterator::Subdirectories}); + const QStringList ignoreList {"_importdata.json", "qmldir", compBaseName + ".hints"}; + QStringList filesList; // 3D component's assets (dependencies) + + for (const Utils::FilePath &sourcePath : sourceFiles) { + Utils::FilePath relativePath = sourcePath.relativePathFrom(compDir); + if (ignoreList.contains(sourcePath.fileName()) || relativePath.startsWith("source scene")) + continue; + + m_zipWriter->addFile(relativePath.toFSPathString(), sourcePath.fileContents().value_or("")); + + if (sourcePath.fileName() != compFileName) // skip component file (only collect dependencies) + filesList.append(relativePath.path()); + } // add the item to the bundle json - QJsonObject &jsonRef = m_widget->userModel()->bundleJson3DObjectRef(); + QJsonObject jsonObj; + QJsonArray itemsArr; + itemsArr.append(QJsonObject { + {"name", node.simplifiedTypeName()}, + {"qml", compFileName}, + {"icon", iconPath}, + {"files", QJsonArray::fromStringList(filesList)} + }); + + jsonObj["items"] = itemsArr; + + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + jsonObj["id"] = compUtils.user3DBundleId(); + jsonObj["version"] = BUNDLE_VERSION; + + Utils::FilePath jsonFilePath = targetPath.pathAppended(Constants::BUNDLE_JSON_FILENAME); + m_zipWriter->addFile(jsonFilePath.fileName(), QJsonDocument(jsonObj).toJson()); + + // add icon + m_iconSavePath = targetPath.pathAppended(iconPath); + m_iconSavePath.parentDir().ensureWritableDir(); + getImageFromCache(compDir.pathAppended(compFileName).path(), [&](const QImage &image) { + addIconAndCloseZip(image); + }); +} + +QString ContentLibraryView::nodeNameToComponentFileName(const QString &name) const +{ + QString fileName = UniqueName::generateId(name, "Component"); + fileName[0] = fileName.at(0).toUpper(); + fileName.prepend("My"); + + return fileName + ".qml"; +} + +void ContentLibraryView::addLibItem(const ModelNode &node, const QPixmap &iconPixmap) +{ + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + + m_bundleId.clear(); + Utils::FilePath bundlePath; + + if (node.metaInfo().isQtQuick3DMaterial()) { + bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/materials/"); + m_bundleId = compUtils.userMaterialsBundleId(); + } else if (node.metaInfo().isQtQuick3DEffect()) { + bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/effects/"); + m_bundleId = compUtils.userEffectsBundleId(); + } else if (node.metaInfo().isQtQuick3DNode()) { + bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/3d/"); + m_bundleId = compUtils.user3DBundleId(); + } else { + qWarning() << __FUNCTION__ << "Unsuppported node type"; + return; + } + + QString name = node.variantProperty("objectName").value().toString(); + if (name.isEmpty()) + name = node.displayName(); + + QJsonObject &jsonRef = m_widget->userModel()->bundleObjectRef(m_bundleId); QJsonArray itemsArr = jsonRef.value("items").toArray(); + + QString qml = nodeNameToComponentFileName(name); + + // confirm overwrite if an item with same name exists + if (m_widget->userModel()->jsonPropertyExists("qml", qml, m_bundleId)) { + QMessageBox::StandardButton reply = QMessageBox::question(m_widget, tr("Component Exists"), + tr("A component with the same name '%1' already " + "exists in the Content Library, are you sure " + "you want to overwrite it?") + .arg(qml), QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::No) + return; + + // before overwriting remove old item (to avoid partial items and dangling assets) + m_widget->userModel()->removeItemByName(qml, m_bundleId); + } + + // generate and save Qml file + auto [qmlString, depAssets] = modelNodeToQmlString(node); + const QList depAssetsList = depAssets.values(); + + QStringList depAssetsRelativePaths; + for (const AssetPath &assetPath : depAssetsList) + depAssetsRelativePaths.append(assetPath.relativePath); + + auto result = bundlePath.pathAppended(qml).writeFileContents(qmlString.toUtf8()); + QTC_ASSERT_EXPECTED(result,); + + // get icon path + QString iconPathTemplate = QLatin1String("icons/%1.png"); + QString iconBaseName = UniqueName::generateId(name, [&] (const QString &currName) { + return m_widget->userModel()->jsonPropertyExists("icon", iconPathTemplate.arg(currName), + m_bundleId); + }); + + QString iconPath = iconPathTemplate.arg(iconBaseName); + + // add the item to the bundle json + itemsArr = jsonRef.value("items").toArray(); itemsArr.append(QJsonObject { {"name", name}, {"qml", qml}, {"icon", iconPath}, - {"files", QJsonArray::fromStringList(depAssets)} + {"files", QJsonArray::fromStringList(depAssetsRelativePaths)} }); jsonRef["items"] = itemsArr; + result = bundlePath.pathAppended(Constants::BUNDLE_JSON_FILENAME) + .writeFileContents(QJsonDocument(jsonRef).toJson()); + QTC_ASSERT_EXPECTED(result,); + + // copy item's assets to target folder + for (const AssetPath &assetPath : depAssetsList) { + Utils::FilePath assetPathSource = assetPath.absFilPath(); + Utils::FilePath assetPathTarget = bundlePath.pathAppended(assetPath.relativePath); + assetPathTarget.parentDir().ensureWritableDir(); + + auto result = assetPathSource.copyFile(assetPathTarget); + QTC_ASSERT_EXPECTED(result,); + } + + m_iconSavePath = bundlePath.pathAppended(iconPath); + m_iconSavePath.parentDir().ensureWritableDir(); + + m_widget->userModel()->addItem(m_bundleId, name, qml, m_iconSavePath.toUrl(), depAssetsRelativePaths); + + // generate and save icon + QPixmap iconPixmapToSave; + if (node.metaInfo().isQtQuick3DCamera()) + iconPixmapToSave = m_widget->iconProvider()->requestPixmap("camera.png", nullptr, {}); + else if (node.metaInfo().isQtQuick3DLight()) + iconPixmapToSave = m_widget->iconProvider()->requestPixmap("light.png", nullptr, {}); + else + iconPixmapToSave = iconPixmap; + + if (iconPixmapToSave.isNull()) + model()->nodeInstanceView()->previewImageDataForGenericNode(node, {}, {}, ADD_ITEM_REQ_ID); + else + saveIconToBundle(iconPixmapToSave); +} + +QString ContentLibraryView::getExportPath(const ModelNode &node) const +{ + QString defaultExportFileName = QLatin1String("%1.%2").arg(node.displayName(), + Constants::BUNDLE_SUFFIX); + Utils::FilePath projectFP = DocumentManager::currentProjectDirPath(); + if (projectFP.isEmpty()) { + projectFP = QmlDesignerPlugin::instance()->documentManager() + .currentDesignDocument()->fileName().parentDir(); + } + + QString dialogTitle = node.metaInfo().isQtQuick3DMaterial() ? tr("Export Material") + : tr("Export Component"); + return QFileDialog::getSaveFileName(m_widget, dialogTitle, + projectFP.pathAppended(defaultExportFileName).toFSPathString(), + tr("Qt Design Studio Bundle Files (*.%1)").arg(Constants::BUNDLE_SUFFIX)); +} + +QString ContentLibraryView::getImportPath() const +{ + Utils::FilePath projectFP = DocumentManager::currentProjectDirPath(); + if (projectFP.isEmpty()) { + projectFP = QmlDesignerPlugin::instance()->documentManager() + .currentDesignDocument()->fileName().parentDir(); + } + + return QFileDialog::getOpenFileName(m_widget, tr("Import Component"), projectFP.toFSPathString(), + tr("Qt Design Studio Bundle Files (*.%1)").arg(Constants::BUNDLE_SUFFIX)); +} + +void ContentLibraryView::exportLibItem(const ModelNode &node, const QPixmap &iconPixmap) +{ + QString exportPath = getExportPath(node); + if (exportPath.isEmpty()) + return; + + // targetPath is a temp path for collecting and zipping assets, actual export target is where + // the user chose to export (i.e. exportPath) + m_tempDir = std::make_unique(); + QTC_ASSERT(m_tempDir->isValid(), return); + auto targetPath = Utils::FilePath::fromString(m_tempDir->path()); + + m_zipWriter = std::make_unique(exportPath); + + QString name = node.variantProperty("objectName").value().toString(); + if (name.isEmpty()) + name = node.displayName(); + + QString qml = nodeNameToComponentFileName(name); + QString iconBaseName = UniqueName::generateId(name); + + // generate and save Qml file + auto [qmlString, depAssets] = modelNodeToQmlString(node); + const QList depAssetsList = depAssets.values(); + + QStringList depAssetsRelativePaths; + for (const AssetPath &assetPath : depAssetsList) + depAssetsRelativePaths.append(assetPath.relativePath); + + auto qmlFilePath = targetPath.pathAppended(qml); + auto result = qmlFilePath.writeFileContents(qmlString.toUtf8()); + QTC_ASSERT_EXPECTED(result, return); + m_zipWriter->addFile(qmlFilePath.fileName(), qmlString.toUtf8()); + + QString iconPath = QLatin1String("icons/%1.png").arg(iconBaseName); + + // add the item to the bundle json + QJsonObject jsonObj; + QJsonArray itemsArr; + itemsArr.append(QJsonObject { + {"name", name}, + {"qml", qml}, + {"icon", iconPath}, + {"files", QJsonArray::fromStringList(depAssetsRelativePaths)} + }); + + jsonObj["items"] = itemsArr; + + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + jsonObj["id"] = node.metaInfo().isQtQuick3DMaterial() ? compUtils.userMaterialsBundleId() + : compUtils.user3DBundleId(); + jsonObj["version"] = BUNDLE_VERSION; + + Utils::FilePath jsonFilePath = targetPath.pathAppended(Constants::BUNDLE_JSON_FILENAME); + m_zipWriter->addFile(jsonFilePath.fileName(), QJsonDocument(jsonObj).toJson()); + + // add item's dependency assets to the bundle zip + for (const AssetPath &assetPath : depAssetsList) + m_zipWriter->addFile(assetPath.relativePath, assetPath.absFilPath().fileContents().value_or("")); + + // add icon + QPixmap iconPixmapToSave; + if (node.metaInfo().isQtQuick3DCamera()) + iconPixmapToSave = m_widget->iconProvider()->requestPixmap("camera.png", nullptr, {}); + else if (node.metaInfo().isQtQuick3DLight()) + iconPixmapToSave = m_widget->iconProvider()->requestPixmap("light.png", nullptr, {}); + else + iconPixmapToSave = iconPixmap; + + m_iconSavePath = targetPath.pathAppended(iconPath); + if (iconPixmapToSave.isNull()) + model()->nodeInstanceView()->previewImageDataForGenericNode(node, {}, {}, EXPORT_ITEM_REQ_ID); + else + addIconAndCloseZip(iconPixmapToSave); +} + +void ContentLibraryView::addIconAndCloseZip(const auto &image) { // auto: QImage or QPixmap + QByteArray iconByteArray; + QBuffer buffer(&iconByteArray); + buffer.open(QIODevice::WriteOnly); + image.save(&buffer, "PNG"); + + m_zipWriter->addFile("icons/" + m_iconSavePath.fileName(), iconByteArray); + m_zipWriter->close(); +}; + +void ContentLibraryView::saveIconToBundle(const auto &image) { // auto: QImage or QPixmap + bool iconSaved = image.save(m_iconSavePath.toFSPathString()); + if (iconSaved) + m_widget->userModel()->refreshSection(m_bundleId); + else + qWarning() << __FUNCTION__ << ": icon save failed"; + + m_iconSavePath.clear(); + m_bundleId.clear(); +}; + +void ContentLibraryView::importBundleToContentLib() +{ + QString importPath = getImportPath(); + if (importPath.isEmpty()) + return; + + ZipReader zipReader(importPath); + + QByteArray bundleJsonContent = zipReader.fileData(Constants::BUNDLE_JSON_FILENAME); + QTC_ASSERT(!bundleJsonContent.isEmpty(), return); + + const QJsonObject importedJsonObj = QJsonDocument::fromJson(bundleJsonContent).object(); + const QJsonArray importedItemsArr = importedJsonObj.value("items").toArray(); + QTC_ASSERT(!importedItemsArr.isEmpty(), return); + + QString bundleVersion = importedJsonObj.value("version").toString(); + bool bundleVersionOk = !bundleVersion.isEmpty() && bundleVersion == BUNDLE_VERSION; + if (!bundleVersionOk) { + QMessageBox::warning(m_widget, tr("Unsupported bundle file"), + tr("The chosen bundle was created with an incompatible version of Qt Design Studio")); + return; + } + QString bundleId = importedJsonObj.value("id").toString(); + bool isMat = isMaterialBundle(bundleId); + + QString bundleFolderName = isMat ? QLatin1String("materials") : QLatin1String("3d"); + + auto bundlePath = Utils::FilePath::fromString(QLatin1String("%1/User/%3/") + .arg(Paths::bundlesPathSetting(), bundleFolderName)); + + QJsonObject &jsonRef = m_widget->userModel()->bundleObjectRef(bundleId); + QJsonArray itemsArr = jsonRef.value("items").toArray(); + + QStringList existingQmls; + for (const QJsonValueConstRef &itemRef : std::as_const(itemsArr)) + existingQmls.append(itemRef.toObject().value("qml").toString()); + + for (const QJsonValueConstRef &itemRef : importedItemsArr) { + QJsonObject itemObj = itemRef.toObject(); + QString qml = itemObj.value("qml").toString(); + + // confirm overwrite if an item with same name exists + if (existingQmls.contains(qml)) { + QMessageBox::StandardButton reply = QMessageBox::question(m_widget, tr("Component Exists"), + tr("A component with the same name '%1' already " + "exists in the Content Library, are you sure " + "you want to overwrite it?") + .arg(qml), QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::No) + continue; + + // before overwriting remove old item (to avoid partial items and dangling assets) + m_widget->userModel()->removeItemByName(qml, bundleId); + } + + // add entry to json + itemsArr.append(itemRef); + + // add entry to model + QString name = itemObj.value("name").toString(); + QStringList files = itemObj.value("files").toVariant().toStringList(); + QString icon = itemObj.value("icon").toString(); + QUrl iconUrl = bundlePath.pathAppended(icon).toUrl(); + + // copy files + files << qml << icon; // all files + for (const QString &file : std::as_const(files)) { + Utils::FilePath filePath = bundlePath.pathAppended(file); + filePath.parentDir().ensureWritableDir(); + QTC_ASSERT_EXPECTED(filePath.writeFileContents(zipReader.fileData(file)),); + } + + m_widget->userModel()->addItem(bundleId, name, qml, iconUrl, files); + } + + m_widget->userModel()->refreshSection(bundleId); + + zipReader.close(); + + jsonRef["items"] = itemsArr; + auto result = bundlePath.pathAppended(Constants::BUNDLE_JSON_FILENAME) .writeFileContents(QJsonDocument(jsonRef).toJson()); - if (!result) - qWarning() << __FUNCTION__ << result.error(); + QTC_ASSERT_EXPECTED(result,); +} - // copy item's assets to bundle folder - for (const QString &assetPath : depAssets) { - Utils::FilePath assetPathSource = DocumentManager::currentResourcePath().pathAppended(assetPath); - Utils::FilePath assetPathTarget = bundlePath.pathAppended(assetPath); - assetPathTarget.parentDir().ensureWritableDir(); +void ContentLibraryView::importBundleToProject() +{ + QString importPath = getImportPath(); + if (importPath.isEmpty()) + return; - auto result = assetPathSource.copyFile(assetPathTarget); - if (!result) - qWarning() << __FUNCTION__ << result.error(); + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + + ZipReader zipReader(importPath); + + QByteArray bundleJsonContent = zipReader.fileData(Constants::BUNDLE_JSON_FILENAME); + QTC_ASSERT(!bundleJsonContent.isEmpty(), return); + + const QJsonObject importedJsonObj = QJsonDocument::fromJson(bundleJsonContent).object(); + const QJsonArray importedItemsArr = importedJsonObj.value("items").toArray(); + QTC_ASSERT(!importedItemsArr.isEmpty(), return); + + QString bundleVersion = importedJsonObj.value("version").toString(); + bool bundleVersionOk = !bundleVersion.isEmpty() && bundleVersion == BUNDLE_VERSION; + if (!bundleVersionOk) { + QMessageBox::warning(m_widget, tr("Unsupported bundle file"), + tr("The chosen bundle was created with an incompatible version of Qt Design Studio")); + return; + } + QString bundleId = importedJsonObj.value("id").toString(); + + QTemporaryDir tempDir; + QTC_ASSERT(tempDir.isValid(), return); + auto bundlePath = Utils::FilePath::fromString(tempDir.path()); + + const QStringList existingQmls = Utils::transform(compUtils.userBundlePath(bundleId) + .dirEntries(QDir::Files), [](const Utils::FilePath &path) { + return path.fileName(); + }); + + for (const QJsonValueConstRef &itemRef : importedItemsArr) { + QJsonObject itemObj = itemRef.toObject(); + QString qml = itemObj.value("qml").toString(); + + // confirm overwrite if an item with same name exists + if (existingQmls.contains(qml)) { + QMessageBox::StandardButton reply = QMessageBox::question(m_widget, tr("Component Exists"), + tr("A component with the same name '%1' already " + "exists in the project, are you sure " + "you want to overwrite it?") + .arg(qml), QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::No) + continue; + + // TODO: before overwriting remove old item's dependencies (not harmful but for cleanup) + } + + // add entry to model + QStringList files = itemObj.value("files").toVariant().toStringList(); + QString icon = itemObj.value("icon").toString(); + + // copy files + QStringList allFiles = files; + allFiles << qml << icon; + for (const QString &file : std::as_const(allFiles)) { + Utils::FilePath filePath = bundlePath.pathAppended(file); + filePath.parentDir().ensureWritableDir(); + QTC_ASSERT_EXPECTED(filePath.writeFileContents(zipReader.fileData(file)),); + } + + QString typePrefix = compUtils.userBundleType(bundleId); + TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.chopped(4)).toLatin1(); + + QString err = m_widget->importer()->importComponent(bundlePath.toFSPathString(), type, qml, files); + + if (err.isEmpty()) + m_widget->setImporterRunning(true); + else + qWarning() << __FUNCTION__ << err; } - m_widget->userModel()->add3DItem(name, qml, QUrl::fromLocalFile(fullIconPath), depAssets); + zipReader.close(); } /** @@ -795,31 +1221,61 @@ void ContentLibraryView::addLib3DItem(const ModelNode &node) * @param qmlPath path to the qml component file to be rendered * @param iconPath output save path of the generated icon */ -void ContentLibraryView::genAndSaveIcon(const QString &qmlPath, const QString &iconPath) +void ContentLibraryView::getImageFromCache(const QString &qmlPath, + std::function successCallback) { m_imageCache.requestSmallImage( Utils::PathString{qmlPath}, - [&, qmlPath, iconPath](const QImage &image) { - bool iconSaved = image.save(iconPath); - if (iconSaved) - m_widget->userModel()->refresh3DSection(); - else - qWarning() << "ContentLibraryView::genAndSaveIcon(): icon save failed"; - }, + successCallback, [&](ImageCache::AbortReason abortReason) { if (abortReason == ImageCache::AbortReason::Abort) { - qWarning() << QLatin1String("ContentLibraryView::genAndSaveIcon(): icon generation " + qWarning() << QLatin1String("ContentLibraryView::getImageFromCache(): icon generation " "failed for path %1, reason: Abort").arg(qmlPath); } else if (abortReason == ImageCache::AbortReason::Failed) { - qWarning() << QLatin1String("ContentLibraryView::genAndSaveIcon(): icon generation " + qWarning() << QLatin1String("ContentLibraryView::getImageFromCache(): icon generation " "failed for path %1, reason: Failed").arg(qmlPath); } else if (abortReason == ImageCache::AbortReason::NoEntry) { - qWarning() << QLatin1String("ContentLibraryView::genAndSaveIcon(): icon generation " + qWarning() << QLatin1String("ContentLibraryView::getImageFromCache(): icon generation " "failed for path %1, reason: NoEntry").arg(qmlPath); } }); } +QSet ContentLibraryView::getBundleComponentDependencies(const ModelNode &node) const +{ + const QString compFileName = node.simplifiedTypeName() + ".qml"; + + Utils::FilePath compPath = componentPath(node.metaInfo()); + + QTC_ASSERT(compPath.exists(), return {}); + + QSet depList; + + Utils::FilePath assetRefPath = compPath.pathAppended(Constants::COMPONENT_BUNDLES_ASSET_REF_FILE); + + Utils::expected_str assetRefContents = assetRefPath.fileContents(); + if (!assetRefContents.has_value()) { + qWarning() << __FUNCTION__ << assetRefContents.error(); + return {}; + } + + QJsonDocument jsonDoc = QJsonDocument::fromJson(assetRefContents.value()); + if (jsonDoc.isNull()) { + qWarning() << __FUNCTION__ << "Invalid json file" << assetRefPath; + return {}; + } + + const QJsonObject rootObj = jsonDoc.object(); + const QStringList bundleAssets = rootObj.keys(); + + for (const QString &asset : bundleAssets) { + if (rootObj.value(asset).toArray().contains(compFileName)) + depList.insert({compPath.toFSPathString(), asset}); + } + + return depList; +} + ModelNode ContentLibraryView::getBundleMaterialDefaultInstance(const TypeName &type) { ModelNode matLib = Utils3D::materialLibraryNode(this); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h index 914a8b8ea00..5a2878eca31 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h @@ -8,10 +8,16 @@ #include #include +#include + #include #include +class ZipWriter; + +QT_FORWARD_DECLARE_CLASS(QImage) QT_FORWARD_DECLARE_CLASS(QPixmap) +QT_FORWARD_DECLARE_CLASS(QTemporaryDir) namespace QmlDesigner { @@ -21,6 +27,27 @@ class ContentLibraryTexture; class ContentLibraryWidget; class Model; +struct AssetPath +{ + QString basePath; + QString relativePath; + + Utils::FilePath absFilPath() const + { + return Utils::FilePath::fromString(basePath).pathAppended(relativePath); + } + + bool operator==(const AssetPath &other) const + { + return basePath == other.basePath && relativePath == other.relativePath; + } + + friend size_t qHash(const AssetPath &asset) + { + return ::qHash(asset.relativePath); + } +}; + class ContentLibraryView : public AbstractView { Q_OBJECT @@ -48,6 +75,9 @@ public: void auxiliaryDataChanged(const ModelNode &node, AuxiliaryDataKeyView type, const QVariant &data) override; + void modelNodePreviewPixmapChanged(const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId) override; private: void connectImporter(); @@ -55,14 +85,22 @@ private: bool isItemBundle(const QString &bundleId) const; void active3DSceneChanged(qint32 sceneId); void updateBundlesQuick3DVersion(); - void addLibMaterial(const ModelNode &node, const QPixmap &iconPixmap); void addLibAssets(const QStringList &paths); void addLib3DComponent(const ModelNode &node); - void addLib3DItem(const ModelNode &node); - void genAndSaveIcon(const QString &qmlPath, const QString &iconPath); - QStringList writeLibItemQml(const ModelNode &node, const QString &qml); - QPair> modelNodeToQmlString(const ModelNode &node, QStringList &depListIds, - int depth = 0); + void exportLib3DComponent(const ModelNode &node); + void addLibItem(const ModelNode &node, const QPixmap &iconPixmap = {}); + void exportLibItem(const ModelNode &node, const QPixmap &iconPixmap = {}); + void importBundleToContentLib(); + void importBundleToProject(); + void getImageFromCache(const QString &qmlPath, + std::function successCallback); + QSet getBundleComponentDependencies(const ModelNode &node) const; + QString getExportPath(const ModelNode &node) const; + QString getImportPath() const; + QString nodeNameToComponentFileName(const QString &name) const; + QPair> modelNodeToQmlString(const ModelNode &node, int depth = 0); + void addIconAndCloseZip(const auto &image); + void saveIconToBundle(const auto &image); #ifdef QDS_USE_PROJECTSTORAGE void applyBundleMaterialToDropTarget(const ModelNode &bundleMat, const TypeName &typeName = {}); @@ -89,6 +127,15 @@ private: bool m_hasQuick3DImport = false; qint32 m_sceneId = -1; CreateTexture m_createTexture; + Utils::FilePath m_iconSavePath; + QString m_generatedFolderName; + QString m_bundleId; + std::unique_ptr m_zipWriter; + std::unique_ptr m_tempDir; + + static constexpr char BUNDLE_VERSION[] = "1.0"; + static constexpr char ADD_ITEM_REQ_ID[] = "AddItemReqId"; + static constexpr char EXPORT_ITEM_REQ_ID[] = "ExportItemReqId"; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp index b61439a80e8..5097d8f2005 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp @@ -5,12 +5,12 @@ #include "contentlibrarybundleimporter.h" #include "contentlibraryeffectsmodel.h" +#include "contentlibraryiconprovider.h" #include "contentlibraryitem.h" #include "contentlibrarymaterial.h" #include "contentlibrarymaterialsmodel.h" #include "contentlibrarytexture.h" #include "contentlibrarytexturesmodel.h" -#include "contentlibraryiconprovider.h" #include "contentlibraryusermodel.h" #include @@ -84,7 +84,7 @@ bool ContentLibraryWidget::eventFilter(QObject *obj, QEvent *event) } else if (m_materialToDrag) { QMouseEvent *me = static_cast(event); if ((me->globalPosition().toPoint() - m_dragStartPoint).manhattanLength() > 20 - && m_materialToDrag->isDownloaded()) { + && m_materialsModel->isMaterialDownloaded(m_materialToDrag)) { QByteArray data; QMimeData *mimeData = new QMimeData; QDataStream stream(&data, QIODevice::WriteOnly); @@ -123,7 +123,8 @@ bool ContentLibraryWidget::eventFilter(QObject *obj, QEvent *event) } ContentLibraryWidget::ContentLibraryWidget() - : m_quickWidget(Utils::makeUniqueObjectPtr(this)) + : m_iconProvider(Utils::makeUniqueObjectPtr()) + , m_quickWidget(Utils::makeUniqueObjectPtr(this)) , m_materialsModel(new ContentLibraryMaterialsModel(this)) , m_texturesModel(new ContentLibraryTexturesModel("Textures", this)) , m_environmentsModel(new ContentLibraryTexturesModel("Environments", this)) @@ -138,8 +139,7 @@ ContentLibraryWidget::ContentLibraryWidget() m_quickWidget->quickWidget()->setObjectName(Constants::OBJECT_NAME_CONTENT_LIBRARY); m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); - m_quickWidget->engine()->addImageProvider(QStringLiteral("contentlibrary"), - new Internal::ContentLibraryIconProvider); + m_quickWidget->engine()->addImageProvider("contentlibrary", m_iconProvider.get()); m_quickWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports"); m_quickWidget->setClearColor(Theme::getColor(Theme::Color::DSpanelBackground)); @@ -181,6 +181,10 @@ ContentLibraryWidget::ContentLibraryWidget() createImporter(); } +ContentLibraryWidget::~ContentLibraryWidget() +{ +} + void ContentLibraryWidget::createImporter() { m_importer = new ContentLibraryBundleImporter(); @@ -212,6 +216,11 @@ void ContentLibraryWidget::createImporter() }); } +ContentLibraryIconProvider *ContentLibraryWidget::iconProvider() const +{ + return m_iconProvider.get(); +} + void ContentLibraryWidget::updateImportedState(const QString &bundleId) { if (!m_importer) @@ -230,10 +239,8 @@ void ContentLibraryWidget::updateImportedState(const QString &bundleId) m_materialsModel->updateImportedState(importedItems); else if (bundleId == compUtils.effectsBundleId()) m_effectsModel->updateImportedState(importedItems); - else if (bundleId == compUtils.userMaterialsBundleId()) - m_userModel->updateMaterialsImportedState(importedItems); - else if (bundleId == compUtils.user3DBundleId()) - m_userModel->update3DImportedState(importedItems); + else + m_userModel->updateImportedState(importedItems, bundleId); } ContentLibraryBundleImporter *ContentLibraryWidget::importer() const diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h index 8e96d9d2f3b..cec47c8917f 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h @@ -24,13 +24,13 @@ namespace QmlDesigner { class ContentLibraryBundleImporter; class ContentLibraryEffectsModel; +class ContentLibraryIconProvider; class ContentLibraryItem; class ContentLibraryMaterial; class ContentLibraryMaterialsModel; class ContentLibraryTexture; class ContentLibraryTexturesModel; class ContentLibraryUserModel; -class NodeMetaInfo; class ContentLibraryWidget : public QFrame { @@ -48,6 +48,7 @@ class ContentLibraryWidget : public QFrame public: ContentLibraryWidget(); + ~ContentLibraryWidget(); QList createToolBarWidgets(); @@ -94,6 +95,7 @@ public: QSize sizeHint() const override; ContentLibraryBundleImporter *importer() const; + ContentLibraryIconProvider *iconProvider() const; signals: void bundleItemDragStarted(QmlDesigner::ContentLibraryItem *item); @@ -108,6 +110,7 @@ signals: void isQt6ProjectChanged(); void importerRunningChanged(); void hasModelSelectionChanged(); + void importBundle(); protected: bool eventFilter(QObject *obj, QEvent *event) override; @@ -128,6 +131,7 @@ private: void populateTextureBundleModels(); void createImporter(); + Utils::UniqueObjectPtr m_iconProvider; Utils::UniqueObjectPtr m_quickWidget; QPointer m_materialsModel; QPointer m_texturesModel; diff --git a/src/plugins/qmldesigner/components/contentlibrary/usercategory.cpp b/src/plugins/qmldesigner/components/contentlibrary/usercategory.cpp new file mode 100644 index 00000000000..0d413752995 --- /dev/null +++ b/src/plugins/qmldesigner/components/contentlibrary/usercategory.cpp @@ -0,0 +1,74 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "usercategory.h" + +namespace QmlDesigner { + +UserCategory::UserCategory(const QString &title, const Utils::FilePath &bundlePath) + : m_title(title) + , m_bundlePath(bundlePath) +{ +} + +QString UserCategory::title() const +{ + return m_title; +} + +bool UserCategory::isEmpty() const +{ + return m_isEmpty; +} + +void UserCategory::setIsEmpty(bool val) +{ + if (m_isEmpty == val) + return; + + m_isEmpty = val; + emit isEmptyChanged(); +} + +bool UserCategory::noMatch() const +{ + return m_noMatch; +} + +void UserCategory::setNoMatch(bool val) +{ + if (m_noMatch == val) + return; + + m_noMatch = val; + emit noMatchChanged(); +} + +void UserCategory::addItem(QObject *item) +{ + m_items.append(item); + emit itemsChanged(); + + setIsEmpty(false); +} + +void UserCategory::removeItem(QObject *item) +{ + m_items.removeOne(item); + item->deleteLater(); + emit itemsChanged(); + + setIsEmpty(m_items.isEmpty()); +} + +Utils::FilePath UserCategory::bundlePath() const +{ + return m_bundlePath; +} + +QObjectList UserCategory::items() const +{ + return m_items; +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/usercategory.h b/src/plugins/qmldesigner/components/contentlibrary/usercategory.h new file mode 100644 index 00000000000..40b5c6d76ea --- /dev/null +++ b/src/plugins/qmldesigner/components/contentlibrary/usercategory.h @@ -0,0 +1,50 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +#include + +namespace QmlDesigner { + +class UserCategory : public QObject +{ + Q_OBJECT + +public: + UserCategory(const QString &title, const Utils::FilePath &bundlePath); + + QString title() const; + QObjectList items() const; + + bool isEmpty() const; + void setIsEmpty(bool val); + + bool noMatch() const; + void setNoMatch(bool val); + + virtual void loadBundle(bool force = false) = 0; + virtual void filter(const QString &searchText) = 0; + + void addItem(QObject *item); + void removeItem(QObject *item); + + Utils::FilePath bundlePath() const; + +signals: + void itemsChanged(); + void isEmptyChanged(); + void noMatchChanged(); + +protected: + QString m_title; + Utils::FilePath m_bundlePath; + QObjectList m_items; + bool m_isEmpty = true; + bool m_noMatch = true; + bool m_bundleLoaded = false; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/useritemcategory.cpp b/src/plugins/qmldesigner/components/contentlibrary/useritemcategory.cpp new file mode 100644 index 00000000000..c6983a92525 --- /dev/null +++ b/src/plugins/qmldesigner/components/contentlibrary/useritemcategory.cpp @@ -0,0 +1,120 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "useritemcategory.h" + +#include "contentlibraryitem.h" + +#include +#include + +#include +#include + +namespace QmlDesigner { + +UserItemCategory::UserItemCategory(const QString &title, const Utils::FilePath &bundlePath, + const QString &bundleId) + : UserCategory(title, bundlePath) + , m_bundleId(bundleId) +{ +} + +void UserItemCategory::loadBundle(bool force) +{ + if (m_bundleLoaded && !force) + return; + + // clean up + qDeleteAll(m_items); + m_items.clear(); + m_bundleLoaded = false; + m_noMatch = false; + m_bundleObj = {}; + + m_bundlePath.ensureWritableDir(); + m_bundlePath.pathAppended("icons").ensureWritableDir(); + + auto jsonFilePath = m_bundlePath.pathAppended(Constants::BUNDLE_JSON_FILENAME); + if (!jsonFilePath.exists()) { + QString jsonContent = "{\n"; + jsonContent += " \"id\": \"" + m_bundleId + "\",\n"; + jsonContent += " \"items\": []\n"; + jsonContent += "}"; + Utils::expected_str res = jsonFilePath.writeFileContents(jsonContent.toLatin1()); + if (!res.has_value()) { + qWarning() << __FUNCTION__ << res.error(); + setIsEmpty(true); + emit itemsChanged(); + return; + } + } + + Utils::expected_str jsonContents = jsonFilePath.fileContents(); + if (!jsonContents.has_value()) { + qWarning() << __FUNCTION__ << jsonContents.error(); + setIsEmpty(true); + emit itemsChanged(); + return; + } + + QJsonDocument bundleJsonDoc = QJsonDocument::fromJson(jsonContents.value()); + if (bundleJsonDoc.isNull()) { + qWarning() << __FUNCTION__ << "Invalid json file" << jsonFilePath; + setIsEmpty(true); + emit itemsChanged(); + return; + } + + m_bundleObj = bundleJsonDoc.object(); + m_bundleObj["id"] = m_bundleId; + + // parse items + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + QString typePrefix = compUtils.userBundleType(m_bundleId); + const QJsonArray itemsArr = m_bundleObj.value("items").toArray(); + for (const QJsonValueConstRef &itemRef : itemsArr) { + const QJsonObject itemObj = itemRef.toObject(); + + QString name = itemObj.value("name").toString(); + QString qml = itemObj.value("qml").toString(); + TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.chopped(4)).toLatin1(); + QUrl icon = m_bundlePath.pathAppended(itemObj.value("icon").toString()).toUrl(); + QStringList files = itemObj.value("files").toVariant().toStringList(); + + m_items.append(new ContentLibraryItem(this, name, qml, type, icon, files, m_bundleId)); + } + + m_sharedFiles.clear(); + const QJsonArray sharedFilesArr = m_bundleObj.value("sharedFiles").toArray(); + for (const QJsonValueConstRef &file : sharedFilesArr) + m_sharedFiles.append(file.toString()); + + m_bundleLoaded = true; + setIsEmpty(m_items.isEmpty()); + emit itemsChanged(); +} + +void UserItemCategory::filter(const QString &searchText) +{ + bool noMatch = true; + for (QObject *item : std::as_const(m_items)) { + ContentLibraryItem *castedItem = qobject_cast(item); + bool itemVisible = castedItem->filter(searchText); + if (itemVisible) + noMatch = false; + } + setNoMatch(noMatch); +} + +QStringList UserItemCategory::sharedFiles() const +{ + return m_sharedFiles; +} + +QJsonObject &UserItemCategory::bundleObjRef() +{ + return m_bundleObj; +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/useritemcategory.h b/src/plugins/qmldesigner/components/contentlibrary/useritemcategory.h new file mode 100644 index 00000000000..dceaee50810 --- /dev/null +++ b/src/plugins/qmldesigner/components/contentlibrary/useritemcategory.h @@ -0,0 +1,35 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "usercategory.h" + +#include + +namespace QmlDesigner { + +class ContentLibraryItem; + +class UserItemCategory : public UserCategory +{ + Q_OBJECT + +public: + UserItemCategory(const QString &title, const Utils::FilePath &bundlePath, const QString &bundleId); + + void loadBundle(bool force) override; + void filter(const QString &searchText) override; + + QStringList sharedFiles() const; + + QJsonObject &bundleObjRef(); + +private: + QString m_bundleId; + QJsonObject m_bundleObj; + QStringList m_sharedFiles; + +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.cpp b/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.cpp new file mode 100644 index 00000000000..22b9cf20aa3 --- /dev/null +++ b/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.cpp @@ -0,0 +1,66 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "usertexturecategory.h" + +#include "contentlibrarytexture.h" + +#include +#include + +namespace QmlDesigner { + +UserTextureCategory::UserTextureCategory(const QString &title, const Utils::FilePath &bundlePath) + : UserCategory(title, bundlePath) +{ +} + +void UserTextureCategory::loadBundle(bool force) +{ + if (m_bundleLoaded && !force) + return; + + // clean up + qDeleteAll(m_items); + m_items.clear(); + + m_bundlePath.ensureWritableDir(); + m_bundlePath.pathAppended("icons").ensureWritableDir(); + + addItems(m_bundlePath.dirEntries(QDir::Files)); + + m_bundleLoaded = true; +} + +void UserTextureCategory::filter(const QString &searchText) +{ + bool noMatch = true; + for (QObject *item : std::as_const(m_items)) { + ContentLibraryTexture *castedItem = qobject_cast(item); + bool itemVisible = castedItem->filter(searchText); + if (itemVisible) + noMatch = false; + } + setNoMatch(noMatch); +} + +void UserTextureCategory::addItems(const Utils::FilePaths &paths) +{ + for (const Utils::FilePath &filePath : paths) { + QString suffix = '.' + filePath.suffix(); + auto iconFileInfo = filePath.parentDir().pathAppended("icons/" + filePath.baseName() + ".png") + .toFileInfo(); + QPair info = ImageUtils::imageInfo(filePath.path()); + QString dirPath = filePath.parentDir().toFSPathString(); + QSize imgDims = info.first; + qint64 imgFileSize = info.second; + + auto tex = new ContentLibraryTexture(this, iconFileInfo, dirPath, suffix, imgDims, imgFileSize); + m_items.append(tex); + } + + setIsEmpty(m_items.isEmpty()); + emit itemsChanged(); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.h b/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.h new file mode 100644 index 00000000000..511e2ea3f83 --- /dev/null +++ b/src/plugins/qmldesigner/components/contentlibrary/usertexturecategory.h @@ -0,0 +1,25 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "usercategory.h" + +namespace QmlDesigner { + +class ContentLibraryTexture; + +class UserTextureCategory : public UserCategory +{ + Q_OBJECT + +public: + UserTextureCategory(const QString &title, const Utils::FilePath &bundlePath); + + void loadBundle(bool force) override; + void filter(const QString &searchText) override; + + void addItems(const Utils::FilePaths &paths); +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/createtexture.cpp b/src/plugins/qmldesigner/components/createtexture.cpp index 56056e3fd2f..c6cbe64e5df 100644 --- a/src/plugins/qmldesigner/components/createtexture.cpp +++ b/src/plugins/qmldesigner/components/createtexture.cpp @@ -16,15 +16,75 @@ #include +#include +#include #include #include namespace QmlDesigner { +using namespace Qt::StringLiterals; + +static QString nameFromId(const QString &id, const QString &defaultName) +{ + if (id.isEmpty()) + return defaultName; + + QString newName = id; + static const QRegularExpression sideUnderscores{R"((?:^_+)|(?:_+$))"}; + static const QRegularExpression underscores{R"((?:_+))"}; + static const QRegularExpression camelCases{R"((?:[A-Z](?=[a-z]))|(?:(?<=[a-z])[A-Z]))"}; + + newName.remove(sideUnderscores); + + // Insert underscore to camel case edges + QRegularExpressionMatchIterator caseMatch = camelCases.globalMatch(newName); + QStack camelCaseIndexes; + while (caseMatch.hasNext()) + camelCaseIndexes.push(caseMatch.next().capturedStart()); + while (!camelCaseIndexes.isEmpty()) + newName.insert(camelCaseIndexes.pop(), '_'); + + // Replace underscored joints with space + newName.replace(underscores, " "); + newName = newName.trimmed(); + + if (newName.isEmpty()) + return defaultName; + + newName[0] = newName[0].toUpper(); + return newName; +} + CreateTexture::CreateTexture(AbstractView *view) : m_view{view} {} +ModelNode CreateTexture::execute() +{ + ModelNode matLib = Utils3D::materialLibraryNode(m_view); + if (!matLib.isValid()) + return {}; + + ModelNode newTextureNode; + m_view->executeInTransaction(__FUNCTION__, [&]() { +#ifdef QDS_USE_PROJECTSTORAGE + newTextureNode = m_view->createModelNode("Texture"); +#else + NodeMetaInfo metaInfo = m_view->model()->qtQuick3DTextureMetaInfo(); + newTextureNode = m_view->createModelNode("QtQuick3D.Texture", + metaInfo.majorVersion(), + metaInfo.minorVersion()); +#endif + newTextureNode.ensureIdExists(); + VariantProperty textureName = newTextureNode.variantProperty("objectName"); + textureName.setValue(nameFromId(newTextureNode.id(), "Texture"_L1)); + matLib.defaultNodeListProperty().reparentHere(newTextureNode); + }); + + return newTextureNode; +} + ModelNode CreateTexture::execute(const QString &filePath, AddTextureMode mode, int sceneId) { Asset asset(filePath); @@ -94,8 +154,12 @@ ModelNode CreateTexture::createTextureFromImage(const Utils::FilePath &assetPat #endif newTexNode.setIdWithoutRefactoring(m_view->model()->generateNewId(assetPath.baseName())); + VariantProperty textureName = newTexNode.variantProperty("objectName"); + textureName.setValue(nameFromId(newTexNode.id(), "Texture"_L1)); + VariantProperty sourceProp = newTexNode.variantProperty("source"); sourceProp.setValue(QUrl(textureSource)); + matLib.defaultNodeListProperty().reparentHere(newTexNode); } diff --git a/src/plugins/qmldesigner/components/createtexture.h b/src/plugins/qmldesigner/components/createtexture.h index 326696c67de..0f276cdbcd2 100644 --- a/src/plugins/qmldesigner/components/createtexture.h +++ b/src/plugins/qmldesigner/components/createtexture.h @@ -23,7 +23,10 @@ class CreateTexture : public QObject public: CreateTexture(AbstractView *view); - ModelNode execute(const QString &filePath, AddTextureMode mode = AddTextureMode::Texture, int sceneId = -1); + ModelNode execute(); + ModelNode execute(const QString &filePath, + AddTextureMode mode = AddTextureMode::Texture, + int sceneId = -1); ModelNode resolveSceneEnv(int sceneId); void assignTextureAsLightProbe(const ModelNode &texture, int sceneId); diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp index 8b7f3062eb5..48f8780b456 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp @@ -49,7 +49,7 @@ bool CurveEditorView::hasWidget() const WidgetInfo CurveEditorView::widgetInfo() { - return createWidgetInfo(m_editor, "CurveEditorId", WidgetInfo::BottomPane, 0, tr("Curves")); + return createWidgetInfo(m_editor, "CurveEditorId", WidgetInfo::BottomPane, tr("Curves")); } void CurveEditorView::modelAttached(Model *model) diff --git a/src/plugins/qmldesigner/components/debugview/debugview.cpp b/src/plugins/qmldesigner/components/debugview/debugview.cpp index b466a3bb658..6635f06f376 100644 --- a/src/plugins/qmldesigner/components/debugview/debugview.cpp +++ b/src/plugins/qmldesigner/components/debugview/debugview.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include @@ -244,6 +244,9 @@ QTextStream &operator<<(QTextStream &stream, AuxiliaryDataType type) case AuxiliaryDataType::Temporary: stream << "Temporary"; break; + case AuxiliaryDataType::Persistent: + stream << "Persistent"; + break; } return stream; @@ -436,7 +439,6 @@ WidgetInfo DebugView::widgetInfo() return createWidgetInfo(m_debugViewWidget.data(), QStringLiteral("DebugView"), WidgetInfo::LeftPane, - 0, tr("Debug View")); } diff --git a/src/plugins/qmldesigner/components/designsystem/dsconstants.h b/src/plugins/qmldesigner/components/designsystem/dsconstants.h new file mode 100644 index 00000000000..ef2dd6a36a1 --- /dev/null +++ b/src/plugins/qmldesigner/components/designsystem/dsconstants.h @@ -0,0 +1,36 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "nodeinstanceglobal.h" + +#include + +namespace QmlDesigner +{ + +using ThemeId = ushort; + +enum class GroupType { Colors, Flags, Numbers, Strings }; + +class ThemeProperty +{ +public: + bool isValid() const { return !name.trimmed().isEmpty() && value.isValid(); } + + PropertyName name; + QVariant value; + bool isBinding = false; +}; + +constexpr const char *GroupId(const GroupType type) { + if (type == GroupType::Colors) return "colors"; + if (type == GroupType::Flags) return "flags"; + if (type == GroupType::Numbers) return "numbers"; + if (type == GroupType::Strings) return "strings"; + + return "unknown"; +} + +} diff --git a/src/plugins/qmldesigner/components/designsystem/dsthemegroup.cpp b/src/plugins/qmldesigner/components/designsystem/dsthemegroup.cpp new file mode 100644 index 00000000000..aa2b5c78a23 --- /dev/null +++ b/src/plugins/qmldesigner/components/designsystem/dsthemegroup.cpp @@ -0,0 +1,187 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "dsthemegroup.h" + +#include +#include +#include +#include + +#include +#include + +namespace QmlDesigner { +using namespace std; + +namespace { +Q_LOGGING_CATEGORY(dsLog, "qtc.designer.designSystem", QtInfoMsg) + +std::optional groupTypeName(GroupType type) +{ + switch (type) { + case QmlDesigner::GroupType::Colors: return "color"; break; + case QmlDesigner::GroupType::Flags: return "bool"; break; + case QmlDesigner::GroupType::Numbers: return "real"; break; + case QmlDesigner::GroupType::Strings: return "string"; break; + } + return {}; +} + +QDebug &operator<<(QDebug &s, const ThemeProperty &p) +{ + s << "{Name:" << p.name << ", Value:" << p.value << ", isBinding:" << p.isBinding << "}"; + return s; +} +} + +DSThemeGroup::DSThemeGroup(GroupType type): + m_type(type) +{} + +DSThemeGroup::~DSThemeGroup() {} + +bool DSThemeGroup::addProperty(ThemeId theme, const ThemeProperty &prop) +{ + if (!prop.isValid()) { + qCDebug(dsLog) << "Add property failed. Invalid property." << prop; + return false; + } + + if (!m_values.contains(prop.name)) + m_values[prop.name] = {}; + + auto &tValues = m_values.at(prop.name); + if (tValues.contains(theme)) { + qCDebug(dsLog) << "Add property failed. Duplicate property name." << prop; + return false; + } + + tValues.emplace(std::piecewise_construct, + std::forward_as_tuple(theme), + std::forward_as_tuple(prop.value, prop.isBinding)); + + return true; +} + +std::optional DSThemeGroup::propertyValue(ThemeId theme, const PropertyName &name) const +{ + if (!m_values.contains(name)) + return {}; + + const auto &tValues = m_values.at(name); + const auto itr = tValues.find(theme); + if (itr != tValues.end()) { + auto &[value, isBindind] = itr->second; + return ThemeProperty{name, value, isBindind}; + } + return {}; +} + +void DSThemeGroup::updateProperty(ThemeId theme, PropertyName newName, const ThemeProperty &prop) +{ + if (!m_values.contains(prop.name)) { + qCDebug(dsLog) << "Property update failure. Can't find property" << prop; + return; + } + + if (!ThemeProperty{newName, prop.value, prop.isBinding}.isValid()) { + qCDebug(dsLog) << "Property update failure. Invalid property" << prop << newName; + return; + } + + if (newName != prop.name && m_values.contains(newName)) { + qCDebug(dsLog) << "Property update failure. Property name update already exists" << newName + << prop; + return; + } + + auto &tValues = m_values.at(prop.name); + const auto itr = tValues.find(theme); + if (itr == tValues.end()) { + qCDebug(dsLog) << "Property update failure. No property for the theme" << theme << prop; + return; + } + + auto &entry = tValues.at(theme); + entry.value = prop.value; + entry.isBinding = prop.isBinding; + if (newName != prop.name) { + m_values[newName] = std::move(tValues); + m_values.erase(prop.name); + } +} + +void DSThemeGroup::removeProperty(const PropertyName &name) +{ + m_values.erase(name); +} + +size_t DSThemeGroup::count(ThemeId theme) const +{ + return std::accumulate(m_values.cbegin(), + m_values.cend(), + 0ull, + [theme](size_t c, const GroupProperties::value_type &p) { + return c + (p.second.contains(theme) ? 1 : 0); + }); +} + +size_t DSThemeGroup::count() const +{ + return m_values.size(); +} + +void DSThemeGroup::removeTheme(ThemeId theme) +{ + for (auto itr = m_values.begin(); itr != m_values.end();) { + itr->second.erase(theme); + itr = itr->second.size() == 0 ? m_values.erase(itr) : std::next(itr); + } +} + +void DSThemeGroup::duplicateValues(ThemeId from, ThemeId to) +{ + for (auto itr = m_values.begin(); itr != m_values.end(); ++itr) { + auto &[propName, values] = *itr; + auto fromValueItr = values.find(from); + if (fromValueItr != values.end()) + values[to] = fromValueItr->second; + } +} + +void DSThemeGroup::decorate(ThemeId theme, ModelNode themeNode) +{ + if (!count(theme)) + return; // No props for this theme in this group. + + const auto groupName = GroupId(m_type); + const auto typeName = groupTypeName(m_type); + auto groupNode = themeNode.model()->createModelNode("QtObject"); + auto groupProperty = themeNode.nodeProperty(groupName); + + if (!groupProperty || !typeName || !groupNode) { + qCDebug(dsLog) << "Adding group node failed." << groupName << theme; + return; + } + + for (auto itr = m_values.begin(); itr != m_values.end(); ++itr) { + auto &[propName, values] = *itr; + auto themeValue = values.find(theme); + if (themeValue != values.end()) { + auto &propData = themeValue->second; + if (propData.isBinding) { + auto bindingProp = groupNode.bindingProperty(propName); + if (bindingProp) + bindingProp.setDynamicTypeNameAndExpression(*typeName, propData.value.toString()); + } else { + auto nodeProp = groupNode.variantProperty(propName); + if (nodeProp) + nodeProp.setDynamicTypeNameAndValue(*typeName, propData.value); + } + } + } + + groupProperty.setDynamicTypeNameAndsetModelNode("QtObject", groupNode); +} +} diff --git a/src/plugins/qmldesigner/components/designsystem/dsthemegroup.h b/src/plugins/qmldesigner/components/designsystem/dsthemegroup.h new file mode 100644 index 00000000000..9b795115ab1 --- /dev/null +++ b/src/plugins/qmldesigner/components/designsystem/dsthemegroup.h @@ -0,0 +1,59 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once +#include "qmldesignercomponents_global.h" +#include "dsconstants.h" +#include "nodeinstanceglobal.h" + +#include + +#include +#include + +namespace QmlDesigner { + +class QMLDESIGNERCOMPONENTS_EXPORT DSThemeGroup +{ + struct PropertyData + { + PropertyData() = default; + template + PropertyData(Variant &&value, bool isBinding) + : value{std::forward(value)} + , isBinding{isBinding} + {} + + QVariant value; + bool isBinding = false; + }; + + using ThemeValues = std::map; + using GroupProperties = std::map; + +public: + DSThemeGroup(GroupType type); + ~DSThemeGroup(); + + bool addProperty(ThemeId, const ThemeProperty &prop); + std::optional propertyValue(ThemeId theme, const PropertyName &name) const; + + void updateProperty(ThemeId theme, PropertyName newName, const ThemeProperty &prop); + void removeProperty(const PropertyName &name); + + GroupType type() const { return m_type; } + + size_t count(ThemeId theme) const; + size_t count() const; + bool isEmpty() const; + + void removeTheme(ThemeId theme); + + void duplicateValues(ThemeId from, ThemeId to); + void decorate(ThemeId theme, ModelNode themeNode); + +private: + const GroupType m_type; + GroupProperties m_values; +}; +} diff --git a/src/plugins/qmldesigner/components/designsystem/dsthememanager.cpp b/src/plugins/qmldesigner/components/designsystem/dsthememanager.cpp new file mode 100644 index 00000000000..652c0080cd3 --- /dev/null +++ b/src/plugins/qmldesigner/components/designsystem/dsthememanager.cpp @@ -0,0 +1,179 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "dsthememanager.h" + +#include "dsconstants.h" +#include "dsthemegroup.h" + +#include +#include +#include + +#include +#include + +namespace { +Q_LOGGING_CATEGORY(dsLog, "qtc.designer.designSystem", QtInfoMsg) +} + +namespace QmlDesigner { + +DSThemeManager::DSThemeManager() {} + +DSThemeManager::~DSThemeManager() {} + +std::optional DSThemeManager::addTheme(const ThemeName &themeName) +{ + if (themeName.trimmed().isEmpty() || themeId(themeName)) { + qCDebug(dsLog) << "Can not add new Theme. Duplicate theme name"; + return {}; + } + + const ThemeId newThemeId = m_themes.empty() ? 1 : m_themes.rbegin()->first + 1; + m_themes.insert({newThemeId, themeName}); + + // Copy the new theme properties from an old theme(first one). + if (m_themes.size() > 1) + duplicateTheme(m_themes.begin()->first, newThemeId); + + return newThemeId; +} + +std::optional DSThemeManager::themeId(const ThemeName &themeName) const +{ + for (auto &[id, name] : m_themes) { + if (themeName == name) + return id; + } + return {}; +} + +size_t DSThemeManager::themeCount() const +{ + return m_themes.size(); +} + +void DSThemeManager::removeTheme(ThemeId id) +{ + if (!m_themes.contains(id)) + return; + + for (auto groupItr = m_groups.begin(); groupItr != m_groups.end(); ++groupItr) + groupItr->second->removeTheme(id); + + m_themes.erase(id); +} + +void DSThemeManager::duplicateTheme(ThemeId from, ThemeId to) +{ + for (auto groupItr = m_groups.begin(); groupItr != m_groups.end(); ++groupItr) + groupItr->second->duplicateValues(from, to); +} + +std::optional DSThemeManager::property(ThemeId themeId, + GroupType gType, + const PropertyName &name) const +{ + if (m_themes.contains(themeId)) { + auto groupItr = m_groups.find(gType); + if (groupItr != m_groups.end()) + return groupItr->second->propertyValue(themeId, name); + } + + qCDebug(dsLog) << "Error fetching property: {" << themeId << GroupId(gType) << name << "}"; + return {}; +} + +bool DSThemeManager::addProperty(GroupType gType, const ThemeProperty &p) +{ + if (!m_themes.size()) { + qCDebug(dsLog) << "Can not add proprty. Themes empty"; + return false; + } + + // A property is added to all themes. + DSThemeGroup *dsGroup = propertyGroup(gType); + QTC_ASSERT(dsGroup, return false); + + bool success = true; + for (auto itr = m_themes.begin(); itr != m_themes.end(); ++itr) + success &= dsGroup->addProperty(itr->first, p); + + return success; +} + +void DSThemeManager::removeProperty(GroupType gType, const PropertyName &name) +{ + // A property is removed from all themes. + DSThemeGroup *dsGroup = propertyGroup(gType); + QTC_ASSERT(dsGroup, return); + dsGroup->removeProperty(name); +} + +void DSThemeManager::updateProperty(ThemeId id, GroupType gType, const ThemeProperty &p) +{ + updateProperty(id, gType, p, p.name); +} + +void DSThemeManager::updateProperty(ThemeId id, + GroupType gType, + const ThemeProperty &p, + const PropertyName &newName) +{ + if (!m_themes.contains(id)) + return; + + DSThemeGroup *dsGroup = propertyGroup(gType); + QTC_ASSERT(dsGroup, return); + + dsGroup->updateProperty(id, newName, p); +} + +void DSThemeManager::decorate(ModelNode rootNode) const +{ + if (!m_themes.size()) + return; + + auto p = rootNode.bindingProperty("currentTheme"); + p.setDynamicTypeNameAndExpression("QtObject", QString::fromLatin1(m_themes.begin()->second)); + addGroupAliases(rootNode); + + auto model = rootNode.model(); + for (auto itr = m_themes.begin(); itr != m_themes.end(); ++itr) { + auto themeNode = model->createModelNode("QtObject"); + auto themeProperty = model->rootModelNode().nodeProperty(itr->second); + themeProperty.setDynamicTypeNameAndsetModelNode("QtObject", themeNode); + + // Add property groups + for (auto groupItr = m_groups.begin(); groupItr != m_groups.end(); ++groupItr) + groupItr->second->decorate(itr->first, themeNode); + } +} + +DSThemeGroup *DSThemeManager::propertyGroup(GroupType type) +{ + auto itr = m_groups.find(type); + if (itr == m_groups.end()) + itr = m_groups.insert({type, std::make_unique(type)}).first; + + return itr->second.get(); +} + +void DSThemeManager::addGroupAliases(ModelNode rootNode) const +{ + QSet groupNames; + for (auto groupItr = m_groups.begin(); groupItr != m_groups.end(); ++groupItr) { + DSThemeGroup *group = groupItr->second.get(); + const PropertyName groupName = GroupId(group->type()); + if (group->count()) + groupNames.insert(groupName); + } + + for (const auto &name : groupNames) { + auto p = rootNode.bindingProperty(name); + auto binding = QString("currentTheme.%1").arg(QString::fromLatin1(name)); + p.setDynamicTypeNameAndExpression("QtObject", binding); + } +} +} diff --git a/src/plugins/qmldesigner/components/designsystem/dsthememanager.h b/src/plugins/qmldesigner/components/designsystem/dsthememanager.h new file mode 100644 index 00000000000..a28bf232c1c --- /dev/null +++ b/src/plugins/qmldesigner/components/designsystem/dsthememanager.h @@ -0,0 +1,56 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "qmldesignercomponents_global.h" + +#include "dsconstants.h" +#include "dsthemegroup.h" + +#include + +namespace QmlDesigner { + +using ThemeName = PropertyName; + +class DSTheme; +class QMLDESIGNERCOMPONENTS_EXPORT DSThemeManager +{ + +public: + DSThemeManager(); + ~DSThemeManager(); + + DSThemeManager(const DSThemeManager&) = delete; + DSThemeManager& operator=(const DSThemeManager&) = delete; + + DSThemeManager(DSThemeManager&&) = default; + DSThemeManager& operator=(DSThemeManager&&) = default; + + std::optional addTheme(const ThemeName &themeName); + std::optional themeId(const ThemeName &themeName) const; + void removeTheme(ThemeId id); + size_t themeCount() const; + + void duplicateTheme(ThemeId from, ThemeId to); + + bool addProperty(GroupType gType, const ThemeProperty &p); + std::optional property(ThemeId themeId, + GroupType gType, + const PropertyName &name) const; + void removeProperty(GroupType gType, const PropertyName &p); + void updateProperty(ThemeId id, GroupType gType, const ThemeProperty &p); + void updateProperty(ThemeId id, GroupType gType, const ThemeProperty &p, const PropertyName &newName); + + void decorate(ModelNode rootNode) const; + +private: + DSThemeGroup *propertyGroup(GroupType type); + void addGroupAliases(ModelNode rootNode) const; + +private: + std::map m_themes; + std::map> m_groups; +}; +} diff --git a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp index ab1eb9b07b1..606f4f4255c 100644 --- a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp +++ b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.cpp b/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.cpp index a1dfcc8f981..bce2777f0d9 100644 --- a/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.cpp +++ b/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.cpp @@ -15,7 +15,7 @@ #include "qmlobjectnode.h" #include "variantproperty.h" -#include +#include #include @@ -234,7 +234,7 @@ bool BakeLightsDataModel::reset() PropertyName dotName = mi.name() + '.'; for (const AbstractProperty &prop : props) { if (prop.name().startsWith(dotName)) { - PropertyName subName = prop.name().mid(dotName.size()); + PropertyNameView subName = prop.name().mid(dotName.size()); if (subName == "bakedLightmap") { ModelNode blm = prop.toBindingProperty().resolveToModelNode(); if (blm.isValid()) { @@ -269,7 +269,7 @@ bool BakeLightsDataModel::reset() PropertyName dotName = mi.name() + '.'; for (const AbstractProperty &prop : props) { if (prop.name().startsWith(dotName)) { - PropertyName subName = prop.name().mid(dotName.size()); + PropertyNameView subName = prop.name().mid(dotName.size()); if (subName == "bakeMode") { if (prop.isVariantProperty()) { QString bakeModeStr = prop.toVariantProperty().value() diff --git a/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.cpp b/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.cpp index f5a74ee8645..fd6feaecadd 100644 --- a/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.cpp +++ b/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.cpp @@ -2,13 +2,9 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "cameraspeedconfiguration.h" - -#include "designersettings.h" #include "edit3dview.h" -#include "edit3dviewconfig.h" #include - #include #include @@ -193,4 +189,9 @@ bool CameraSpeedConfiguration::eventFilter(QObject *obj, QEvent *event) return QObject::eventFilter(obj, event); } +bool CameraSpeedConfiguration::isQDSTrusted() const +{ + return Edit3DView::isQDSTrusted(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.h b/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.h index fef06efc499..34f391c78b5 100644 --- a/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.h +++ b/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.h @@ -39,6 +39,7 @@ public: Q_INVOKABLE void restoreCursor(); Q_INVOKABLE void holdCursorInPlace(); Q_INVOKABLE int devicePixelRatio(); + Q_INVOKABLE bool isQDSTrusted() const; void cancel(); void apply(); @@ -58,6 +59,7 @@ signals: void speedChanged(); void multiplierChanged(); void totalSpeedChanged(); + void accessibilityOpened(); protected: bool eventFilter(QObject *obj, QEvent *event) override; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp index b3d140bc887..83299a485d5 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp @@ -3,9 +3,8 @@ #include "edit3dactions.h" -#include "bakelights.h" #include "edit3dview.h" -#include "nodemetainfo.h" +#include "indicatoractionwidget.h" #include "qmldesignerconstants.h" #include "seekerslider.h" @@ -34,10 +33,25 @@ void Edit3DActionTemplate::actionTriggered(bool b) m_action(m_selectionContext); } -Edit3DWidgetActionTemplate::Edit3DWidgetActionTemplate(QWidgetAction *widget) +Edit3DWidgetActionTemplate::Edit3DWidgetActionTemplate(QWidgetAction *widget, + SelectionContextOperation action) : PureActionInterface(widget) + , m_action(action) { + QObject::connect(widget, &QAction::triggered, widget, [this](bool value) { + actionTriggered(value); + }); +} +void Edit3DWidgetActionTemplate::setSelectionContext(const SelectionContext &selectionContext) +{ + m_selectionContext = selectionContext; +} + +void Edit3DWidgetActionTemplate::actionTriggered([[maybe_unused]] bool b) +{ + if (m_action) + m_action(m_selectionContext); } Edit3DAction::Edit3DAction(const QByteArray &menuId, @@ -154,4 +168,34 @@ bool Edit3DBakeLightsAction::isEnabled(const SelectionContext &) const && !Utils3D::activeView3dId(m_view).isEmpty(); } +Edit3DIndicatorButtonAction::Edit3DIndicatorButtonAction(const QByteArray &menuId, + View3DActionType type, + const QString &description, + const QIcon &icon, + SelectionContextOperation customAction, + Edit3DView *view) + : Edit3DAction(menuId, + type, + view, + new Edit3DWidgetActionTemplate(new IndicatorButtonAction(description, icon), + customAction)) +{ + m_buttonAction = qobject_cast(action()); } + +void Edit3DIndicatorButtonAction::setIndicator(bool indicator) +{ + m_buttonAction->setIndicator(indicator); +} + +bool Edit3DIndicatorButtonAction::isVisible(const SelectionContext &) const +{ + return m_buttonAction->isVisible(); +} + +bool Edit3DIndicatorButtonAction::isEnabled(const SelectionContext &) const +{ + return m_buttonAction->isEnabled(); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dactions.h b/src/plugins/qmldesigner/components/edit3d/edit3dactions.h index 3a451ea40d5..03aeb22902a 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dactions.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dactions.h @@ -17,6 +17,7 @@ namespace QmlDesigner { using SelectionContextOperation = std::function; class Edit3DView; class SeekerSliderAction; +class IndicatorButtonAction; class Edit3DActionTemplate : public DefaultAction { @@ -40,8 +41,13 @@ class Edit3DWidgetActionTemplate : public PureActionInterface Q_DISABLE_COPY(Edit3DWidgetActionTemplate) public: - explicit Edit3DWidgetActionTemplate(QWidgetAction *widget); - virtual void setSelectionContext(const SelectionContext &) {} + explicit Edit3DWidgetActionTemplate(QWidgetAction *widget, SelectionContextOperation action = {}); + + void setSelectionContext(const SelectionContext &selectionContext) override; + virtual void actionTriggered(bool b); + + SelectionContextOperation m_action; + SelectionContext m_selectionContext; }; class Edit3DAction : public AbstractAction @@ -108,6 +114,27 @@ private: SeekerSliderAction *m_seeker = nullptr; }; +class Edit3DIndicatorButtonAction : public Edit3DAction +{ +public: + Edit3DIndicatorButtonAction(const QByteArray &menuId, + View3DActionType type, + const QString &description, + const QIcon &icon, + SelectionContextOperation customAction, + Edit3DView *view); + + IndicatorButtonAction *buttonAction(); + void setIndicator(bool indicator); + +protected: + bool isVisible(const SelectionContext &) const override; + bool isEnabled(const SelectionContext &) const override; + +private: + IndicatorButtonAction *m_buttonAction = nullptr; +}; + class Edit3DBakeLightsAction : public Edit3DAction { public: diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp index 63d5e958b19..553d8cb7b3d 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp @@ -81,21 +81,13 @@ QWidget *Edit3DCanvas::busyIndicator() const return m_busyIndicator; } -#ifdef Q_OS_MACOS -extern "C" bool AXIsProcessTrusted(); -#endif - void Edit3DCanvas::setFlyMode(bool enabled, const QPoint &pos) { if (m_flyMode == enabled) return; -#ifdef Q_OS_MACOS - if (!AXIsProcessTrusted()) - m_isTrusted = false; -#endif - m_flyMode = enabled; + m_isQDSTrusted = Edit3DView::isQDSTrusted(); if (enabled) { m_flyModeStartTime = QDateTime::currentMSecsSinceEpoch(); @@ -199,7 +191,7 @@ void Edit3DCanvas::mouseMoveEvent(QMouseEvent *e) // We notify explicit camera rotation need for puppet rather than rely in mouse events, // as mouse isn't grabbed on puppet side and can't handle fast movements that go out of // edit camera mouse area. This also simplifies split view handling. - QPointF diff = m_isTrusted ? (m_hiddenCursorPos - e->globalPos()) : (m_lastCursorPos - e->globalPos()); + QPointF diff = m_isQDSTrusted ? (m_hiddenCursorPos - e->globalPos()) : (m_lastCursorPos - e->globalPos()); if (e->buttons() == (Qt::LeftButton | Qt::RightButton)) { m_parent->view()->emitView3DAction(View3DActionType::EditCameraMove, @@ -212,7 +204,7 @@ void Edit3DCanvas::mouseMoveEvent(QMouseEvent *e) m_flyModeFirstUpdate = false; } - if (m_isTrusted) + if (m_isQDSTrusted) QCursor::setPos(m_hiddenCursorPos); else m_lastCursorPos = e->globalPos(); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h index 16c1063dd61..66846061ac6 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h @@ -53,7 +53,7 @@ private: qint32 m_activeScene = -1; QElapsedTimer m_usageTimer; qreal m_opacity = 1.0; - bool m_isTrusted = true; + bool m_isQDSTrusted = true; QWidget *m_busyIndicator = nullptr; bool m_flyMode = false; QPoint m_flyModeStartCursorPos; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.cpp new file mode 100644 index 00000000000..970791b2db6 --- /dev/null +++ b/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.cpp @@ -0,0 +1,195 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "edit3dmaterialsaction.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace Qt::StringLiterals; + +namespace QmlDesigner { + +static QString getMaterialName(const ModelNode &material, bool forceIncludeId = false) +{ + QString materialName = material.variantProperty("objectName").value().toString(); + if (materialName.isEmpty() || forceIncludeId) + materialName.append(QString("[%1]").arg(material.id())); + return materialName; +} + +struct MaterialNameLessThan +{ + bool operator()(const ModelNode &a, const ModelNode &b) + { + const QString aName = getMaterialName(a, true); + const QString bName = getMaterialName(b, true); + return aName.compare(bName, Qt::CaseSensitive) < 0; + }; +}; + +static QList getMaterials(const ModelNode &node) +{ + BindingProperty matsProp = node.bindingProperty("materials"); + if (!matsProp.exists()) + return {}; + + Model *model = node.model(); + QList materials; + if (model->hasId(matsProp.expression())) + materials.append(model->modelNodeForId(matsProp.expression())); + else + materials = matsProp.resolveToModelNodeList(); + + return materials; +} + +static QList getSortedMaterials(const ModelNode &node) +{ + QList materials = getMaterials(node); + std::sort(materials.begin(), materials.end(), MaterialNameLessThan{}); + return materials; +} + +static void removeMaterialFromNode(const ModelNode &node, const QString &materialId, int nthMaterial) +{ + BindingProperty matsProp = node.bindingProperty("materials"); + if (!matsProp.exists()) + return; + + const QString materialsExpression = matsProp.expression(); + Model *model = node.model(); + + if (matsProp.isList()) { + matsProp.removeModelNodeFromArray(model->modelNodeForId(materialId)); + QStringList nodeMaterials = ModelUtils::expressionToList(materialsExpression); + + int indexToBeRemoved = -1; + do + indexToBeRemoved = nodeMaterials.indexOf(materialId, indexToBeRemoved + 1); + while (nthMaterial-- && indexToBeRemoved != -1); + + if (indexToBeRemoved != -1) + nodeMaterials.removeAt(indexToBeRemoved); + + if (nodeMaterials.isEmpty()) + matsProp.parentModelNode().removeProperty(matsProp.name()); + else if (nodeMaterials.size() == 1) + matsProp.setExpression(nodeMaterials.first()); + else + matsProp.setExpression('[' + nodeMaterials.join(',') + ']'); + } else if (materialsExpression == materialId) { + matsProp.parentModelNode().removeProperty(matsProp.name()); + } +} + +static QList commonMaterialsOfNodes(const QList &selectedNodes) +{ + if (selectedNodes.isEmpty()) + return {}; + + if (selectedNodes.size() == 1) + return getMaterials(selectedNodes.first()); + + QList commonMaterials = getSortedMaterials(selectedNodes.first()); + for (const ModelNode &node : Utils::span(selectedNodes).subspan(1)) { + const QList materials = getSortedMaterials(node); + QList materialIntersection; + std::set_intersection(commonMaterials.begin(), + commonMaterials.end(), + materials.begin(), + materials.end(), + std::back_inserter(materialIntersection), + MaterialNameLessThan{}); + std::swap(commonMaterials, materialIntersection); + if (commonMaterials.isEmpty()) + return {}; + } + return commonMaterials; +} + +Edit3DMaterialsAction::Edit3DMaterialsAction(const QIcon &icon, QObject *parent) + : QAction(icon, tr("Materials"), parent) +{ + this->setMenu(new QmlEditorMenu("Materials")); + connect(this, &QObject::destroyed, this->menu(), &QObject::deleteLater); +} + +void Edit3DMaterialsAction::updateMenu(const QList &selecedNodes) +{ + QMenu *menu = this->menu(); + QTC_ASSERT(menu, return); + + m_selectedNodes = selecedNodes; + + menu->clear(); + const QList materials = commonMaterialsOfNodes(m_selectedNodes); + QHash nthMaterialMap; // + + for (const ModelNode &material : materials) { + int nthMaterialWithTheSameId = nthMaterialMap.value(material, -1) + 1; + nthMaterialMap.insert(material, nthMaterialWithTheSameId); + QAction *materialAction = createMaterialAction(material, menu, nthMaterialWithTheSameId); + if (materialAction) + menu->addAction(materialAction); + } + + setVisible(!menu->actions().isEmpty()); + setEnabled(isVisible()); +} + +void Edit3DMaterialsAction::removeMaterial(const QString &materialId, int nthMaterial) +{ + if (m_selectedNodes.isEmpty()) + return; + + AbstractView *nodesView = m_selectedNodes.first().view(); + nodesView->executeInTransaction(__FUNCTION__, [&] { + for (ModelNode &node : m_selectedNodes) + removeMaterialFromNode(node, materialId, nthMaterial); + }); +} + +QAction *Edit3DMaterialsAction::createMaterialAction(const ModelNode &material, + QMenu *parentMenu, + int nthMaterial) +{ + const QString materialId = material.id(); + if (materialId.isEmpty()) + return nullptr; + + QString materialName = getMaterialName(material); + + QAction *action = new QAction(materialName, parentMenu); + QMenu *menu = new QmlEditorMenu(materialName, parentMenu); + connect(action, &QObject::destroyed, menu, &QObject::deleteLater); + + QAction *removeMaterialAction = new QAction(tr("Remove"), menu); + connect(removeMaterialAction, + &QAction::triggered, + menu, + std::bind(&Edit3DMaterialsAction::removeMaterial, this, materialId, nthMaterial)); + + QAction *editMaterialAction = new QAction(tr("Edit"), menu); + connect(editMaterialAction, &QAction::triggered, menu, [material] { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor", true); + if (auto materialView = material.view()) + materialView->emitCustomNotification("select_material", {material}); + }); + + menu->addAction(editMaterialAction); + menu->addAction(removeMaterialAction); + action->setMenu(menu); + + return action; +} + +}; // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.h b/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.h new file mode 100644 index 00000000000..3c483ffeb39 --- /dev/null +++ b/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.h @@ -0,0 +1,31 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#pragma once + +#include + +#include +#include + +namespace QmlDesigner { + +class ModelNode; + +class Edit3DMaterialsAction : public QAction +{ + Q_OBJECT +public: + Edit3DMaterialsAction(const QIcon &icon, QObject *parent); + + void updateMenu(const QList &selecedNodes); + +private slots: + void removeMaterial(const QString &materialId, int nthMaterial); + +private: + QAction *createMaterialAction(const ModelNode &material, QMenu *parentMenu, int nthMaterial); + + QList m_selectedNodes; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index a3eedd7bc28..e13f7440c9a 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -26,7 +26,7 @@ #include "variantproperty.h" #include -#include +#include #include #include @@ -41,7 +41,6 @@ #include #include #include - #include namespace QmlDesigner { @@ -86,7 +85,6 @@ WidgetInfo Edit3DView::widgetInfo() return createWidgetInfo(m_edit3DWidget.data(), "Editor3D", WidgetInfo::CentralPane, - 0, tr("3D"), tr("3D view"), DesignerWidgetFlags::IgnoreErrors); @@ -1306,22 +1304,25 @@ void Edit3DView::createEdit3DActions() this, [this] { setCameraSpeedAuxData(m_cameraSpeedConfiguration->speed(), m_cameraSpeedConfiguration->multiplier()); - }); + }); + connect(m_cameraSpeedConfiguration.data(), &CameraSpeedConfiguration::accessibilityOpened, + this, [this] { + m_cameraSpeedConfigAction->setIndicator(false); + }); } m_cameraSpeedConfiguration->showConfigDialog(resolveToolbarPopupPos(m_cameraSpeedConfigAction.get())); }; - m_cameraSpeedConfigAction = std::make_unique( + m_cameraSpeedConfigAction = std::make_unique( QmlDesigner::Constants::EDIT3D_CAMERA_SPEED_CONFIG, View3DActionType::Empty, - QCoreApplication::translate("CameraSpeedConfigAction", "Open camera speed configuration dialog"), - QKeySequence(), - false, - false, + QCoreApplication::translate("CameraSpeedConfigAction", + "Open camera speed configuration dialog"), toolbarIcon(DesignerIcons::CameraSpeedConfigIcon), - this, - cameraSpeedConfigTrigger); + cameraSpeedConfigTrigger, + this); + m_cameraSpeedConfigAction->setIndicator(!isQDSTrusted()); m_leftActions << m_selectionModeAction.get(); m_leftActions << nullptr; // Null indicates separator diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index 755efc0ae38..9e9bce13587 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -18,6 +18,10 @@ #include #include +#ifdef Q_OS_MACOS +extern "C" bool AXIsProcessTrusted(); +#endif + QT_BEGIN_NAMESPACE class QAction; class QInputEvent; @@ -41,6 +45,15 @@ public: bool showWireframe = false; }; + static bool isQDSTrusted() + { +#ifdef Q_OS_MACOS + return AXIsProcessTrusted(); +#else + return true; +#endif + } + Edit3DView(ExternalDependenciesInterface &externalDependencies); WidgetInfo widgetInfo() override; @@ -180,7 +193,7 @@ private: std::unique_ptr m_backgroundColorMenuAction; std::unique_ptr m_snapToggleAction; std::unique_ptr m_snapConfigAction; - std::unique_ptr m_cameraSpeedConfigAction; + std::unique_ptr m_cameraSpeedConfigAction; std::unique_ptr m_bakeLightsAction; int particlemode; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index e77c0bb9c47..5fb6c50fdd6 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -5,6 +5,7 @@ #include "edit3dactions.h" #include "edit3dcanvas.h" +#include "edit3dmaterialsaction.h" #include "edit3dtoolbarmenu.h" #include "edit3dview.h" @@ -35,7 +36,7 @@ #include #include -#include +#include #include #include @@ -205,13 +206,8 @@ void Edit3DWidget::createContextMenu() DocumentManager::goIntoComponent(m_view->singleSelectedModelNode()); }); - m_editMaterialAction = m_contextMenu->addAction( - contextIcon(DesignerIcons::MaterialIcon), - tr("Edit Material"), [&] { - SelectionContext selCtx(m_view); - selCtx.setTargetNode(m_contextMenuTarget); - ModelNodeOperations::editMaterial(selCtx); - }); + m_materialsAction = new Edit3DMaterialsAction(contextIcon(DesignerIcons::MaterialIcon), this); + m_contextMenu->addAction(m_materialsAction); m_contextMenu->addSeparator(); @@ -374,7 +370,19 @@ void Edit3DWidget::createContextMenu() m_addToContentLibAction = m_contextMenu->addAction( contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon tr("Add to Content Library"), [&] { - view()->emitCustomNotification("add_3d_to_content_lib", {m_contextMenuTarget}); + view()->emitCustomNotification("add_3d_to_content_lib", {m_contextMenuTarget}); // To ContentLibrary + }); + + m_importBundleAction = m_contextMenu->addAction( + contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon + tr("Import Component"), [&] { + view()->emitCustomNotification("import_bundle_to_project"); // To ContentLibrary + }); + + m_exportBundleAction = m_contextMenu->addAction( + contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon + tr("Export Component"), [&] { + view()->emitCustomNotification("export_item_as_bundle", {m_contextMenuTarget}); // To ContentLibrary }); m_contextMenu->addSeparator(); @@ -644,7 +652,7 @@ void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode m_createSubMenu->setEnabled(!isSceneLocked()); m_editComponentAction->setEnabled(isSingleComponent); - m_editMaterialAction->setEnabled(isModel); + m_materialsAction->setEnabled(isModel); m_duplicateAction->setEnabled(selectionExcludingRoot); m_copyAction->setEnabled(selectionExcludingRoot); m_pasteAction->setEnabled(isPasteAvailable()); @@ -657,6 +665,8 @@ void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode m_bakeLightsAction->setVisible(view()->bakeLightsAction()->action()->isVisible()); m_bakeLightsAction->setEnabled(view()->bakeLightsAction()->action()->isEnabled()); m_addToContentLibAction->setEnabled(isNode && !isInBundle); + m_exportBundleAction->setEnabled(isNode); + m_materialsAction->updateMenu(view()->selectedModelNodes()); if (m_view) { int idx = m_view->activeSplit(); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h index 97c0469668f..cfed01669e3 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h @@ -21,6 +21,7 @@ namespace QmlDesigner { class Edit3DView; class Edit3DCanvas; class ToolBox; +class Edit3DMaterialsAction; struct ItemLibraryDetails { QString name; @@ -89,7 +90,6 @@ private: QPointer m_contextMenu; QPointer m_bakeLightsAction; QPointer m_editComponentAction; - QPointer m_editMaterialAction; QPointer m_duplicateAction; QPointer m_copyAction; QPointer m_pasteAction; @@ -100,7 +100,10 @@ private: QPointer m_selectParentAction; QPointer m_toggleGroupAction; QPointer m_wireFrameAction; + QPointer m_importBundleAction; + QPointer m_exportBundleAction; QPointer m_addToContentLibAction; + QPointer m_materialsAction; QHash> m_matOverrideActions; QPointer m_createSubMenu; ModelNode m_contextMenuTarget; diff --git a/src/plugins/qmldesigner/components/edit3d/indicatoractionwidget.cpp b/src/plugins/qmldesigner/components/edit3d/indicatoractionwidget.cpp new file mode 100644 index 00000000000..664ad323b9a --- /dev/null +++ b/src/plugins/qmldesigner/components/edit3d/indicatoractionwidget.cpp @@ -0,0 +1,193 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "indicatoractionwidget.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace QmlDesigner { + +static void drawIndicator(QPainter *painter, const QPoint &point, int dimension) +{ + painter->save(); + painter->setPen(Qt::NoPen); + painter->setBrush(Theme::getColor(Theme::DSamberLight)); + painter->drawEllipse(point, dimension, dimension); + painter->restore(); +} + +IndicatorButton::IndicatorButton(QWidget *parent) + : QToolButton(parent) +{ + Utils::StyleHelper::setPanelWidget(this); + Utils::StyleHelper::setPanelWidgetSingleRow(this); +} + +bool IndicatorButton::indicator() const +{ + return m_indicator; +} + +void IndicatorButton::setIndicator(bool newIndicator) +{ + if (m_indicator != newIndicator) { + m_indicator = newIndicator; + emit indicatorChanged(m_indicator); + update(); + } +} + +QSize IndicatorButton::sizeHint() const +{ + if (QMenu *menu = qobject_cast(parent())) { + ensurePolished(); + QStyleOptionMenuItem opt; + initMenuStyleOption(menu, &opt, defaultAction()); + QSize sz = style() + ->itemTextRect(fontMetrics(), QRect(), Qt::TextShowMnemonic, false, text()) + .size(); + if (!opt.icon.isNull()) + sz = QSize(sz.width() + opt.maxIconWidth + 4, qMax(sz.height(), opt.maxIconWidth)); + QSize size = style()->sizeFromContents(QStyle::CT_MenuItem, &opt, sz, this); + return size; + } + return Super::sizeHint(); +} + +void IndicatorButton::paintEvent([[maybe_unused]] QPaintEvent *event) +{ + QStylePainter p(this); + + if (QMenu *menu = qobject_cast(parent())) { + this->setFixedWidth(menu->width()); + QStyleOptionMenuItem opt; + initMenuStyleOption(menu, &opt, defaultAction()); + p.drawControl(QStyle::CE_MenuItem, opt); + + if (indicator() && opt.maxIconWidth && !opt.icon.isNull()) { + const int indicatorDim = opt.rect.height() / 8; + const int indicatorOffset = indicatorDim * 5 / 4; + + drawIndicator(&p, + opt.rect.topLeft() + + QPoint{opt.rect.height() - indicatorOffset, indicatorOffset}, + indicatorDim); + } + } else { + QStyleOptionToolButton option; + initStyleOption(&option); + p.drawComplexControl(QStyle::CC_ToolButton, option); + + if (indicator() && option.iconSize.isValid() && !option.icon.isNull()) { + const int indicatorDim = std::min(option.rect.width(), option.rect.height()) / 8; + const int indicatorOffset = indicatorDim * 5 / 4; + drawIndicator(&p, + option.rect.topRight() + QPoint{-indicatorOffset, indicatorOffset}, + indicatorDim); + } + } +} + +void IndicatorButton::initMenuStyleOption(QMenu *menu, + QStyleOptionMenuItem *option, + const QAction *action) const +{ + if (!option || !action) + return; + + option->initFrom(menu); + option->palette = palette(); + option->state = QStyle::State_None; + + if (window()->isActiveWindow()) + option->state |= QStyle::State_Active; + if (isEnabled() && action->isEnabled() && (!action->menu() || action->menu()->isEnabled())) + option->state |= QStyle::State_Enabled; + else + option->palette.setCurrentColorGroup(QPalette::Disabled); + + option->font = action->font().resolve(font()); + option->fontMetrics = QFontMetrics(option->font); + + if (menu->activeAction() && menu->activeAction() == action) + option->state |= QStyle::State_Selected; + + option->menuHasCheckableItems = false; + if (!action->isCheckable()) { + option->checkType = QStyleOptionMenuItem::NotCheckable; + } else { + option->checkType = (action->actionGroup() && action->actionGroup()->isExclusive()) + ? QStyleOptionMenuItem::Exclusive + : QStyleOptionMenuItem::NonExclusive; + option->checked = action->isChecked(); + } + if (action->menu()) + option->menuItemType = QStyleOptionMenuItem::SubMenu; + else if (action->isSeparator()) + option->menuItemType = QStyleOptionMenuItem::Separator; + else + option->menuItemType = QStyleOptionMenuItem::Normal; + if (action->isIconVisibleInMenu()) + option->icon = action->icon(); + + option->text = action->text(); + option->maxIconWidth = 20; + option->rect = rect(); +} + +IndicatorButtonAction::IndicatorButtonAction(const QString &description, + const QIcon &icon, + QObject *parent) + : QWidgetAction(parent) +{ + setText(description); + setToolTip(description); + setIcon(icon); +} + +IndicatorButtonAction::~IndicatorButtonAction() = default; + +void IndicatorButtonAction::setIndicator(bool indicator) +{ + if (m_indicator != indicator) { + m_indicator = indicator; + emit indicatorChanged(m_indicator, QPrivateSignal{}); + } +} + +QWidget *IndicatorButtonAction::createWidget(QWidget *parent) +{ + if (qobject_cast(parent)) + return nullptr; + + IndicatorButton *button = new IndicatorButton(parent); + + connect(this, &IndicatorButtonAction::indicatorChanged, button, &IndicatorButton::setIndicator); + connect(button, &IndicatorButton::indicatorChanged, this, &IndicatorButtonAction::setIndicator); + connect(button, &QToolButton::clicked, this, &QAction::trigger); + button->setIndicator(m_indicator); + button->setDefaultAction(this); + + if (QToolBar *tb = qobject_cast(parent)) { + button->setAutoRaise(true); + button->setFocusPolicy(Qt::NoFocus); + button->setIconSize(tb->iconSize()); + button->setToolButtonStyle(tb->toolButtonStyle()); + connect(tb, &QToolBar::iconSizeChanged, button, &IndicatorButton::setIconSize); + connect(tb, &QToolBar::toolButtonStyleChanged, button, &IndicatorButton::setToolButtonStyle); + connect(button, &IndicatorButton::triggered, tb, &QToolBar::actionTriggered); + } + + return button; +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/indicatoractionwidget.h b/src/plugins/qmldesigner/components/edit3d/indicatoractionwidget.h new file mode 100644 index 00000000000..dd34fa50588 --- /dev/null +++ b/src/plugins/qmldesigner/components/edit3d/indicatoractionwidget.h @@ -0,0 +1,63 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#pragma once + +#include +#include + +QT_BEGIN_NAMESPACE +class QStyleOptionToolButton; +class QPaintEvent; +class QStyleOptionMenuItem; +QT_END_NAMESPACE + +namespace QmlDesigner { + +class IndicatorButton : public QToolButton +{ + Q_OBJECT + + Q_PROPERTY(bool indicator READ indicator WRITE setIndicator NOTIFY indicatorChanged FINAL) +public: + explicit IndicatorButton(QWidget *parent = nullptr); + + bool indicator() const; + void setIndicator(bool newIndicator); + +protected: + QSize sizeHint() const override; + void paintEvent(QPaintEvent *event) override; + void initMenuStyleOption(QMenu *menu, QStyleOptionMenuItem *option, const QAction *action) const; + +signals: + void indicatorChanged(bool); + +private: + bool m_indicator = false; + using Super = QToolButton; +}; + +class IndicatorButtonAction : public QWidgetAction +{ + Q_OBJECT + +public: + explicit IndicatorButtonAction(const QString &description, + const QIcon &icon, + QObject *parent = nullptr); + virtual ~IndicatorButtonAction(); + +public slots: + void setIndicator(bool indicator); + +protected: + virtual QWidget *createWidget(QWidget *parent) override; + +private: + bool m_indicator; + +signals: + void indicatorChanged(bool, QPrivateSignal); +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp index 657fb4773e0..b8913546647 100644 --- a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp @@ -9,7 +9,7 @@ #include "modelnodecontextmenu.h" #include "qmldesignerconstants.h" -#include +#include #include #include diff --git a/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp b/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp index 9d9139cf017..4a4bce6dd71 100644 --- a/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp +++ b/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp @@ -10,6 +10,8 @@ #include #include +#include + namespace QmlDesigner { BackgroundAction::BackgroundAction(QObject *parent) : @@ -21,7 +23,17 @@ void BackgroundAction::setColor(const QColor &color) { if (m_comboBox) m_comboBox->setCurrentIndex(colors().indexOf(color)); +} +void BackgroundAction::setColorEnabled(const QColor &color, bool enable) +{ + if (!m_comboBox) + return; + + QStandardItemModel *model = qobject_cast(m_comboBox->model()); + if (QStandardItem *item = model->item(colors().indexOf(color))) + item->setFlags(enable ? item->flags() | Qt::ItemIsEnabled + : item->flags() & ~Qt::ItemIsEnabled); } QIcon iconForColor(const QColor &color) { diff --git a/src/plugins/qmldesigner/components/formeditor/backgroundaction.h b/src/plugins/qmldesigner/components/formeditor/backgroundaction.h index c6eeb212fe4..604a9aae720 100644 --- a/src/plugins/qmldesigner/components/formeditor/backgroundaction.h +++ b/src/plugins/qmldesigner/components/formeditor/backgroundaction.h @@ -20,6 +20,7 @@ public: explicit BackgroundAction(QObject *parent); void setColor(const QColor &color); + void setColorEnabled(const QColor &color, bool enable); signals: void backgroundChanged(const QColor &color); diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp index b3df6b8fe72..e8f8846466b 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp @@ -200,7 +200,7 @@ qreal FormEditorItem::selectionWeigth(const QPointF &point, int iteration) return weight; } -void FormEditorItem::synchronizeOtherProperty(const QByteArray &propertyName) +void FormEditorItem::synchronizeOtherProperty(PropertyNameView propertyName) { if (propertyName == "opacity") setOpacity(qmlItemNode().instanceValue("opacity").toDouble()); @@ -557,7 +557,7 @@ QmlItemNode FormEditorItem::qmlItemNode() const return m_qmlItemNode; } -void FormEditorFlowItem::synchronizeOtherProperty(const QByteArray &) +void FormEditorFlowItem::synchronizeOtherProperty(PropertyNameView) { setContentVisible(true); } @@ -783,7 +783,7 @@ QTransform FormEditorFlowActionItem::instanceSceneContentItemTransform() const return sceneTransform(); } -void FormEditorTransitionItem::synchronizeOtherProperty(const QByteArray &) +void FormEditorTransitionItem::synchronizeOtherProperty(PropertyNameView) { setContentVisible(true); } diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.h b/src/plugins/qmldesigner/components/formeditor/formeditoritem.h index 3629d500e29..64569592394 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.h @@ -87,7 +87,7 @@ public: QPointF center() const; qreal selectionWeigth(const QPointF &point, int iteration); - virtual void synchronizeOtherProperty(const QByteArray &propertyName); + virtual void synchronizeOtherProperty(PropertyNameView propertyName); virtual void setDataModelPosition(const QPointF &position); virtual void setDataModelPositionInBaseState(const QPointF &position); virtual QPointF instancePosition() const; @@ -141,7 +141,7 @@ class FormEditorFlowItem : public FormEditorItem friend FormEditorScene; public: - void synchronizeOtherProperty(const QByteArray &propertyName) override; + void synchronizeOtherProperty(PropertyNameView propertyName) override; void setDataModelPosition(const QPointF &position) override; void setDataModelPositionInBaseState(const QPointF &position) override; void updateGeometry() override; @@ -198,7 +198,7 @@ class FormEditorTransitionItem : public FormEditorItem friend FormEditorScene; public: - void synchronizeOtherProperty(const QByteArray &propertyName) override; + void synchronizeOtherProperty(PropertyNameView propertyName) override; void setDataModelPosition(const QPointF &position) override; void setDataModelPositionInBaseState(const QPointF &position) override; void updateGeometry() override; diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp index cd89b74853d..24522f41453 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp @@ -142,7 +142,7 @@ void FormEditorScene::synchronizeParent(const QmlItemNode &qmlItemNode) reparentItem(qmlItemNode, parentNode); } -void FormEditorScene::synchronizeOtherProperty(FormEditorItem *item, const QByteArray &propertyName) +void FormEditorScene::synchronizeOtherProperty(FormEditorItem *item, PropertyNameView propertyName) { Q_ASSERT(item); diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorscene.h b/src/plugins/qmldesigner/components/formeditor/formeditorscene.h index 133991d5b79..29330402b82 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorscene.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditorscene.h @@ -59,7 +59,7 @@ public: void synchronizeTransformation(FormEditorItem *item); void synchronizeParent(const QmlItemNode &qmlItemNode); - void synchronizeOtherProperty(FormEditorItem *item, const QByteArray &propertyName); + void synchronizeOtherProperty(FormEditorItem *item, PropertyNameView propertyName); FormEditorItem* calulateNewParent(FormEditorItem *widget); LayerItem* manipulatorLayerItem() const; diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index 841a6422042..8d4c7979da3 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -364,7 +364,6 @@ WidgetInfo FormEditorView::widgetInfo() return createWidgetInfo(m_formEditorWidget.data(), "FormEditor", WidgetInfo::CentralPane, - 0, tr("2D"), tr("2D view"), DesignerWidgetFlags::IgnoreErrors); @@ -996,10 +995,8 @@ void FormEditorView::setupRootItemSize() formEditorWidget()->setRootItemRect(rootRect); formEditorWidget()->centerScene(); - auto contextImage = rootModelNode().auxiliaryData(contextImageProperty); - - if (contextImage) - m_formEditorWidget->setBackgoundImage(contextImage.value().value()); + if (auto contextImage = rootModelNode().auxiliaryData(contextImageProperty)) + formEditorWidget()->setBackgoundImage(contextImage.value().value()); } } diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp index 3b9295f9278..19639d435d3 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp @@ -330,24 +330,14 @@ void FormEditorWidget::changeRootItemHeight(const QString &heighText) } } -namespace { -constexpr AuxiliaryDataKeyView formeditorColorProperty{AuxiliaryDataType::Temporary, - "formeditorColor"}; -} - void FormEditorWidget::changeBackgound(const QColor &color) { - if (color.alpha() == 0) { + if (color.alpha() == 0) m_graphicsView->activateCheckboardBackground(); - if (m_formEditorView->rootModelNode().hasAuxiliaryData(formeditorColorProperty)) { - m_formEditorView->rootModelNode().setAuxiliaryDataWithoutLock(formeditorColorProperty, - {}); - } - } else { + else m_graphicsView->activateColoredBackground(color); - m_formEditorView->rootModelNode().setAuxiliaryDataWithoutLock(formeditorColorProperty, - color); - } + + m_formEditorView->rootModelNode().setAuxiliaryDataWithoutLock(formeditorColorProperty, color); } void FormEditorWidget::registerActionAsCommand( @@ -408,8 +398,12 @@ void FormEditorWidget::updateActions() m_backgroundAction->setColor(Qt::transparent); } - if (m_formEditorView->rootModelNode().hasAuxiliaryData(contextImageProperty)) + if (m_formEditorView->rootModelNode().hasAuxiliaryData(contextImageProperty)) { + m_backgroundAction->setColorEnabled(BackgroundAction::ContextImage, true); m_backgroundAction->setColor(BackgroundAction::ContextImage); + } else { + m_backgroundAction->setColorEnabled(BackgroundAction::ContextImage, false); + } } else { m_rootWidthAction->clearLineEditText(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.cpp b/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.cpp index 608bf42eb36..d4480ccdb65 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.cpp @@ -34,6 +34,12 @@ void Import3dCanvas::updateRenderImage(const QImage &img) update(); } +void Import3dCanvas::displayError(const QString &error) +{ + m_errorMsg = error; + update(); +} + void Import3dCanvas::paintEvent([[maybe_unused]] QPaintEvent *e) { QWidget::paintEvent(e); @@ -46,6 +52,9 @@ void Import3dCanvas::paintEvent([[maybe_unused]] QPaintEvent *e) } else { painter.drawImage(rect(), m_image, QRect(0, 0, m_image.width(), m_image.height())); } + + if (!m_errorMsg.isEmpty()) + painter.drawText(QRect(0, 0, width(), height()), Qt::AlignHCenter | Qt::AlignVCenter, m_errorMsg); } void Import3dCanvas::resizeEvent(QResizeEvent *) diff --git a/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.h b/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.h index 72fb19acffc..5df000e763a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.h +++ b/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.h @@ -17,6 +17,7 @@ public: Import3dCanvas(QWidget *parent); void updateRenderImage(const QImage &img); + void displayError(const QString &error); signals: void requestImageUpdate(); @@ -32,6 +33,7 @@ protected: private: QImage m_image; QPointF m_dragPos; + QString m_errorMsg; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/import3dconnectionmanager.cpp b/src/plugins/qmldesigner/components/itemlibrary/import3dconnectionmanager.cpp index 4c455e3c6d2..efa5c27bca3 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/import3dconnectionmanager.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/import3dconnectionmanager.cpp @@ -16,6 +16,11 @@ Import3dConnectionManager::Import3dConnectionManager() connections().emplace_back("Import 3D", "import3dmode"); } +void Import3dConnectionManager::setPreviewIconCallback(IconCallback callback) +{ + m_previewIconCallback = std::move(callback); +} + void Import3dConnectionManager::setPreviewImageCallback(ImageCallback callback) { m_previewImageCallback = std::move(callback); @@ -29,6 +34,15 @@ void Import3dConnectionManager::dispatchCommand(const QVariant &command, if (command.typeId() == commandType) { auto cmd = command.value(); switch (cmd.type()) { + case PuppetToCreatorCommand::Import3DPreviewIcon: { + const QVariantList data = cmd.data().toList(); + const QString assetName = data[0].toString(); + ImageContainer container = qvariant_cast(data[1]); + QImage image = container.image(); + if (!image.isNull()) + m_previewIconCallback(assetName, image); + break; + } case PuppetToCreatorCommand::Import3DPreviewImage: { ImageContainer container = qvariant_cast(cmd.data()); QImage image = container.image(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/import3dconnectionmanager.h b/src/plugins/qmldesigner/components/itemlibrary/import3dconnectionmanager.h index 458d612ad2d..cc6b90b3f2e 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/import3dconnectionmanager.h +++ b/src/plugins/qmldesigner/components/itemlibrary/import3dconnectionmanager.h @@ -12,16 +12,19 @@ namespace QmlDesigner { class Import3dConnectionManager : public InteractiveConnectionManager { public: + using IconCallback = std::function; using ImageCallback = std::function; Import3dConnectionManager(); + void setPreviewIconCallback(IconCallback callback); void setPreviewImageCallback(ImageCallback callback); protected: void dispatchCommand(const QVariant &command, Connection &connection) override; private: + IconCallback m_previewIconCallback; ImageCallback m_previewImageCallback; }; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp index 8b3f2dee79d..fe6c9058a73 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include #include #include @@ -73,6 +75,9 @@ void ItemLibraryAddImportModel::update(const Imports &possibleImports) const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); const bool isQtForMCUs = mcuManager.isMCUProject(); Imports filteredImports; + + const bool isLiteDesigner = QmlDesigner::QmlDesignerBasePlugin::isLiteModeEnabled(); + if (isQtForMCUs) { const QStringList mcuAllowedList = mcuManager.allowedImports(); const QStringList mcuBannedList = mcuManager.bannedImports(); @@ -82,6 +87,11 @@ void ItemLibraryAddImportModel::update(const Imports &possibleImports) || !import.url().startsWith("Qt")) && !mcuBannedList.contains(import.url()); }); + } else if (isLiteDesigner) { + const QStringList liteAllowedList = {"QtQuick", "QtQuick.Layouts", "QtQuick.Controls"}; + filteredImports = Utils::filtered(possibleImports, [&](const Import &import) { + return (liteAllowedList.contains(import.url()) || !import.url().startsWith("Qt")); + }); } else { filteredImports = possibleImports; } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp index 271410233b2..b9252a874f7 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp @@ -7,8 +7,10 @@ #include "import3dcanvas.h" #include "import3dconnectionmanager.h" +#include +#include #include -#include +#include #include #include #include @@ -18,6 +20,7 @@ #include #include +#include #include #include @@ -25,7 +28,9 @@ #include #include +#include #include +#include #include #include #include @@ -63,6 +68,17 @@ void addFormattedMessage(Utils::OutputFormatter *formatter, formatter->plainTextEdit()->verticalScrollBar()->maximum()); } +QIcon iconFromIconFont(Theme::Icon iconType, const QColor &color) +{ + const QString unicode = Theme::getIconUnicode(iconType); + const QString fontName = "qtds_propertyIconFont.ttf"; + + const auto helper = Utils::StyleHelper::IconFontHelper( + unicode, color, QSize(28, 28), QIcon::Normal); + + return Utils::StyleHelper::getIconFromIconFont(fontName, {helper}); +} + const int rowHeight = 32; const int checkBoxColWidth = 18; const int labelMinWidth = 130; @@ -88,6 +104,11 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog( setModal(true); ui->setupUi(this); + m_selectedRemoveIcon = iconFromIconFont(Theme::Icon::delete_small, + Theme::getColor(Theme::IconsBaseColor)); + m_unselectedRemoveIcon = iconFromIconFont(Theme::Icon::delete_small, + Theme::getColor(Theme::IconsDisabledColor)); + m_outputFormatter = new Utils::OutputFormatter; m_outputFormatter->setPlainTextEdit(ui->plainTextEdit); @@ -239,20 +260,18 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog( connect(ui->advancedSettingsButton, &QPushButton::clicked, this, &ItemLibraryAssetImportDialog::toggleAdvanced); + connect(ui->importList, &QListWidget::currentItemChanged, + this, &ItemLibraryAssetImportDialog::onCurrentItemChanged); QTimer::singleShot(0, this, &ItemLibraryAssetImportDialog::updateUi); - if (m_quick3DFiles.size() != 1) { - addInfo(tr("Select import options and press \"Import\" to import the following files:")); - } else { - addInfo(tr("Importing:")); - QTimer::singleShot(0, this, &ItemLibraryAssetImportDialog::onImport); - } + addInfo(tr("Importing:")); + QTimer::singleShot(0, this, &ItemLibraryAssetImportDialog::onImport); for (const auto &file : std::as_const(m_quick3DFiles)) addInfo(file); - updateImportButtonState(); + m_updatingControlStates = false; } ItemLibraryAssetImportDialog::~ItemLibraryAssetImportDialog() @@ -385,6 +404,15 @@ void ItemLibraryAssetImportDialog::updateImport(AbstractView *view, } } +void ItemLibraryAssetImportDialog::keyPressEvent(QKeyEvent *event) +{ + if ((event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete) + && ui->importList->currentItem()) { + onRemoveAsset(assetNameForListItem(ui->importList->currentItem())); + } + return QDialog::keyPressEvent(event); +} + void ItemLibraryAssetImportDialog::createTab(const QString &tabLabel, int optionsIndex, const QJsonObject &groups) { @@ -501,7 +529,7 @@ QGridLayout *ItemLibraryAssetImportDialog::createOptionsGrid( QJsonValue value(optCheck->isChecked()); optObj.insert("value", value); m_importOptions[optionsIndex].insert(optKey, optObj); - updateImportButtonState(); + updatePreviewOptions(); }); } else { // Simple options also exist in advanced, so don't connect simple controls directly @@ -512,13 +540,13 @@ QGridLayout *ItemLibraryAssetImportDialog::createOptionsGrid( QObject::connect(optCheck, &QCheckBox::toggled, this, [this, optCheck, advCheck]() { if (advCheck->isChecked() != optCheck->isChecked()) { advCheck->setChecked(optCheck->isChecked()); - updateImportButtonState(); + updatePreviewOptions(); } }); QObject::connect(advCheck, &QCheckBox::toggled, this, [this, optCheck, advCheck]() { if (advCheck->isChecked() != optCheck->isChecked()) { optCheck->setChecked(advCheck->isChecked()); - updateImportButtonState(); + updatePreviewOptions(); } }); } @@ -555,7 +583,7 @@ QGridLayout *ItemLibraryAssetImportDialog::createOptionsGrid( QJsonValue value(optSpin->value()); optObj.insert("value", value); m_importOptions[optionsIndex].insert(optKey, optObj); - updateImportButtonState(); + updatePreviewOptions(); }); } else { auto *advSpin = qobject_cast( @@ -566,14 +594,14 @@ QGridLayout *ItemLibraryAssetImportDialog::createOptionsGrid( this, [this, optSpin, advSpin] { if (advSpin->value() != optSpin->value()) { advSpin->setValue(optSpin->value()); - updateImportButtonState(); + updatePreviewOptions(); } }); QObject::connect(advSpin, &QDoubleSpinBox::valueChanged, this, [this, optSpin, advSpin] { if (advSpin->value() != optSpin->value()) { optSpin->setValue(advSpin->value()); - updateImportButtonState(); + updatePreviewOptions(); } }); } @@ -830,6 +858,15 @@ void ItemLibraryAssetImportDialog::updateUi() } } +QString ItemLibraryAssetImportDialog::assetNameForListItem(QListWidgetItem *item) +{ + for (const ImportData &data : std::as_const(m_importData)) { + if (data.listItem == item) + return data.previewData.name; + } + return {}; +} + bool ItemLibraryAssetImportDialog::isSimpleGroup(const QString &id) { static QStringList simpleGroups { @@ -859,6 +896,15 @@ bool ItemLibraryAssetImportDialog::isHiddenOption(const QString &id) return hiddenOptions.contains(id); } +bool ItemLibraryAssetImportDialog::optionsChanged() +{ + for (const ImportData &data : std::as_const(m_importData)) { + if (data.previewData.renderedOptions != data.previewData.currentOptions) + return true; + } + return false; +} + void ItemLibraryAssetImportDialog::startPreview() { cleanupPreviewPuppet(); @@ -876,8 +922,9 @@ Rectangle { property alias sceneNode: sceneNode property alias view3d: view3d + property alias iconView3d: iconView3d property string extents - property string sceneModelName: "%3" + property string sceneModelName gradient: Gradient { GradientStop { position: 1.0; color: "#222222" } @@ -890,30 +937,46 @@ Rectangle { camera: viewCamera environment: SceneEnvironment { + id: sceneEnvironment + lightProbe: probeTexture antialiasingMode: SceneEnvironment.MSAA antialiasingQuality: SceneEnvironment.VeryHigh } - PerspectiveCamera { - id: viewCamera - x: 600 - y: 600 - z: 600 - eulerRotation.x: -45 - eulerRotation.y: -45 - clipFar: 100000 - clipNear: 10 - } - - DirectionalLight { - rotation: viewCamera.rotation - } - Node { id: sceneNode + PerspectiveCamera { + id: viewCamera + x: 600 + y: 600 + z: 600 + eulerRotation.x: -45 + eulerRotation.y: -45 + clipFar: 100000 + clipNear: 10 + } + + DirectionalLight { + rotation: viewCamera.rotation + } + + Texture { + id: probeTexture + source: "qrc:/qtquickplugin/mockfiles/images/preview_studio.hdr" + } } } + View3D { + id: iconView3d + importScene: sceneNode + camera: viewCamera + environment: sceneEnvironment + visible: false + width: 48 + height: 48 + } + Text { anchors.bottom: parent.bottom anchors.left: parent.left @@ -925,7 +988,7 @@ Rectangle { )"; QSize size = canvas()->size(); - previewQml = previewQml.arg(size.width()).arg(size.height()).arg(m_previewCompName); + previewQml = previewQml.arg(size.width()).arg(size.height()); m_previewFile.writeFileContents(previewQml.toUtf8()); @@ -957,17 +1020,29 @@ Rectangle { return; } - m_nodeInstanceView->setTarget(m_view->nodeInstanceView()->target()); + m_nodeInstanceView->setTarget(ProjectExplorer::ProjectManager::startupTarget()); + + auto previewIconCallback = [this](const QString &assetName, const QImage &image) { + if (!m_importData.contains(assetName)) { + addWarning(tr("Preview icon generated for non-existent asset: %1").arg(assetName)); + return; + } + if (m_importData[assetName].iconLabel) + m_importData[assetName].iconLabel->setPixmap(QPixmap::fromImage(image)); + }; auto previewImageCallback = [this](const QImage &image) { canvas()->updateRenderImage(image); }; auto crashCallback = [&] { - addWarning("Preview process crashed."); - cleanupPreviewPuppet(); + const QString errorMsg(tr("Preview generation process crashed.")); + addWarning(errorMsg); + canvas()->displayError(errorMsg); + QTimer::singleShot(0, this, &ItemLibraryAssetImportDialog::cleanupPreviewPuppet); }; + m_connectionManager->setPreviewIconCallback(std::move(previewIconCallback)); m_connectionManager->setPreviewImageCallback(std::move(previewImageCallback)); m_nodeInstanceView->setCrashCallback(std::move(crashCallback)); @@ -985,8 +1060,10 @@ void ItemLibraryAssetImportDialog::cleanupPreviewPuppet() if (m_nodeInstanceView) m_nodeInstanceView->setCrashCallback({}); - if (m_connectionManager) + if (m_connectionManager) { + m_connectionManager->setPreviewIconCallback({}); m_connectionManager->setPreviewImageCallback({}); + } delete m_rewriterView; delete m_nodeInstanceView; @@ -998,6 +1075,31 @@ Import3dCanvas *ItemLibraryAssetImportDialog::canvas() return ui->import3dcanvas; } +void ItemLibraryAssetImportDialog::resetOptionControls() +{ + const QString currentName = assetNameForListItem(ui->importList->currentItem()); + if (!m_importData.contains(currentName)) + return; + + m_updatingControlStates = true; + + const ImportData &data = m_importData[currentName]; + const QJsonObject options = data.previewData.currentOptions; + const QStringList optKeys = options.keys(); + for (const QString &optKey : optKeys) { + QWidget *w = m_labelToControlWidgetMaps[data.previewData.optionsIndex].value(optKey); + const QJsonObject optObj = options.value(optKey).toObject(); + const QJsonValue optValue = optObj.value("value"); + if (auto *cb = qobject_cast(w)) + cb->setChecked(optValue.toBool()); + else if (auto *spin = qobject_cast(w)) + spin->setValue(optValue.toDouble()); + } + + m_updatingControlStates = false; + updatePreviewOptions(); +} + void ItemLibraryAssetImportDialog::resizeEvent(QResizeEvent *event) { m_dialogHeight = event->size().height(); @@ -1010,9 +1112,20 @@ void ItemLibraryAssetImportDialog::setCloseButtonState(bool importing) ui->closeButton->setText(importing ? tr("Cancel") : tr("Close")); } -void ItemLibraryAssetImportDialog::updateImportButtonState() +void ItemLibraryAssetImportDialog::updatePreviewOptions() { - ui->importButton->setText(m_previewOptions == m_importOptions ? tr("Accept") : tr("Import")); + if (m_updatingControlStates) + return; + + if (ui->importList->currentRow() >= 0) { + const QString assetName = assetNameForListItem(ui->importList->currentItem()); + if (m_importData.contains(assetName)) { + ImportData &data = m_importData[assetName]; + data.previewData.currentOptions = m_importOptions[data.previewData.optionsIndex]; + } + } + + ui->importButton->setText(optionsChanged() ? tr("Import") : tr("Accept")); } void ItemLibraryAssetImportDialog::addError(const QString &error, const QString &srcPath) @@ -1035,19 +1148,29 @@ void ItemLibraryAssetImportDialog::addInfo(const QString &info, const QString &s void ItemLibraryAssetImportDialog::onImport() { ui->importButton->setEnabled(false); + ui->tabWidget->setEnabled(false); + ui->importList->setEnabled(false); - if (!m_previewCompName.isEmpty() && m_previewOptions == m_importOptions) { + if (!m_importData.isEmpty() && !optionsChanged()) { cleanupPreviewPuppet(); m_importer.finalizeQuick3DImport(); return; } + const QString assetName = assetNameForListItem(ui->importList->currentItem()); + const ImportData &data = m_importData.value(assetName); + setCloseButtonState(true); ui->progressBar->setValue(0); if (!m_quick3DFiles.isEmpty()) { - if (!m_previewCompName.isEmpty()) { - m_importer.reImportQuick3D(m_previewCompName, m_importOptions); + if (!m_importData.isEmpty()) { + QHash importOptions; + for (const ImportData &data : std::as_const(m_importData)) { + if (data.previewData.renderedOptions != data.previewData.currentOptions) + importOptions.insert(data.previewData.name, data.previewData.currentOptions); + } + m_importer.reImportQuick3D(importOptions); } else { m_importer.importQuick3D(m_quick3DFiles, m_quick3DImportPath, m_importOptions, m_extToImportOptionsMap, @@ -1066,19 +1189,118 @@ void ItemLibraryAssetImportDialog::setImportProgress(int value, const QString &t ui->progressBar->setValue(value); } -void ItemLibraryAssetImportDialog::onImportReadyForPreview(const QString &path, const QString &compName) +void ItemLibraryAssetImportDialog::onImportReadyForPreview( + const QString &path, const QList &previewData) { - addInfo(tr("Import is ready for preview.")); - if (m_previewCompName.isEmpty()) - addInfo(tr("Click \"Accept\" to finish the import or adjust options and click \"Import\" to import again.")); + if (previewData.isEmpty()) { + m_importer.cancelImport(); + return; + } - m_previewFile = Utils::FilePath::fromString(path).pathAppended(m_importer.previewFileName()); - m_previewCompName = compName; - m_previewOptions = m_importOptions; - QTimer::singleShot(0, this, &ItemLibraryAssetImportDialog::startPreview); + QPixmap placeHolder = QPixmap(":/navigator/icon/tooltip_placeholder.png").scaled(48, 48); + + int maxNameLen = 150; + // Used to initially layout infolabel with sufficient height + const QString tallStr = "Wj\nWj\nWj"; + + QStringList assetNames; + for (const ItemLibraryAssetImporter::PreviewData &data : previewData) { + const QString assetName = data.name; + assetNames.append(assetName); + if (!m_importData.contains(assetName)) { + ImportData impData; + impData.previewData = data; + auto lwi = new QListWidgetItem(); + impData.listItem = lwi; + auto w = new QWidget(ui->importList); + w->setToolTip(assetName); + auto layout = new QHBoxLayout(w); + auto iconLabel = new QLabel(w); + iconLabel->setPixmap(placeHolder); + impData.iconLabel = iconLabel; + layout->addWidget(iconLabel); + auto infoLabel = new QLabel(w); + impData.infoLabel = infoLabel; + infoLabel->setText(tallStr); + infoLabel->setFixedWidth(maxNameLen); + layout->addWidget(infoLabel); + layout->addStretch(1); + auto removeButton = new QPushButton(m_unselectedRemoveIcon, {}, w); + removeButton->setFlat(true); + impData.removeButton = removeButton; + layout->addWidget(removeButton, 0, Qt::AlignRight); + layout->setSizeConstraint(QLayout::SetNoConstraint); + w->setLayout(layout); + w->resize(w->height(), ui->importList->width()); + lwi->setSizeHint(w->sizeHint()); + ui->importList->addItem(lwi); + ui->importList->setItemWidget(lwi, w); + m_importData[assetName] = impData; + QObject::connect(removeButton, &QPushButton::clicked, this, [this, assetName]() { + onRemoveAsset(assetName); + }); + } else { + m_importData[assetName].previewData = data; + } + + if (!m_importData.contains(assetName)) + return; + + const ImportData &impData = m_importData[assetName]; + + if (QLabel *l = impData.infoLabel) { + QFontMetrics fm = l->fontMetrics(); + QString truncNameBase = assetName; + QString truncName = assetName; + int truncNameLen = fm.boundingRect(truncName).width(); + while (!truncNameBase.isEmpty() && truncNameLen > maxNameLen) { + truncNameBase.chop(1); + truncName = truncNameBase + "..."; + truncNameLen = fm.boundingRect(truncName).width(); + } + + QString s; + s += truncName + '\n'; + s += tr("Object Type: %1\n").arg(data.type); + s += tr("Import Size: %1").arg(QLocale::system().formattedDataSize( + data.size, 2, QLocale::DataSizeTraditionalFormat)); + l->setText(s); + } + + addInfo(tr("Import ready for preview: %1").arg(assetName)); + } + + if (m_firstImport) { + addInfo(tr("Click \"Accept\" to finish the import or adjust options and click \"Import\" to import again.")); + m_firstImport = false; + } + + if (m_previewFile.isEmpty()) { + m_previewFile = Utils::FilePath::fromString(path).pathAppended(m_importer.previewFileName()); + QTimer::singleShot(0, this, &ItemLibraryAssetImportDialog::startPreview); + } + + QTimer::singleShot(0, this, [this, assetNames]() { + if (!m_nodeInstanceView) + return; + for (const QString &assetName : std::as_const(assetNames)) { + const ImportData &data = m_importData.value(assetName); + if (!data.previewData.name.isEmpty()) { + QVariantHash msgData; + msgData.insert("name", data.previewData.name); + msgData.insert("qmlName", data.previewData.qmlName); + msgData.insert("folder", data.previewData.folderName); + m_nodeInstanceView->view3DAction(View3DActionType::Import3dAddPreviewModel, msgData); + } + } + }); ui->importButton->setEnabled(true); - updateImportButtonState(); + ui->tabWidget->setEnabled(true); + ui->importList->setEnabled(true); + updatePreviewOptions(); + if (ui->importList->currentRow() < 0) + ui->importList->setCurrentRow(0); } void ItemLibraryAssetImportDialog::onRequestImageUpdate() @@ -1119,6 +1341,37 @@ void ItemLibraryAssetImportDialog::onImportFinished() } } +void ItemLibraryAssetImportDialog::onCurrentItemChanged(QListWidgetItem *current, QListWidgetItem *) +{ + if (!current) + return; + + for (const ImportData &data : std::as_const(m_importData)) { + if (data.removeButton) { + if (current == data.listItem) + data.removeButton->setIcon(m_selectedRemoveIcon); + else + data.removeButton->setIcon(m_unselectedRemoveIcon); + } + } + const QString assetName = assetNameForListItem(ui->importList->currentItem()); + resetOptionControls(); + + const ImportData data = m_importData.value(assetName); + for (int i = 0; i < ui->tabWidget->count(); ++i) + ui->tabWidget->widget(i)->setVisible(i == data.previewData.optionsIndex); + ui->tabWidget->setCurrentIndex(data.previewData.optionsIndex); + + QTimer::singleShot(0, this, [this, assetName]() { + if (!m_nodeInstanceView) + return; + if (m_importData.contains(assetName)) { + m_nodeInstanceView->view3DAction(View3DActionType::Import3dSetCurrentPreviewModel, + assetName); + } + }); +} + void ItemLibraryAssetImportDialog::onClose() { ui->importButton->setEnabled(false); @@ -1164,4 +1417,20 @@ void ItemLibraryAssetImportDialog::toggleAdvanced() updateUi(); } +void ItemLibraryAssetImportDialog::onRemoveAsset(const QString &assetName) +{ + m_importer.removeAssetFromImport(assetName); + if (m_importData.contains(assetName)) { + ImportData data = m_importData.take(assetName); + addInfo(tr("Removed %1 from the import.").arg(assetName)); + if (data.listItem) { + ui->importList->removeItemWidget(data.listItem); + delete data.listItem; + } + } + + if (m_importData.isEmpty()) + onClose(); +} + } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.h index e7c49330561..17df31502b3 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.h @@ -9,12 +9,15 @@ #include #include +#include #include #include #include QT_BEGIN_NAMESPACE class QGridLayout; +class QLabel; +class QListWidgetItem; class QPushButton; QT_END_NAMESPACE @@ -23,7 +26,6 @@ class OutputFormatter; } namespace QmlDesigner { -class ItemLibraryAssetImporter; class Import3dCanvas; class Import3dConnectionManager; class NodeInstanceView; @@ -53,6 +55,8 @@ public: const QVariantMap &supportedExts, const QVariantMap &supportedOpts); + void keyPressEvent(QKeyEvent *event) override; + protected: void resizeEvent(QResizeEvent *event) override; @@ -62,32 +66,54 @@ private slots: void addInfo(const QString &info, const QString &srcPath = {}); private: + struct ImportData + { + QListWidgetItem *listItem = {}; + QLabel *iconLabel = {}; + QLabel *infoLabel = {}; + QPushButton *removeButton = {}; + ItemLibraryAssetImporter::PreviewData previewData; + }; + + struct OptionsData + { + int optionsRows = 0; + int optionsHeight = 0; + QList contentWidgets; + }; + void setCloseButtonState(bool importing); - void updateImportButtonState(); + void updatePreviewOptions(); void onImport(); void setImportProgress(int value, const QString &text); - void onImportReadyForPreview(const QString &path, const QString &compName); + void onImportReadyForPreview(const QString &path, + const QList &previewData); void onRequestImageUpdate(); void onRequestRotation(const QPointF &delta); void onImportNearlyFinished(); void onImportFinished(); + void onCurrentItemChanged(QListWidgetItem *current, QListWidgetItem *previous); void onClose(); void doClose(); void toggleAdvanced(); + void onRemoveAsset(const QString &assetName); void createTab(const QString &tabLabel, int optionsIndex, const QJsonObject &groups); QGridLayout *createOptionsGrid(QWidget *contentWidget, bool advanced, int optionsIndex, const QJsonObject &groups); void updateUi(); + QString assetNameForListItem(QListWidgetItem *item); bool isSimpleGroup(const QString &id); bool isSimpleOption(const QString &id); bool isHiddenOption(const QString &id); + bool optionsChanged(); void startPreview(); void cleanupPreviewPuppet(); Import3dCanvas *canvas(); + void resetOptionControls(); Ui::ItemLibraryAssetImportDialog *ui = nullptr; Utils::OutputFormatter *m_outputFormatter = nullptr; @@ -96,21 +122,14 @@ private: QPointer m_rewriterView; QPointer m_view; ModelPointer m_model; - Utils::FilePath m_previewFile; - QString m_previewCompName; - struct OptionsData - { - int optionsRows = 0; - int optionsHeight = 0; - QList contentWidgets; // Tab content widgets - }; + QMap m_importData; + Utils::FilePath m_previewFile; QStringList m_quick3DFiles; QString m_quick3DImportPath; ItemLibraryAssetImporter m_importer; QVector m_importOptions; - QVector m_previewOptions; QHash m_extToImportOptionsMap; QSet m_preselectedFilesForOverwrite; bool m_closeOnFinish = true; @@ -120,5 +139,9 @@ private: bool m_advancedMode = false; int m_dialogHeight = 350; bool m_explicitClose = false; + bool m_updatingControlStates = true; + bool m_firstImport = true; + QIcon m_selectedRemoveIcon; + QIcon m_unselectedRemoveIcon; }; } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.ui b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.ui index e0b9d925fca..62f31283119 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.ui +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.ui @@ -6,7 +6,7 @@ 0 0 - 1100 + 1280 350 @@ -14,6 +14,42 @@ Asset Import + + + + + + Imported objects + + + + + + + + 1 + 0 + + + + + 260 + 0 + + + + + 150 + 16777215 + + + + false + + + + + diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp index 010d00a970a..5c14c46d183 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp @@ -15,7 +15,7 @@ #include "rewritingexception.h" #include "viewmanager.h" -#include +#include #include @@ -91,50 +91,60 @@ void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles, } } -void ItemLibraryAssetImporter::reImportQuick3D(const QString &assetName, - const QVector &options) +void ItemLibraryAssetImporter::reImportQuick3D(const QHash &importOptions) { - if (!assetName.isEmpty() && !m_parseData.contains(assetName)) { - addError(tr("Attempted to reimport non-existing asset: %1").arg(assetName)); - return; - } - - ParseData &pd = m_parseData[assetName]; - // Change outDir just in case reimport generates different files - QDir oldDir = pd.outDir; - QString assetFolder = generateAssetFolderName(pd.assetName); - pd.outDir.cdUp(); - pd.outDir.mkpath(assetFolder); - - if (!pd.outDir.cd(assetFolder)) { - addError(tr("Could not access temporary asset directory: \"%1\".") - .arg(pd.outDir.filePath(assetFolder))); - return; - } - - if (oldDir.absolutePath().contains(tempDirNameBase())) - oldDir.removeRecursively(); - m_isImporting = false; m_cancelled = false; + int importId = 1; + m_puppetProcess.reset(); - m_requiredImports.clear(); m_currentImportId = 0; m_puppetQueue.clear(); - - for (ParseData &pd : m_parseData) - pd.importId = -1; - - pd.options = options[pd.optionsIndex]; - pd.importId = 1; - - m_importFiles.remove(assetName); - m_importIdToAssetNameMap.clear(); - m_importIdToAssetNameMap[pd.importId] = assetName; - m_puppetQueue.append(pd.importId); + if (importOptions.isEmpty()) { + addError(tr("Attempted to reimport no assets.")); + cancelImport(); + return; + } + + const QStringList keys = importOptions.keys(); + for (const QString &key : keys) { + if (!key.isEmpty() && !m_parseData.contains(key)) { + addError(tr("Attempted to reimport non-existing asset: %1").arg(key)); + cancelImport(); + return; + } + + ParseData &pd = m_parseData[key]; + // Change outDir just in case reimport generates different files + QDir oldDir = pd.outDir; + QString assetFolder = generateAssetFolderName(pd.assetName); + pd.outDir.cdUp(); + pd.outDir.mkpath(assetFolder); + + if (!pd.outDir.cd(assetFolder)) { + addError(tr("Could not access temporary asset directory: \"%1\".") + .arg(pd.outDir.filePath(assetFolder))); + cancelImport(); + return; + } + + if (oldDir.absolutePath().contains(tempDirNameBase())) + oldDir.removeRecursively(); + + for (ParseData &pd : m_parseData) + pd.importId = -1; + + pd.options = importOptions[key]; + pd.importId = importId++; + + m_importFiles.remove(key); + m_importIdToAssetNameMap[pd.importId] = key; + + m_puppetQueue.append(pd.importId); + } startNextImportProcess(); } @@ -228,7 +238,6 @@ void ItemLibraryAssetImporter::reset() delete m_tempDir; m_tempDir = new QTemporaryDir(QDir::tempPath() + tempDirNameBase()); m_importFiles.clear(); - m_overwrittenImports.clear(); m_puppetProcess.reset(); m_parseData.clear(); m_requiredImports.clear(); @@ -281,10 +290,12 @@ bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseDa currentChar = QLatin1Char('_'); } const QChar firstChar = pd.assetName[0]; - if (firstChar.isDigit()) - pd.assetName[0] = QLatin1Char('_'); - if (firstChar.isLower()) + if (firstChar.isDigit()) { + // Match quick3d importer logic on starting digit + pd.assetName.prepend("Node"); + } else if (firstChar.isLower()) { pd.assetName[0] = firstChar.toUpper(); + } } pd.targetDirPath = pd.targetDir.filePath(pd.assetName); @@ -327,14 +338,14 @@ bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseDa overwriteFiles = dlg.selectedFiles(); if (!overwriteFiles.isEmpty()) { overwriteFiles.append(::Utils::toList(alwaysOverwrite)); - m_overwrittenImports.insert(pd.targetDirPath, overwriteFiles); + pd.overwrittenImports.insert(pd.targetDirPath, overwriteFiles); } else { addWarning(tr("No files selected for overwrite, skipping import: \"%1\".").arg(pd.assetName)); return false; } } else { - m_overwrittenImports.insert(pd.targetDirPath, {}); + pd.overwrittenImports.insert(pd.targetDirPath, {}); } } @@ -386,13 +397,14 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(ParseData &pd) qmlInfo.append("."); qmlInfo.append(pd.assetName); qmlInfo.append('\n'); - m_requiredImports.append( - QStringLiteral("%1.%2").arg(QmlDesignerPlugin::instance()->documentManager() - .generatedComponentUtils().import3dTypePrefix(), - pd.assetName)); + const QString reqImp = generateRequiredImportForAsset(pd.assetName); + if (!m_requiredImports.contains(reqImp)) + m_requiredImports.append(reqImp); while (qmlIt.hasNext()) { qmlIt.next(); QFileInfo fi = QFileInfo(qmlIt.filePath()); + if (pd.importedQmlName.isEmpty()) + pd.importedQmlName = fi.baseName(); qmlInfo.append(fi.baseName()); qmlInfo.append(' '); qmlInfo.append(version); @@ -469,9 +481,13 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(ParseData &pd) // Gather all generated files QDirIterator dirIt(outDir.path(), QDir::Files, QDirIterator::Subdirectories); + pd.assetSize = 0; while (dirIt.hasNext()) { dirIt.next(); insertAsset(dirIt.filePath()); + QFileInfo fi = dirIt.fileInfo(); + if (fi.isFile()) + pd.assetSize += fi.size(); } // Copy the original asset into a subdirectory @@ -481,14 +497,17 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(ParseData &pd) void ItemLibraryAssetImporter::copyImportedFiles() { - if (!m_overwrittenImports.isEmpty()) { + QHash allOverwrites; + for (const ParseData &pd: std::as_const(m_parseData)) + allOverwrites.insert(pd.overwrittenImports); + if (!allOverwrites.isEmpty()) { const QString progressTitle = tr("Removing old overwritten assets."); addInfo(progressTitle); notifyProgress(0, progressTitle); int counter = 0; - auto it = m_overwrittenImports.constBegin(); - while (it != m_overwrittenImports.constEnd()) { + auto it = allOverwrites.constBegin(); + while (it != allOverwrites.constEnd()) { Utils::FilePath dir = Utils::FilePath::fromUserInput(it.key()); if (dir.exists()) { const auto &overwrittenFiles = it.value(); @@ -501,7 +520,7 @@ void ItemLibraryAssetImporter::copyImportedFiles() QFile::remove(fileName); } } - notifyProgress((100 * ++counter) / m_overwrittenImports.size(), progressTitle); + notifyProgress((100 * ++counter) / allOverwrites.size(), progressTitle); ++it; } } @@ -557,6 +576,13 @@ QString ItemLibraryAssetImporter::generateAssetFolderName(const QString &assetNa return assetName + "_QDS_" + QString::number(counter++); } +QString ItemLibraryAssetImporter::generateRequiredImportForAsset(const QString &assetName) const +{ + return QStringLiteral("%1.%2").arg( + QmlDesignerPlugin::instance()->documentManager() + .generatedComponentUtils().import3dTypePrefix(), assetName); +} + ItemLibraryAssetImporter::OverwriteResult ItemLibraryAssetImporter::confirmAssetOverwrite(const QString &assetName) { const QString title = tr("Overwrite Existing Asset?"); @@ -633,14 +659,32 @@ void ItemLibraryAssetImporter::postImport() } if (!isCancelled()) { - // TODO: Currently we only support import preview for single imports - if (m_parseData.size() != 1) { - finalizeQuick3DImport(); - } else { - const ParseData &pd = m_parseData[m_parseData.keys().first()]; - const QString importedComponentName = pd.assetName; - emit importReadyForPreview(pd.outDir.absolutePath(), importedComponentName); + QList dataList; + for (const QString &assetName : std::as_const(m_importIdToAssetNameMap)) { + const ParseData &pd = m_parseData[assetName]; + PreviewData data; + data.name = pd.assetName; + data.folderName = pd.outDir.dirName(); + data.qmlName = pd.importedQmlName; + data.renderedOptions = pd.options; + data.currentOptions = pd.options; + data.optionsIndex = pd.optionsIndex; + data.type = pd.sourceInfo.suffix().toLower(); + data.size = pd.assetSize; + + bool inserted = false; + for (int i = 0; i < dataList.size(); ++i) { + if (dataList[i].name.compare(data.name, Qt::CaseInsensitive) > 0) { + dataList.insert(i, data); + inserted = true; + break; + } + } + if (!inserted) + dataList.append(data); } + + emit importReadyForPreview(m_tempDir->path(), dataList); } } @@ -701,8 +745,12 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport() addError(tr("Failed to update imports: %1").arg(e.description())); } } else if (counter >= 50) { - if (!m_overwrittenImports.isEmpty()) - model->rewriterView()->emitCustomNotification("asset_import_update"); + for (const ParseData &pd : std::as_const(m_parseData)) { + if (!pd.overwrittenImports.isEmpty()) { + model->rewriterView()->emitCustomNotification("asset_import_update"); + break; + } + } timer->stop(); notifyFinished(); } @@ -717,6 +765,13 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport() } } +void ItemLibraryAssetImporter::removeAssetFromImport(const QString &assetName) +{ + m_parseData.remove(assetName); + m_importFiles.remove(assetName); + m_requiredImports.removeOne(generateRequiredImportForAsset(assetName)); +} + QString ItemLibraryAssetImporter::sourceSceneTargetFilePath(const ParseData &pd) { return pd.targetDirPath + QStringLiteral("/source scene/") + pd.sourceInfo.fileName(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h index abe96909514..dcdc1150a6b 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h @@ -33,7 +33,7 @@ public: const QHash &extToImportOptionsMap, const QSet &preselectedFilesForOverwrite); - void reImportQuick3D(const QString &assetName, const QVector &options); + void reImportQuick3D(const QHash &importOptions); bool isImporting() const; void cancelImport(); @@ -47,13 +47,26 @@ public: QString tempDirNameBase() const { return "/qds3dimport"; } void finalizeQuick3DImport(); + void removeAssetFromImport(const QString &assetName); + + struct PreviewData + { + int optionsIndex = 0; + QJsonObject renderedOptions; + QJsonObject currentOptions; + QString name; + QString folderName; + QString qmlName; + QString type; + qint64 size; + }; signals: void errorReported(const QString &, const QString &); void warningReported(const QString &, const QString &); void infoReported(const QString &, const QString &); void progressChanged(int value, const QString &text); - void importReadyForPreview(const QString &path, const QString &compName); + void importReadyForPreview(const QString &path, const QList &previewData); void importNearlyFinished(); void importFinished(); @@ -69,8 +82,11 @@ private: QFileInfo sourceInfo; QString assetName; QString originalAssetName; + QString importedQmlName; + qint64 assetSize; int importId = -1; int optionsIndex = -1; + QHash overwrittenImports; }; void notifyFinished(); @@ -87,6 +103,7 @@ private: void notifyProgress(int value); void keepUiAlive() const; QString generateAssetFolderName(const QString &assetName) const; + QString generateRequiredImportForAsset(const QString &assetName) const; enum class OverwriteResult { Skip, @@ -100,7 +117,6 @@ private: QString sourceSceneTargetFilePath(const ParseData &pd); QHash> m_importFiles; // Key: asset name - QHash m_overwrittenImports; bool m_isImporting = false; bool m_cancelled = false; QString m_importPath; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index 8ef9512e26a..cf2ca4b74e7 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -14,10 +14,11 @@ #include #include #include -#include "qmldesignerconstants.h" -#include "qmldesignerplugin.h" +#include +#include #include #include +#include #include #include diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp index e4f4ffcd9c6..9ff1f8e8e70 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp @@ -49,7 +49,6 @@ WidgetInfo ItemLibraryView::widgetInfo() return createWidgetInfo(m_widget.data(), "Components", WidgetInfo::LeftPane, - 0, tr("Components"), tr("Components view")); } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index dd43d8bf2b1..06f6c2de102 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -21,7 +21,7 @@ #endif #include #include -#include +#include #include #include #include diff --git a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp index f97b6f74acc..0eb654bf0d0 100644 --- a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp +++ b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp @@ -100,7 +100,7 @@ QList getPropertyNames(const ModelNode &listElementNode) names.reserve(properties.size()); for (const auto &property : properties) - names.push_back(property.name()); + names.push_back(property.name().toByteArray()); std::sort(names.begin(), names.end()); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp index b74f3107412..f01424e96e8 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp @@ -401,8 +401,8 @@ void MaterialBrowserModel::copyMaterialProperties(int idx, const QString §io // Dynamic properties must always be set in base state const QList dynProps = m_copiedMaterial.dynamicProperties(); for (const auto &prop : dynProps) { - dynamicProps.insert(prop.name(), prop.dynamicTypeName()); - validProps.insert(prop.name()); + dynamicProps.insert(prop.name().toByteArray(), prop.dynamicTypeName()); + validProps.insert(prop.name().toByteArray()); } } @@ -417,7 +417,7 @@ void MaterialBrowserModel::copyMaterialProperties(int idx, const QString §io if (changes.isValid()) { const QList changedProps = changes.targetProperties(); for (const auto &changedProp : changedProps) - validProps.insert(changedProp.name()); + validProps.insert(changedProp.name().toByteArray()); } } diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp index 918956a04c0..e34cc9825e3 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp @@ -34,30 +34,30 @@ QVariant MaterialBrowserTexturesModel::data(const QModelIndex &index, int role) QTC_ASSERT(index.isValid() && index.row() < m_textureList.size(), return {}); QTC_ASSERT(roleNames().contains(role), return {}); - if (role == RoleTexSource) { + switch (role) { + case RoleTexVisible: + return isVisible(index.row()); + case RoleTexHasDynamicProps: + return !m_textureList.at(index.row()).dynamicProperties().isEmpty(); + case RoleTexInternalId: + return m_textureList.at(index.row()).internalId(); + case RoleTexName: + return m_textureList.at(index.row()).variantProperty("objectName").value(); + case RoleTexSource: { QString source = QmlObjectNode(m_textureList.at(index.row())).modelValue("source").toString(); if (source.isEmpty()) return {}; if (Utils::FilePath::fromString(source).isAbsolutePath()) return QVariant(source); - return QVariant(QmlDesignerPlugin::instance()->documentManager().currentDesignDocument() - ->fileName().absolutePath().pathAppended(source).cleanPath().toString()); - } - - if (role == RoleTexVisible) - return isVisible(index.row()); - - if (role == RoleTexHasDynamicProps) - return !m_textureList.at(index.row()).dynamicProperties().isEmpty(); - - if (role == RoleTexInternalId) - return m_textureList.at(index.row()).internalId(); - - if (role == RoleTexId) { - return m_textureList.at(index.row()).id(); - } - - if (role == RoleTexToolTip) { + return QVariant(QmlDesignerPlugin::instance() + ->documentManager() + .currentDesignDocument() + ->fileName() + .absolutePath() + .pathAppended(source) + .toFSPathString()); + }; + case RoleTexToolTip: { QString source = data(index, RoleTexSource).toString(); // absolute path if (source.isEmpty()) return tr("Texture has no source image."); @@ -68,11 +68,13 @@ QVariant MaterialBrowserTexturesModel::data(const QModelIndex &index, int role) if (info.isEmpty()) return tr("Texture has no data."); + QString textName = data(index, RoleTexName).toString(); QString sourceRelative = QmlObjectNode(texNode).modelValue("source").toString(); - return QLatin1String("%1\n%2\n%3").arg(texNode.id(), sourceRelative, info); + return QLatin1String("%1 (%2)\n%3\n%4").arg(textName, texNode.id(), sourceRelative, info); + }; + default: + return {}; } - - return {}; } bool MaterialBrowserTexturesModel::isVisible(int idx) const @@ -80,8 +82,17 @@ bool MaterialBrowserTexturesModel::isVisible(int idx) const if (!isValidIndex(idx)) return false; - return m_searchText.isEmpty() || m_textureList.at(idx).variantProperty("source") - .value().toString().contains(m_searchText, Qt::CaseInsensitive); + if (m_searchText.isEmpty()) + return true; + + const ModelNode &texture = m_textureList.at(idx); + + auto propertyHasMatch = [&](const PropertyName &property) -> bool { + return texture.variantProperty(property).value().toString().contains(m_searchText, + Qt::CaseInsensitive); + }; + + return propertyHasMatch("objectName") || propertyHasMatch("source"); } bool MaterialBrowserTexturesModel::isValidIndex(int idx) const @@ -91,13 +102,13 @@ bool MaterialBrowserTexturesModel::isValidIndex(int idx) const QHash MaterialBrowserTexturesModel::roleNames() const { - static const QHash roles { + static const QHash roles{ {RoleTexHasDynamicProps, "hasDynamicProperties"}, - {RoleTexInternalId, "textureInternalId"}, - {RoleTexId, "textureId"}, - {RoleTexSource, "textureSource"}, - {RoleTexToolTip, "textureToolTip"}, - {RoleTexVisible, "textureVisible"} + {RoleTexInternalId, "textureInternalId"}, + {RoleTexName, "textureName"}, + {RoleTexSource, "textureSource"}, + {RoleTexToolTip, "textureToolTip"}, + {RoleTexVisible, "textureVisible"}, }; return roles; } @@ -206,6 +217,20 @@ void MaterialBrowserTexturesModel::updateTextureSource(const ModelNode &texture) emit dataChanged(index(idx, 0), index(idx, 0), {RoleTexSource, RoleTexToolTip}); } +void MaterialBrowserTexturesModel::updateTextureId(const ModelNode &texture) +{ + int idx = textureIndex(texture); + if (idx != -1) + emit dataChanged(index(idx, 0), index(idx, 0), {RoleTexToolTip}); +} + +void MaterialBrowserTexturesModel::updateTextureName(const ModelNode &texture) +{ + int idx = textureIndex(texture); + if (idx != -1) + emit dataChanged(index(idx, 0), index(idx, 0), {RoleTexName, RoleTexToolTip}); +} + void MaterialBrowserTexturesModel::updateAllTexturesSources() { emit dataChanged(index(0, 0), index(rowCount() - 1, 0), {RoleTexSource, RoleTexToolTip}); @@ -304,7 +329,7 @@ void MaterialBrowserTexturesModel::deleteTexture(int idx) } } -void MaterialBrowserTexturesModel::setTextureId(int idx, const QString &newId) +void MaterialBrowserTexturesModel::setTextureName(int idx, const QString &newName) { if (!isValidIndex(idx)) return; @@ -313,9 +338,17 @@ void MaterialBrowserTexturesModel::setTextureId(int idx, const QString &newId) if (!node.isValid()) return; - if (node.id() != newId) { - node.setIdWithRefactoring(newId); - emit dataChanged(index(idx, 0), index(idx, 0), {RoleTexId}); + VariantProperty objectNameProperty = node.variantProperty("objectName"); + QString oldName = objectNameProperty.value().toString(); + + if (oldName != newName) { + const Model *model = m_view->model(); + QTC_ASSERT(model, return); + + m_view->executeInTransaction(__FUNCTION__, [&] { + node.setIdWithRefactoring(model->generateNewId(newName, "texture")); + objectNameProperty.setValue(newName); + }); } } diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.h index 8836d3b5db8..5625cc7d578 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.h @@ -38,6 +38,8 @@ public: void deleteSelectedTexture(); void updateSelectedTexture(); void updateTextureSource(const ModelNode &texture); + void updateTextureId(const ModelNode &texture); + void updateTextureName(const ModelNode &texture); void updateAllTexturesSources(); int textureIndex(const ModelNode &texture) const; ModelNode textureAt(int idx) const; @@ -57,7 +59,7 @@ public: Q_INVOKABLE void addNewTexture(); Q_INVOKABLE void duplicateTexture(int idx); Q_INVOKABLE void deleteTexture(int idx); - Q_INVOKABLE void setTextureId(int idx, const QString &newId); + Q_INVOKABLE void setTextureName(int idx, const QString &newName); Q_INVOKABLE void applyToSelectedMaterial(qint64 internalId); Q_INVOKABLE void applyToSelectedModel(qint64 internalId); Q_INVOKABLE void openTextureEditor(); @@ -96,7 +98,7 @@ private: enum { RoleTexHasDynamicProps = Qt::UserRole + 1, RoleTexInternalId, - RoleTexId, + RoleTexName, RoleTexSource, RoleTexToolTip, RoleTexVisible diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index f6aec165b4f..03118fc3b52 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -96,27 +96,34 @@ WidgetInfo MaterialBrowserView::widgetInfo() executeInTransaction(__FUNCTION__, [&] { if (all) { // all material properties copied // remove current properties - PropertyNameList propNames; if (mat.isInBaseState()) { const QList baseProps = material.properties(); + PropertyNameViews propNames; for (const auto &baseProp : baseProps) { if (!baseProp.isDynamic()) propNames.append(baseProp.name()); } + + for (PropertyNameView propName : propNames) { + if (propName != "objectName" && propName != "data") + mat.removeProperty(propName); + } } else { QmlPropertyChanges changes = mat.propertyChangeForCurrentState(); if (changes.isValid()) { + PropertyNameViews propNames; const QList changedProps = changes.targetProperties(); for (const auto &changedProp : changedProps) { if (!changedProp.isDynamic()) propNames.append(changedProp.name()); } + + for (PropertyNameView propName : propNames) { + if (propName != "objectName" && propName != "data") + mat.removeProperty(propName); + } } } - for (const PropertyName &propName : std::as_const(propNames)) { - if (propName != "objectName" && propName != "data") - mat.removeProperty(propName); - } } // apply pasted properties @@ -205,7 +212,6 @@ WidgetInfo MaterialBrowserView::widgetInfo() return createWidgetInfo(m_widget.data(), "MaterialBrowser", WidgetInfo::LeftPane, - 0, tr("Material Browser"), tr("Material Browser view")); } @@ -276,6 +282,33 @@ void MaterialBrowserView::updateMaterialsPreview() m_previewTimer.start(0); } +template // T can be either BindingProperty or VariantProperty +void MaterialBrowserView::updatePropertyList(const QList &propertyList) +{ + for (const AbstractProperty &property : propertyList) { + ModelNode node(property.parentModelNode()); + if (isMaterial(node)) { + if (property.name() == "objectName") + m_widget->materialBrowserModel()->updateMaterialName(node); + else + m_previewRequests << node; + } else if (isTexture(node)) { + QmlObjectNode selectedTex = m_widget->materialBrowserTexturesModel()->selectedTexture(); + if (property.name() == "source") + m_widget->materialBrowserTexturesModel()->updateTextureSource(node); + else if (property.name() == "objectName") + m_widget->materialBrowserTexturesModel()->updateTextureName(node); + } else { + QmlObjectNode selectedTex = m_widget->materialBrowserTexturesModel()->selectedTexture(); + if (property.name() == "source" && selectedTex.propertyChangeForCurrentState() == node) + m_widget->materialBrowserTexturesModel()->updateTextureSource(selectedTex); + } + } + + if (!m_previewRequests.isEmpty()) + m_previewTimer.start(0); +} + bool MaterialBrowserView::isMaterial(const ModelNode &node) const { return node.metaInfo().isQtQuick3DMaterial(); @@ -329,9 +362,16 @@ void MaterialBrowserView::selectedNodesChanged(const QList &selectedN m_widget->materialBrowserModel()->selectMaterial(idx); } -void MaterialBrowserView::modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) +void MaterialBrowserView::modelNodePreviewPixmapChanged(const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId) { - if (isMaterial(node)) + if (!isMaterial(node)) + return; + + // There might be multiple requests for different preview pixmap sizes. + // Here only the one with the default size is picked. + if (requestId.isEmpty()) m_widget->updateMaterialPreview(node, pixmap); } @@ -339,32 +379,24 @@ void MaterialBrowserView::nodeIdChanged(const ModelNode &node, [[maybe_unused]] [[maybe_unused]] const QString &oldId) { if (isTexture(node)) - m_widget->materialBrowserTexturesModel()->updateTextureSource(node); + m_widget->materialBrowserTexturesModel()->updateTextureId(node); } void MaterialBrowserView::variantPropertiesChanged(const QList &propertyList, [[maybe_unused]] PropertyChangeFlags propertyChange) { - for (const VariantProperty &property : propertyList) { - ModelNode node(property.parentModelNode()); - if (isMaterial(node) && property.name() == "objectName") { - m_widget->materialBrowserModel()->updateMaterialName(node); - } else if (property.name() == "source") { - QmlObjectNode selectedTex = m_widget->materialBrowserTexturesModel()->selectedTexture(); - if (isTexture(node)) - m_widget->materialBrowserTexturesModel()->updateTextureSource(node); - else if (selectedTex.propertyChangeForCurrentState() == node) - m_widget->materialBrowserTexturesModel()->updateTextureSource(selectedTex); - } - } + updatePropertyList(propertyList); +} + +void MaterialBrowserView::bindingPropertiesChanged(const QList &propertyList, + [[maybe_unused]] PropertyChangeFlags propertyChange) +{ + updatePropertyList(propertyList); } void MaterialBrowserView::propertiesRemoved(const QList &propertyList) { - for (const AbstractProperty &prop : propertyList) { - if (isTexture(prop.parentModelNode()) && prop.name() == "source") - m_widget->materialBrowserTexturesModel()->updateTextureSource(prop.parentModelNode()); - } + updatePropertyList(propertyList); } void MaterialBrowserView::nodeReparented(const ModelNode &node, diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index 36ac908e8cf..b6470ee1617 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -34,9 +34,13 @@ public: void modelAboutToBeDetached(Model *model) override; void selectedNodesChanged(const QList &selectedNodeList, const QList &lastSelectedNodeList) override; - void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) override; + void modelNodePreviewPixmapChanged(const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId) override; void nodeIdChanged(const ModelNode &node, const QString &newId, const QString &oldId) override; void variantPropertiesChanged(const QList &propertyList, PropertyChangeFlags propertyChange) override; + void bindingPropertiesChanged(const QList &propertyList, + PropertyChangeFlags propertyChange) override; void propertiesRemoved(const QList &propertyList) override; void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, @@ -70,6 +74,10 @@ private: void active3DSceneChanged(qint32 sceneId); void refreshModel(bool updateImages); void updateMaterialsPreview(); + + template::value>::type> + void updatePropertyList(const QList &propertyList); + bool isMaterial(const ModelNode &node) const; bool isTexture(const ModelNode &node) const; void loadPropertyGroups(); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index f6acfb5ee4c..11e1065be7c 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -375,7 +375,19 @@ void MaterialBrowserWidget::addMaterialToContentLibrary() { ModelNode mat = m_materialBrowserModel->selectedMaterial(); m_materialBrowserView->emitCustomNotification("add_material_to_content_lib", {mat}, - {m_previewImageProvider->getPixmap(mat)}); + {m_previewImageProvider->getPixmap(mat)}); // to ContentLibrary +} + +void MaterialBrowserWidget::importMaterial() +{ + ModelNode mat = m_materialBrowserModel->selectedMaterial(); + m_materialBrowserView->emitCustomNotification("import_bundle_to_project"); // to ContentLibrary +} +void MaterialBrowserWidget::exportMaterial() +{ + ModelNode mat = m_materialBrowserModel->selectedMaterial(); + m_materialBrowserView->emitCustomNotification("export_material_as_bundle", {mat}, + {m_previewImageProvider->getPixmap(mat)}); // to ContentLibrary } QString MaterialBrowserWidget::qmlSourcesPath() diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h index 6506283f858..36cb40ac0d2 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h @@ -63,6 +63,8 @@ public: Q_INVOKABLE void acceptTextureDropOnMaterial(int matIndex, const QString &texId); Q_INVOKABLE void focusMaterialSection(bool focusMatSec); Q_INVOKABLE void addMaterialToContentLibrary(); + Q_INVOKABLE void importMaterial(); + Q_INVOKABLE void exportMaterial(); StudioQuickWidget *quickWidget() const; diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialutils.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialutils.cpp index 1ee2e409f38..1a1071de347 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialutils.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialutils.cpp @@ -55,7 +55,7 @@ void MaterialUtils::assignMaterialTo3dModel(AbstractView *view, const ModelNode metaInfo.majorVersion(), metaInfo.minorVersion()); #endif - newMaterialNode.validId(); + newMaterialNode.ensureIdExists(); } } diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp index f583498db78..fa3469254f5 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp @@ -110,9 +110,9 @@ void MaterialEditorContextObject::changeTypeName(const QString &typeName) continue; // Add dynamic property - propertiesAndSignals.append(property.name()); + propertiesAndSignals.append(property.name().toByteArray()); // Add its change signal - PropertyName name = property.name(); + PropertyName name = property.name().toByteArray(); QChar firstChar = QChar(property.name().at(0)).toUpper().toLatin1(); name[0] = firstChar.toLatin1(); name.prepend("on"); @@ -124,7 +124,7 @@ void MaterialEditorContextObject::changeTypeName(const QString &typeName) QList incompatibleProperties; for (const auto &property : matProps) { if (!propertiesAndSignals.contains(property.name())) - incompatibleProperties.append(property.name()); + incompatibleProperties.append(property.name().toByteArray()); } // When switching between material types, copy base (diffuse) color and map properties of @@ -135,7 +135,7 @@ void MaterialEditorContextObject::changeTypeName(const QString &typeName) int targetIndex = -1; NodeMetaInfo oldMetaInfo = m_selectedMaterial.metaInfo(); struct CopyData { - CopyData() {}; + CopyData() {} CopyData(PropertyName n) : name(n) {} PropertyName name; QVariant value; diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorimageprovider.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorimageprovider.cpp new file mode 100644 index 00000000000..24d7d583ab9 --- /dev/null +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorimageprovider.cpp @@ -0,0 +1,82 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#include "materialeditorimageprovider.h" + +#include "materialeditorview.h" + +#include +#include + +namespace QmlDesigner { + +MaterialEditorImageProvider::MaterialEditorImageProvider(MaterialEditorView *materialEditorView) + : QQuickImageProvider(Pixmap) + , m_delayTimer(new QTimer(this)) +{ + m_delayTimer->setInterval(500); + m_delayTimer->setSingleShot(true); + m_delayTimer->callOnTimeout([this] { + if (m_previewPixmap.size() != m_requestedSize) + emit this->requestPreview(m_requestedSize); + }); + + connect(this, + &MaterialEditorImageProvider::requestPreview, + materialEditorView, + &MaterialEditorView::handlePreviewSizeChanged); +} + +void MaterialEditorImageProvider::setPixmap(const QPixmap &pixmap) +{ + m_previewPixmap = pixmap; +} + +QPixmap MaterialEditorImageProvider::requestPixmap(const QString &id, + QSize *size, + const QSize &requestedSize) +{ + static QPixmap defaultPreview = QPixmap::fromImage( + QImage(":/materialeditor/images/defaultmaterialpreview.png")); + + QPixmap pixmap{150, 150}; + + if (id == "preview") { + if (!m_previewPixmap.isNull()) { + pixmap = m_previewPixmap; + setRequestedSize(requestedSize); + } else { + if (requestedSize.isEmpty()) + pixmap = defaultPreview; + else + pixmap = defaultPreview.scaled(requestedSize, Qt::KeepAspectRatio); + } + } else { + qWarning() << __FUNCTION__ << "Unsupported image id:" << id; + pixmap.fill(Qt::red); + } + + if (size) + *size = pixmap.size(); + + return pixmap; +} + +/*! + * \internal + * \brief Sets the requested size. If the requested size is not the same as the + * size of the m_previewPixmap, it will ask \l {MaterialEditorView} to provide + * an image with the requested size + * The requests are delayed until the requested size is stable. + */ +void MaterialEditorImageProvider::setRequestedSize(const QSize &requestedSize) +{ + if (requestedSize.isEmpty()) + return; + + m_requestedSize = requestedSize; + + if (m_previewPixmap.size() != requestedSize) + m_delayTimer->start(); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorimageprovider.h b/src/plugins/qmldesigner/components/materialeditor/materialeditorimageprovider.h new file mode 100644 index 00000000000..6730f418a2c --- /dev/null +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorimageprovider.h @@ -0,0 +1,37 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +QT_BEGIN_NAMESPACE +class QTimer; +QT_END_NAMESPACE + +namespace QmlDesigner { + +class MaterialEditorView; + +class MaterialEditorImageProvider : public QQuickImageProvider +{ + Q_OBJECT + +public: + explicit MaterialEditorImageProvider(MaterialEditorView *materialEditorView); + + void setPixmap(const QPixmap &pixmap); + QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override; + +signals: + void requestPreview(QSize); + +private: + void setRequestedSize(const QSize &requestedSize); + + QPixmap m_previewPixmap; + QSize m_requestedSize; + QTimer *m_delayTimer = nullptr; // Delays the preview requests +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.cpp index 3922db97405..5e6a38d1583 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.cpp @@ -3,9 +3,10 @@ #include "materialeditorqmlbackend.h" -#include "propertyeditorvalue.h" -#include "materialeditortransaction.h" #include "materialeditorcontextobject.h" +#include "materialeditorimageprovider.h" +#include "materialeditortransaction.h" +#include "propertyeditorvalue.h" #include #include @@ -22,7 +23,6 @@ #include #include -#include #include #include #include @@ -39,50 +39,11 @@ static QObject *variantToQObject(const QVariant &value) namespace QmlDesigner { -class MaterialEditorImageProvider : public QQuickImageProvider -{ - QPixmap m_previewPixmap; - -public: - MaterialEditorImageProvider() - : QQuickImageProvider(Pixmap) {} - - void setPixmap(const QPixmap &pixmap) - { - m_previewPixmap = pixmap; - } - - QPixmap requestPixmap(const QString &id, - QSize *size, - [[maybe_unused]] const QSize &requestedSize) override - { - static QPixmap defaultPreview = QPixmap::fromImage(QImage(":/materialeditor/images/defaultmaterialpreview.png")); - - QPixmap pixmap{150, 150}; - - if (id == "preview") { - if (!m_previewPixmap.isNull()) - pixmap = m_previewPixmap; - else - pixmap = defaultPreview; - } else { - qWarning() << __FUNCTION__ << "Unsupported image id:" << id; - pixmap.fill(Qt::red); - } - - - if (size) - *size = pixmap.size(); - - return pixmap; - } -}; - MaterialEditorQmlBackend::MaterialEditorQmlBackend(MaterialEditorView *materialEditor) : m_quickWidget(Utils::makeUniqueObjectPtr()) , m_materialEditorTransaction(std::make_unique(materialEditor)) , m_contextObject(std::make_unique(m_quickWidget.get())) - , m_materialEditorImageProvider(new MaterialEditorImageProvider()) + , m_materialEditorImageProvider(new MaterialEditorImageProvider(materialEditor)) { m_quickWidget->setObjectName(Constants::OBJECT_NAME_MATERIAL_EDITOR); m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); @@ -100,17 +61,17 @@ MaterialEditorQmlBackend::~MaterialEditorQmlBackend() { } -PropertyName MaterialEditorQmlBackend::auxNamePostFix(const PropertyName &propertyName) +PropertyName MaterialEditorQmlBackend::auxNamePostFix(PropertyNameView propertyName) { return propertyName + "__AUX"; } void MaterialEditorQmlBackend::createPropertyEditorValue(const QmlObjectNode &qmlObjectNode, - const PropertyName &name, + PropertyNameView name, const QVariant &value, MaterialEditorView *materialEditor) { - PropertyName propertyName(name); + PropertyName propertyName(name.toByteArray()); propertyName.replace('.', '_'); auto valueObject = qobject_cast(variantToQObject(backendValuesPropertyMap().value(QString::fromUtf8(propertyName)))); if (!valueObject) { @@ -140,7 +101,9 @@ void MaterialEditorQmlBackend::createPropertyEditorValue(const QmlObjectNode &qm } } -void MaterialEditorQmlBackend::setValue(const QmlObjectNode &, const PropertyName &name, const QVariant &value) +void MaterialEditorQmlBackend::setValue(const QmlObjectNode &, + PropertyNameView name, + const QVariant &value) { // Vector*D values need to be split into their subcomponents if (value.typeId() == QMetaType::QVector2D) { @@ -178,7 +141,7 @@ void MaterialEditorQmlBackend::setValue(const QmlObjectNode &, const PropertyNam propertyValue->setValue(QVariant(vecValue[i])); } } else { - PropertyName propertyName = name; + PropertyName propertyName = name.toByteArray(); propertyName.replace('.', '_'); auto propertyValue = qobject_cast(variantToQObject(m_backendValuesPropertyMap.value(QString::fromUtf8(propertyName)))); if (propertyValue) @@ -217,6 +180,11 @@ void MaterialEditorQmlBackend::updateMaterialPreview(const QPixmap &pixmap) QMetaObject::invokeMethod(m_quickWidget->rootObject(), "refreshPreview"); } +void MaterialEditorQmlBackend::refreshBackendModel() +{ + m_backendModelNode.refresh(); +} + DesignerPropertyMap &MaterialEditorQmlBackend::backendValuesPropertyMap() { return m_backendValuesPropertyMap; diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.h b/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.h index 9fd5fc23992..c8dc64b045f 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.h +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.h @@ -36,7 +36,7 @@ public: void setup(const QmlObjectNode &selectedMaterialNode, const QString &stateName, const QUrl &qmlSpecificsFile, MaterialEditorView *materialEditor); - void setValue(const QmlObjectNode &fxObjectNode, const PropertyName &name, const QVariant &value); + void setValue(const QmlObjectNode &fxObjectNode, PropertyNameView name, const QVariant &value); QQmlContext *context() const; MaterialEditorContextObject *contextObject() const; @@ -44,6 +44,7 @@ public: void setSource(const QUrl &url); QmlAnchorBindingProxy &backendAnchorBinding(); void updateMaterialPreview(const QPixmap &pixmap); + void refreshBackendModel(); DesignerPropertyMap &backendValuesPropertyMap(); MaterialEditorTransaction *materialEditorTransaction() const; @@ -58,9 +59,10 @@ public: private: void createPropertyEditorValue(const QmlObjectNode &qmlObjectNode, - const PropertyName &name, const QVariant &value, + PropertyNameView name, + const QVariant &value, MaterialEditorView *materialEditor); - PropertyName auxNamePostFix(const PropertyName &propertyName); + PropertyName auxNamePostFix(PropertyNameView propertyName); // to avoid a crash while destructing DesignerPropertyMap in the QQmlData // this needs be destructed after m_quickWidget->engine() is destructed diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 21114267cbb..2b6d321b57f 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -24,6 +24,8 @@ #include "qmldesignerplugin.h" #include "qmltimeline.h" #include "variantproperty.h" +#include +#include #include #include @@ -41,6 +43,21 @@ namespace QmlDesigner { +static const char MATERIAL_EDITOR_IMAGE_REQUEST_ID[] = "MaterialEditor"; + +static bool containsTexture(const ModelNode &node) +{ + if (node.metaInfo().isQtQuick3DTexture()) + return true; + + const ModelNodes children = node.allSubModelNodes(); + for (const ModelNode &child : children) { + if (child.metaInfo().isQtQuick3DTexture()) + return true; + } + return false; +}; + MaterialEditorView::MaterialEditorView(ExternalDependenciesInterface &externalDependencies) : AbstractView{externalDependencies} , m_stackedWidget(new QStackedWidget) @@ -284,7 +301,8 @@ bool MaterialEditorView::locked() const void MaterialEditorView::currentTimelineChanged(const ModelNode &) { - m_qmlBackEnd->contextObject()->setHasActiveTimeline(QmlTimeline::hasActiveTimeline(this)); + if (m_qmlBackEnd) + m_qmlBackEnd->contextObject()->setHasActiveTimeline(QmlTimeline::hasActiveTimeline(this)); } DynamicPropertiesModel *MaterialEditorView::dynamicPropertiesModel() const @@ -358,34 +376,14 @@ void MaterialEditorView::applyMaterialToSelectedModels(const ModelNode &material QTC_ASSERT(material.isValid(), return); - auto expToList = [](const QString &exp) { - QString copy = exp; - copy = copy.remove("[").remove("]"); - - QStringList tmp = copy.split(',', Qt::SkipEmptyParts); - for (QString &str : tmp) - str = str.trimmed(); - - return tmp; - }; - - auto listToExp = [](QStringList &stringList) { - if (stringList.size() > 1) - return QString("[" + stringList.join(",") + "]"); - - if (stringList.size() == 1) - return stringList.first(); - - return QString(); - }; - executeInTransaction(__FUNCTION__, [&] { for (const ModelNode &node : std::as_const(m_selectedModels)) { QmlObjectNode qmlObjNode(node); if (add) { - QStringList matList = expToList(qmlObjNode.expression("materials")); + QStringList matList = ModelUtils::expressionToList( + qmlObjNode.expression("materials")); matList.append(material.id()); - QString updatedExp = listToExp(matList); + QString updatedExp = ModelUtils::listToExpression(matList); qmlObjNode.setBindingProperty("materials", updatedExp); } else { qmlObjNode.setBindingProperty("materials", material.id()); @@ -524,6 +522,15 @@ void MaterialEditorView::handlePreviewModelChanged(const QString &modelStr) emitCustomNotification("refresh_material_browser", {}); } +void MaterialEditorView::handlePreviewSizeChanged(const QSizeF &size) +{ + if (m_previewSize == size.toSize()) + return; + + m_previewSize = size.toSize(); + requestPreviewRender(); +} + void MaterialEditorView::setupQmlBackend() { #ifdef QDS_USE_PROJECTSTORAGE @@ -609,7 +616,7 @@ void MaterialEditorView::setupQmlBackend() #endif } -void MaterialEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value) +void MaterialEditorView::commitVariantValueToModel(PropertyNameView propertyName, const QVariant &value) { m_locked = true; executeInTransaction(__FUNCTION__, [&] { @@ -618,11 +625,11 @@ void MaterialEditorView::commitVariantValueToModel(const PropertyName &propertyN m_locked = false; } -void MaterialEditorView::commitAuxValueToModel(const PropertyName &propertyName, const QVariant &value) +void MaterialEditorView::commitAuxValueToModel(PropertyNameView propertyName, const QVariant &value) { m_locked = true; - PropertyName name = propertyName; + PropertyNameView name = propertyName; name.chop(5); try { @@ -637,7 +644,7 @@ void MaterialEditorView::commitAuxValueToModel(const PropertyName &propertyName, m_locked = false; } -void MaterialEditorView::removePropertyFromModel(const PropertyName &propertyName) +void MaterialEditorView::removePropertyFromModel(PropertyNameView propertyName) { m_locked = true; executeInTransaction(__FUNCTION__, [&] { @@ -693,11 +700,11 @@ void MaterialEditorView::updatePossibleTypes() if (!m_qmlBackEnd) return; - static const QStringList basicTypes { + static const QStringList basicTypes{ "CustomMaterial", "DefaultMaterial", "PrincipledMaterial", - "SpecularGlossyMaterial" + "SpecularGlossyMaterial", }; const QString matType = m_selectedMaterial.simplifiedTypeName(); @@ -740,9 +747,11 @@ void MaterialEditorView::modelAboutToBeDetached(Model *model) { AbstractView::modelAboutToBeDetached(model); m_dynamicPropertiesModel->reset(); - if (auto transaction = m_qmlBackEnd->materialEditorTransaction()) - transaction->end(); - m_qmlBackEnd->contextObject()->setHasMaterialLibrary(false); + if (m_qmlBackEnd) { + if (auto transaction = m_qmlBackEnd->materialEditorTransaction()) + transaction->end(); + m_qmlBackEnd->contextObject()->setHasMaterialLibrary(false); + } m_selectedMaterial = {}; } @@ -849,8 +858,15 @@ void MaterialEditorView::propertiesAboutToBeRemoved(const QListnodeInstanceView() && m_selectedMaterial.isValid()) - model()->nodeInstanceView()->previewImageDataForGenericNode(m_selectedMaterial, {}); + if (model() && model()->nodeInstanceView() && m_selectedMaterial.isValid()) { + static int requestId = 0; + m_previewRequestId = QByteArray(MATERIAL_EDITOR_IMAGE_REQUEST_ID) + + QByteArray::number(++requestId); + model()->nodeInstanceView()->previewImageDataForGenericNode(m_selectedMaterial, + {}, + m_previewSize, + m_previewRequestId); + } } bool MaterialEditorView::hasWidget() const @@ -863,7 +879,6 @@ WidgetInfo MaterialEditorView::widgetInfo() return createWidgetInfo(m_stackedWidget, "MaterialEditor", WidgetInfo::RightPane, - 0, tr("Material Editor"), tr("Material Editor view")); } @@ -934,17 +949,22 @@ void MaterialEditorView::rootNodeTypeChanged(const QString &type, int, int) } } -void MaterialEditorView::modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) +void MaterialEditorView::modelNodePreviewPixmapChanged(const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId) { - if (node == m_selectedMaterial) - m_qmlBackEnd->updateMaterialPreview(pixmap); + if (node != m_selectedMaterial || requestId != m_previewRequestId) + return; + + m_qmlBackEnd->updateMaterialPreview(pixmap); } void MaterialEditorView::importsChanged([[maybe_unused]] const Imports &addedImports, [[maybe_unused]] const Imports &removedImports) { m_hasQuick3DImport = model()->hasImport("QtQuick3D"); - m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport); + if (m_qmlBackEnd) + m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport); if (m_hasQuick3DImport) m_ensureMatLibTimer.start(500); @@ -970,10 +990,7 @@ void MaterialEditorView::renameMaterial(ModelNode &material, const QString &newN void MaterialEditorView::duplicateMaterial(const ModelNode &material) { - QTC_ASSERT(material.isValid(), return); - - if (!model()) - return; + QTC_ASSERT(material.isValid() && model(), return); TypeName matType = material.type(); QmlObjectNode sourceMat(material); @@ -982,8 +999,7 @@ void MaterialEditorView::duplicateMaterial(const ModelNode &material) executeInTransaction(__FUNCTION__, [&] { ModelNode matLib = Utils3D::materialLibraryNode(this); - if (!matLib.isValid()) - return; + QTC_ASSERT(matLib.isValid(), return); // create the duplicate material #ifdef QDS_USE_PROJECTSTORAGE @@ -994,10 +1010,24 @@ void MaterialEditorView::duplicateMaterial(const ModelNode &material) #endif duplicateMatNode = duplicateMat.modelNode(); - // set name and id - QString newName = sourceMat.modelNode().variantProperty("objectName").value().toString() + " copy"; + // generate and set a unique name + QString newName = sourceMat.modelNode().variantProperty("objectName").value().toString(); + if (!newName.contains("copy", Qt::CaseInsensitive)) + newName.append(" copy"); + + const QList mats = matLib.directSubModelNodesOfType(model()->qtQuick3DMaterialMetaInfo()); + QStringList matNames; + for (const ModelNode &mat : mats) + matNames.append(mat.variantProperty("objectName").value().toString()); + + newName = UniqueName::generate(newName, [&] (const QString &name) { + return matNames.contains(name); + }); + VariantProperty objNameProp = duplicateMatNode.variantProperty("objectName"); objNameProp.setValue(newName); + + // generate and set an id duplicateMatNode.setIdWithoutRefactoring(model()->generateNewId(newName, "material")); // sync properties. Only the base state is duplicated. @@ -1076,12 +1106,34 @@ void MaterialEditorView::nodeReparented(const ModelNode &node, { if (node.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) m_qmlBackEnd->contextObject()->setHasMaterialLibrary(true); + else if (m_qmlBackEnd && containsTexture(node)) + m_qmlBackEnd->refreshBackendModel(); +} + +void MaterialEditorView::nodeIdChanged(const ModelNode &node, + [[maybe_unused]] const QString &newId, + [[maybe_unused]] const QString &oldId) +{ + if (m_qmlBackEnd && node.metaInfo().isQtQuick3DTexture()) + m_qmlBackEnd->refreshBackendModel(); } void MaterialEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode) { if (removedNode.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) m_qmlBackEnd->contextObject()->setHasMaterialLibrary(false); + else if (containsTexture(removedNode)) + m_textureAboutToBeRemoved = true; +} + +void MaterialEditorView::nodeRemoved([[maybe_unused]] const ModelNode &removedNode, + [[maybe_unused]] const NodeAbstractProperty &parentProperty, + [[maybe_unused]] PropertyChangeFlags propertyChange) +{ + if (m_qmlBackEnd && m_textureAboutToBeRemoved) + m_qmlBackEnd->refreshBackendModel(); + + m_textureAboutToBeRemoved = false; } void QmlDesigner::MaterialEditorView::highlightSupportedProperties(bool highlight) @@ -1125,7 +1177,9 @@ void MaterialEditorView::dragEnded() } // from model to material editor -void MaterialEditorView::setValue(const QmlObjectNode &qmlObjectNode, const PropertyName &name, const QVariant &value) +void MaterialEditorView::setValue(const QmlObjectNode &qmlObjectNode, + PropertyNameView name, + const QVariant &value) { m_locked = true; m_qmlBackEnd->setValue(qmlObjectNode, name, value); diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h index 11bea460638..8c9247ee784 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h @@ -8,6 +8,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE @@ -54,14 +55,23 @@ public: void nodeTypeChanged(const ModelNode& node, const TypeName &type, int majorVersion, int minorVersion) override; void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion) override; - void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) override; + void modelNodePreviewPixmapChanged(const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId) override; void importsChanged(const Imports &addedImports, const Imports &removedImports) override; void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data) override; - void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, + + void nodeReparented(const ModelNode &node, + const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange) override; + + void nodeIdChanged(const ModelNode &node, const QString &newId, const QString &oldId) override; void nodeAboutToBeRemoved(const ModelNode &removedNode) override; + void nodeRemoved(const ModelNode &removedNode, + const NodeAbstractProperty &parentProperty, + PropertyChangeFlags propertyChange) override; void dragStarted(QMimeData *mimeData) override; void dragEnded() override; @@ -83,10 +93,11 @@ public slots: void handleToolBarAction(int action); void handlePreviewEnvChanged(const QString &envAndValue); void handlePreviewModelChanged(const QString &modelStr); + void handlePreviewSizeChanged(const QSizeF &size); protected: void timerEvent(QTimerEvent *event) override; - void setValue(const QmlObjectNode &fxObjectNode, const PropertyName &name, const QVariant &value); + void setValue(const QmlObjectNode &fxObjectNode, PropertyNameView name, const QVariant &value); bool eventFilter(QObject *obj, QEvent *event) override; private: @@ -100,9 +111,9 @@ private: void setupQmlBackend(); - void commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value); - void commitAuxValueToModel(const PropertyName &propertyName, const QVariant &value); - void removePropertyFromModel(const PropertyName &propertyName); + void commitVariantValueToModel(PropertyNameView propertyName, const QVariant &value); + void commitAuxValueToModel(PropertyNameView propertyName, const QVariant &value); + void removePropertyFromModel(PropertyNameView propertyName); void renameMaterial(ModelNode &material, const QString &newName); void duplicateMaterial(const ModelNode &material); @@ -124,6 +135,9 @@ private: bool m_hasQuick3DImport = false; bool m_hasMaterialRoot = false; bool m_initializingPreviewData = false; + bool m_textureAboutToBeRemoved = false; + QSize m_previewSize; + QByteArray m_previewRequestId; QPointer m_colorDialog; QPointer m_itemLibraryInfo; diff --git a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp index 223e04fd967..7dd73fac1cb 100644 --- a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp +++ b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp @@ -9,7 +9,7 @@ #include "navigatortreeview.h" #include "navigatorwidget.h" #include "choosefrompropertylistdialog.h" -#include +#include #include #include #include diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index c5fa30fc7d8..9ed9f24e42d 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index 774eb43dba3..adfcc903193 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -116,7 +116,6 @@ WidgetInfo NavigatorView::widgetInfo() return createWidgetInfo(m_widget.data(), QStringLiteral("Navigator"), WidgetInfo::LeftPane, - 0, tr("Navigator"), tr("Navigator view")); } @@ -363,9 +362,14 @@ void NavigatorView::enableWidget() m_widget->enableNavigator(); } -void NavigatorView::modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) +void NavigatorView::modelNodePreviewPixmapChanged(const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId) { - m_treeModel->updateToolTipPixmap(node, pixmap); + // There might be multiple requests for different preview pixmap sizes. + // Here only the one with the default size is picked. + if (requestId.isEmpty()) + m_treeModel->updateToolTipPixmap(node, pixmap); } ModelNode NavigatorView::modelNodeForIndex(const QModelIndex &modelIndex) const diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.h b/src/plugins/qmldesigner/components/navigator/navigatorview.h index 662b749ecec..60c48d7bc57 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.h +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.h @@ -83,7 +83,9 @@ public: void disableWidget() override; void enableWidget() override; - void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) override; + void modelNodePreviewPixmapChanged(const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId) override; private: ModelNode modelNodeForIndex(const QModelIndex &modelIndex) const; diff --git a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp index ea2e8bd3e6e..813e64bac71 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp @@ -186,10 +186,27 @@ QToolBar *NavigatorWidget::createToolBar() void NavigatorWidget::contextHelp(const Core::IContext::HelpCallback &callback) const { - if (auto view = navigatorView()) + if (auto view = navigatorView()) { + QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_HELP_REQUESTED + + view->contextHelpId()); +#ifndef QDS_USE_PROJECTSTORAGE + ModelNode selectedNode = view->firstSelectedModelNode(); + if (!selectedNode) + selectedNode = view->rootModelNode(); + + // TODO: Needs to be fixed for projectstorage. + const Core::HelpItem helpItem({QString::fromUtf8("QML." + selectedNode.type()), + "QML." + selectedNode.simplifiedTypeName()}, + {}, + {}, + Core::HelpItem::QmlComponent); + callback(helpItem); +#else QmlDesignerPlugin::contextHelp(callback, view->contextHelpId()); - else +#endif + } else { callback({}); + } } void NavigatorWidget::disableNavigator() diff --git a/src/plugins/qmldesigner/components/navigator/previewtooltip.cpp b/src/plugins/qmldesigner/components/navigator/previewtooltip.cpp index e5e42697e24..1def3cf1198 100644 --- a/src/plugins/qmldesigner/components/navigator/previewtooltip.cpp +++ b/src/plugins/qmldesigner/components/navigator/previewtooltip.cpp @@ -58,7 +58,9 @@ void PreviewToolTip::setInfo(const QString &info) void PreviewToolTip::setPixmap(const QPixmap &pixmap) { - m_ui->imageLabel->setPixmap(pixmap); + QPixmap scaled = pixmap.scaled(m_ui->labelBackground->size(), Qt::KeepAspectRatio); + scaled.setDevicePixelRatio(1.); + m_ui->imageLabel->setPixmap(scaled); } QString PreviewToolTip::id() const diff --git a/src/plugins/qmldesigner/components/propertyeditor/dynamicpropertiesproxymodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/dynamicpropertiesproxymodel.cpp index 48983666199..b1b693b4329 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/dynamicpropertiesproxymodel.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/dynamicpropertiesproxymodel.cpp @@ -102,7 +102,7 @@ QVariant DynamicPropertiesProxyModel::data(const QModelIndex &index, int role) c QTC_ASSERT(property.isValid(), return QVariant()); if (role == propertyNameRole) - return property.name(); + return property.name().toByteArray(); if (propertyTypeRole) return property.dynamicTypeName(); @@ -353,7 +353,7 @@ void DynamicPropertyRow::commitValue(const QVariant &value) variantProperty.setDynamicTypeNameAndValue(variantProperty.dynamicTypeName(), value); } else { QTC_CHECK(objectNode.isValid()); - PropertyName name = variantProperty.name(); + PropertyNameView name = variantProperty.name(); if (objectNode.isValid() && objectNode.modelValue(name) != value) objectNode.setVariantProperty(name, value); } @@ -400,7 +400,7 @@ void DynamicPropertyRow::commitExpression(const QString &expression) } else { QmlObjectNode objectNode = bindingProperty.parentQmlObjectNode(); QTC_CHECK(objectNode.isValid()); - PropertyName name = bindingProperty.name(); + PropertyNameView name = bindingProperty.name(); if (objectNode.isValid() && objectNode.expression(name) != theExpression) objectNode.setBindingProperty(name, theExpression); } @@ -444,7 +444,7 @@ void DynamicPropertyRow::resetValue() try { QmlObjectNode objectNode = property.parentQmlObjectNode(); QTC_CHECK(objectNode.isValid()); - PropertyName name = property.name(); + PropertyNameView name = property.name(); if (objectNode.isValid() && objectNode.propertyAffectedByCurrentState(name)) objectNode.removeProperty(name); diff --git a/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.cpp index aa1d41888b6..dd6b4e92691 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.cpp @@ -28,9 +28,16 @@ void ItemFilterModel::setModelNodeBackend(const QVariant &modelNodeBackend) const auto backendObjectCasted = qobject_cast(modelNodeBackendObject); - if (backendObjectCasted) + disconnect(m_updateConnection); + if (backendObjectCasted) { m_modelNode = backendObjectCasted->qmlObjectNode().modelNode(); + m_updateConnection = connect(backendObjectCasted, + &QmlModelNodeProxy::refreshRequired, + this, + &ItemFilterModel::setupModel); + } + setupModel(); emit modelNodeBackendChanged(); } @@ -112,6 +119,41 @@ QStringList ItemFilterModel::validationItems() const return m_validationItems; } +QVariant ItemFilterModel::modelItemData(int row) const +{ + QModelIndex idx = index(row, 0, {}); + if (!idx.isValid()) + return {}; + + QVariantMap mapItem; + + auto insertData = [&](Role role) { + mapItem.insert(QString::fromUtf8(roleNames().value(role)), idx.data(role)); + }; + + insertData(IdRole); + insertData(IdAndNameRole); + insertData(NameRole); + insertData(EnabledRole); + + return mapItem; +} + +int ItemFilterModel::indexFromId(const QString &id) const +{ + AbstractView *view = m_modelNode.view(); + if (!view || !view->model()) + return -1; + + int idx = -1; + for (const auto &internalId : std::as_const(m_modelInternalIds)) { + ++idx; + if (id == view->modelNodeForInternalId(internalId).id()) + return idx; + } + return -1; +} + void ItemFilterModel::registerDeclarativeType() { qmlRegisterType("HelperWidgets", 2, 0, "ItemFilterModel"); diff --git a/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.h b/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.h index eaf23820d4f..5ffb9d1deed 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.h +++ b/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.h @@ -30,7 +30,9 @@ class ItemFilterModel : public QAbstractListModel Q_PROPERTY(QStringList validationItems READ validationItems NOTIFY validationItemsChanged) public: - enum { IdRole = Qt::DisplayRole, NameRole = Qt::UserRole, IdAndNameRole, EnabledRole }; + enum Role { IdRole = Qt::DisplayRole, NameRole = Qt::UserRole, IdAndNameRole, EnabledRole }; + + Q_ENUM(Role) explicit ItemFilterModel(QObject *parent = nullptr); @@ -45,6 +47,8 @@ public: QStringList itemModel() const; QStringList validationRoles() const; QStringList validationItems() const; + Q_INVOKABLE QVariant modelItemData(int row) const; + Q_INVOKABLE int indexFromId(const QString &id) const; static void registerDeclarativeType(); @@ -71,6 +75,7 @@ private: QString m_typeFilter; QList m_modelInternalIds; QmlDesigner::ModelNode m_modelNode; + QMetaObject::Connection m_updateConnection; bool m_selectionOnly; QStringList m_selectedItems; diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp index 1a49ce0c39e..b1bde8fb0f3 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp @@ -6,8 +6,9 @@ #include "abstractview.h" #include "easingcurvedialog.h" #include "nodemetainfo.h" -#include "qmldesignerconstants.h" +#include "propertyeditorutils.h" #include "qml3dnode.h" +#include "qmldesignerconstants.h" #include "qmldesignerplugin.h" #include "qmlmodelnodeproxy.h" #include "qmlobjectnode.h" @@ -204,10 +205,9 @@ void PropertyEditorContextObject::changeTypeName(const QString &typeName) } // Create a list of properties available for the new type - auto propertiesAndSignals = Utils::transform(metaInfo.properties(), - [](const auto &property) { - return property.name(); - }); + auto propertiesAndSignals = Utils::transform( + PropertyEditorUtils::filteredPropertes(metaInfo), + [](const auto &property) { return property.name(); }); // Add signals to the list for (const auto &signal : metaInfo.signalNames()) { if (signal.isEmpty()) @@ -226,9 +226,9 @@ void PropertyEditorContextObject::changeTypeName(const QString &typeName) continue; // Add dynamic property - propertiesAndSignals.append(property.name()); + propertiesAndSignals.append(property.name().toByteArray()); // Add its change signal - PropertyName name = property.name(); + PropertyName name = property.name().toByteArray(); QChar firstChar = QChar(property.name().at(0)).toUpper().toLatin1(); name[0] = firstChar.toLatin1(); name.prepend("on"); @@ -240,7 +240,7 @@ void PropertyEditorContextObject::changeTypeName(const QString &typeName) QList incompatibleProperties; for (const auto &property : selectedNode.properties()) { if (!propertiesAndSignals.contains(property.name())) - incompatibleProperties.append(property.name()); + incompatibleProperties.append(property.name().toByteArray()); } Utils::sort(incompatibleProperties); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index 9d53b82ab19..b728a9faf77 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -4,6 +4,7 @@ #include "propertyeditorqmlbackend.h" #include "propertyeditortransaction.h" +#include "propertyeditorutils.h" #include "propertyeditorvalue.h" #include "propertymetainfo.h" @@ -21,11 +22,12 @@ #include #include +#include #include #include #include #include -#include +#include #include #include @@ -104,11 +106,11 @@ PropertyEditorQmlBackend::PropertyEditorQmlBackend(PropertyEditorView *propertyE PropertyEditorQmlBackend::~PropertyEditorQmlBackend() = default; -void PropertyEditorQmlBackend::setupPropertyEditorValue(const PropertyName &name, +void PropertyEditorQmlBackend::setupPropertyEditorValue(PropertyNameView name, PropertyEditorView *propertyEditor, const NodeMetaInfo &type) { - QmlDesigner::PropertyName propertyName(name); + QmlDesigner::PropertyName propertyName(name.toByteArray()); propertyName.replace('.', '_'); auto valueObject = qobject_cast(variantToQObject(backendValuesPropertyMap().value(QString::fromUtf8(propertyName)))); if (!valueObject) { @@ -141,9 +143,9 @@ QVariant properDefaultAuxiliaryProperties(const QmlObjectNode &qmlObjectNode, } QVariant properDefaultLayoutAttachedProperties(const QmlObjectNode &qmlObjectNode, - const PropertyName &propertyName) + PropertyNameView propertyName) { - const QVariant value = qmlObjectNode.modelValue("Layout." + propertyName); + const QVariant value = qmlObjectNode.modelValue("Layout."_sv + propertyName); QVariant marginsValue = qmlObjectNode.modelValue("Layout.margins"); if (!marginsValue.isValid()) @@ -176,9 +178,9 @@ QVariant properDefaultLayoutAttachedProperties(const QmlObjectNode &qmlObjectNod } QVariant properDefaultInsightAttachedProperties(const QmlObjectNode &qmlObjectNode, - const PropertyName &propertyName) + PropertyNameView propertyName) { - const QVariant value = qmlObjectNode.modelValue("InsightCategory." + propertyName); + const QVariant value = qmlObjectNode.modelValue("InsightCategory."_sv + propertyName); if (value.isValid()) return value; @@ -196,8 +198,12 @@ void PropertyEditorQmlBackend::setupLayoutAttachedProperties(const QmlObjectNode "minimumHeight", "minimumWidth", "preferredHeight", "preferredWidth", "row", "rowSpan", "topMargin", "bottomMargin", "leftMargin", "rightMargin", "margins"}; - for (const PropertyName &propertyName : propertyNames) { - createPropertyEditorValue(qmlObjectNode, "Layout." + propertyName, properDefaultLayoutAttachedProperties(qmlObjectNode, propertyName), propertyEditor); + for (PropertyNameView propertyName : propertyNames) { + createPropertyEditorValue(qmlObjectNode, + "Layout."_sv + propertyName, + properDefaultLayoutAttachedProperties(qmlObjectNode, + propertyName), + propertyEditor); } } } @@ -207,7 +213,7 @@ void PropertyEditorQmlBackend::setupInsightAttachedProperties(const QmlObjectNod { const PropertyName propertyName = "category"; createPropertyEditorValue(qmlObjectNode, - "InsightCategory." + propertyName, + "InsightCategory."_sv + propertyName, properDefaultInsightAttachedProperties(qmlObjectNode, propertyName), propertyEditor); } @@ -286,7 +292,7 @@ void PropertyEditorQmlBackend::setupAuxiliaryProperties(const QmlObjectNode &qml } void PropertyEditorQmlBackend::handleInstancePropertyChangedInModelNodeProxy( - const ModelNode &modelNode, const PropertyName &propertyName) + const ModelNode &modelNode, PropertyNameView propertyName) { m_backendModelNode.handleInstancePropertyChanged(modelNode, propertyName); } @@ -307,11 +313,11 @@ void PropertyEditorQmlBackend::handlePropertiesRemovedInModelNodeProxy(const Abs } void PropertyEditorQmlBackend::createPropertyEditorValue(const QmlObjectNode &qmlObjectNode, - const PropertyName &name, + PropertyNameView name, const QVariant &value, PropertyEditorView *propertyEditor) { - PropertyName propertyName(name); + PropertyName propertyName(name.toByteArray()); propertyName.replace('.', '_'); auto valueObject = qobject_cast(variantToQObject(backendValuesPropertyMap().value(QString::fromUtf8(propertyName)))); if (!valueObject) { @@ -325,7 +331,8 @@ void PropertyEditorQmlBackend::createPropertyEditorValue(const QmlObjectNode &qm valueObject->setName(name); valueObject->setModelNode(qmlObjectNode); - if (qmlObjectNode.propertyAffectedByCurrentState(name) && !(qmlObjectNode.modelNode().property(name).isBindingProperty())) + if (qmlObjectNode.propertyAffectedByCurrentState(name) + && !(qmlObjectNode.hasBindingProperty(name))) valueObject->setValue(qmlObjectNode.modelValue(name)); else @@ -343,7 +350,9 @@ void PropertyEditorQmlBackend::createPropertyEditorValue(const QmlObjectNode &qm } } -void PropertyEditorQmlBackend::setValue(const QmlObjectNode & , const PropertyName &name, const QVariant &value) +void PropertyEditorQmlBackend::setValue(const QmlObjectNode &, + PropertyNameView name, + const QVariant &value) { // Vector*D values need to be split into their subcomponents if (value.typeId() == QMetaType::QVector2D) { @@ -381,7 +390,7 @@ void PropertyEditorQmlBackend::setValue(const QmlObjectNode & , const PropertyNa propertyValue->setValue(QVariant(vecValue[i])); } } else { - PropertyName propertyName = name; + PropertyName propertyName = name.toByteArray(); propertyName.replace('.', '_'); auto propertyValue = qobject_cast(variantToQObject(m_backendValuesPropertyMap.value(QString::fromUtf8(propertyName)))); if (propertyValue) @@ -389,7 +398,7 @@ void PropertyEditorQmlBackend::setValue(const QmlObjectNode & , const PropertyNa } } -void PropertyEditorQmlBackend::setExpression(const PropertyName &propName, const QString &exp) +void PropertyEditorQmlBackend::setExpression(PropertyNameView propName, const QString &exp) { PropertyEditorValue *propertyValue = propertyValueForName(QString::fromUtf8(propName)); if (propertyValue) @@ -453,7 +462,7 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q if (propertyEditorBenchmark().isInfoEnabled()) time.start(); - for (const auto &property : qmlObjectNode.modelNode().metaInfo().properties()) { + for (const auto &property : PropertyEditorUtils::filteredPropertes(qmlObjectNode.metaInfo())) { auto propertyName = property.name(); createPropertyEditorValue(qmlObjectNode, propertyName, @@ -563,7 +572,7 @@ void PropertyEditorQmlBackend::initialSetup(const TypeName &typeName, const QUrl { NodeMetaInfo metaInfo = propertyEditor->model()->metaInfo(typeName); - for (const auto &property : metaInfo.properties()) { + for (const auto &property : PropertyEditorUtils::filteredPropertes(metaInfo)) { setupPropertyEditorValue(property.name(), propertyEditor, property.propertyType()); } @@ -613,7 +622,9 @@ QString PropertyEditorQmlBackend::propertyEditorResourcesPath() return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); } -inline bool dotPropertyHeuristic(const QmlObjectNode &node, const NodeMetaInfo &type, const PropertyName &name) +inline bool dotPropertyHeuristic(const QmlObjectNode &node, + const NodeMetaInfo &type, + PropertyNameView name) { if (!name.contains(".")) return true; @@ -621,7 +632,7 @@ inline bool dotPropertyHeuristic(const QmlObjectNode &node, const NodeMetaInfo & if (name.count('.') > 1) return false; - QList list = name.split('.'); + QList list = name.toByteArray().split('.'); const PropertyName parentProperty = list.first(); const PropertyName itemProperty = list.last(); @@ -682,7 +693,7 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp PropertyMetaInfos separateSectionProperties; // Iterate over all properties and isolate the properties which have their own template - for (const auto &property : metaType.properties()) { + for (const auto &property : PropertyEditorUtils::filteredPropertes(metaType)) { const auto &propertyName = property.name(); if (propertyName.startsWith("__")) continue; // private API @@ -736,7 +747,7 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp Utils::sort(basicProperties, propertyMetaInfoCompare); - auto findAndFillTemplate = [&nodes, &node, &needsTypeArgTypes](const PropertyName &label, + auto findAndFillTemplate = [&nodes, &node, &needsTypeArgTypes](PropertyNameView label, const PropertyMetaInfo &property) { const auto &propertyName = property.name(); PropertyName underscoreProperty = propertyName; @@ -960,9 +971,10 @@ void PropertyEditorQmlBackend::emitSelectionChanged() m_backendModelNode.emitSelectionChanged(); } -void PropertyEditorQmlBackend::setValueforLayoutAttachedProperties(const QmlObjectNode &qmlObjectNode, const PropertyName &name) +void PropertyEditorQmlBackend::setValueforLayoutAttachedProperties(const QmlObjectNode &qmlObjectNode, + PropertyNameView name) { - PropertyName propertyName = name; + PropertyName propertyName = name.toByteArray(); propertyName.replace("Layout.", ""); setValue(qmlObjectNode, name, properDefaultLayoutAttachedProperties(qmlObjectNode, propertyName)); @@ -976,9 +988,9 @@ void PropertyEditorQmlBackend::setValueforLayoutAttachedProperties(const QmlObje } void PropertyEditorQmlBackend::setValueforInsightAttachedProperties(const QmlObjectNode &qmlObjectNode, - const PropertyName &name) + PropertyNameView name) { - PropertyName propertyName = name; + PropertyName propertyName = name.toByteArray(); propertyName.replace("InsightCategory.", ""); setValue(qmlObjectNode, name, properDefaultInsightAttachedProperties(qmlObjectNode, propertyName)); } diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h index 1c9b808ac3d..c9afbe91bd5 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h @@ -38,8 +38,8 @@ public: void setup(const QmlObjectNode &fxObjectNode, const QString &stateName, const QUrl &qmlSpecificsFile, PropertyEditorView *propertyEditor); void initialSetup(const TypeName &typeName, const QUrl &qmlSpecificsFile, PropertyEditorView *propertyEditor); - void setValue(const QmlObjectNode &fxObjectNode, const PropertyName &name, const QVariant &value); - void setExpression(const PropertyName &propName, const QString &exp); + void setValue(const QmlObjectNode &fxObjectNode, PropertyNameView name, const QVariant &value); + void setExpression(PropertyNameView propName, const QString &exp); QQmlContext *context(); PropertyEditorContextObject* contextObject(); @@ -66,9 +66,9 @@ public: void emitSelectionChanged(); void setValueforLayoutAttachedProperties(const QmlObjectNode &qmlObjectNode, - const PropertyName &name); + PropertyNameView name); void setValueforInsightAttachedProperties(const QmlObjectNode &qmlObjectNode, - const PropertyName &name); + PropertyNameView name); void setValueforAuxiliaryProperties(const QmlObjectNode &qmlObjectNode, AuxiliaryDataKeyView key); void setupLayoutAttachedProperties(const QmlObjectNode &qmlObjectNode, @@ -79,7 +79,7 @@ public: PropertyEditorView *propertyEditor); void handleInstancePropertyChangedInModelNodeProxy(const ModelNode &modelNode, - const PropertyName &propertyName); + PropertyNameView propertyName); void handleVariantPropertyChangedInModelNodeProxy(const VariantProperty &property); void handleBindingPropertyChangedInModelNodeProxy(const BindingProperty &property); @@ -89,9 +89,10 @@ public: private: void createPropertyEditorValue(const QmlObjectNode &qmlObjectNode, - const PropertyName &name, const QVariant &value, + PropertyNameView name, + const QVariant &value, PropertyEditorView *propertyEditor); - void setupPropertyEditorValue(const PropertyName &name, + void setupPropertyEditorValue(PropertyNameView name, PropertyEditorView *propertyEditor, const NodeMetaInfo &type); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.cpp new file mode 100644 index 00000000000..3af4c1abe83 --- /dev/null +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.cpp @@ -0,0 +1,69 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "propertyeditorutils.h" + +namespace QmlDesigner { + +namespace PropertyEditorUtils { + +#ifndef QDS_USE_PROJECTSTORAGE + +static bool checkIfUnkownTypeProperty(const std::vector &propertyNames, + const PropertyName &name) +{ + int i = 0; + + PropertyName prefix = name + '.'; + + for (auto propertyName : propertyNames) { + if (propertyName.startsWith(prefix)) + i++; + + if (i > 10) + return true; + } + + return false; +} + +#endif //QDS_USE_PROJECTSTORAGE + +PropertyMetaInfos filteredPropertes(const NodeMetaInfo &metaInfo) +{ + auto properties = metaInfo.properties(); + +#ifndef QDS_USE_PROJECTSTORAGE + std::vector names = Utils::transform(properties, [](const PropertyMetaInfo &info) { + return info.name(); + }); + + std::vector itemProperties; + + for (const auto &property : properties) { + if (!property.name().contains('.') && property.propertyType().prototypes().size() == 0 + && checkIfUnkownTypeProperty(names, property.name())) { + itemProperties.push_back(property.name()); + } + } + + if (properties.size() > 1000) { + properties = Utils::filtered(properties, [&itemProperties](const PropertyMetaInfo &metaInfo) { + if (metaInfo.name().contains('.')) { + const auto splitted = metaInfo.name().split('.'); + if (std::find(itemProperties.begin(), itemProperties.end(), splitted.first()) + != itemProperties.end()) + return false; + } + + return true; + }); + } +#endif //QDS_USE_PROJECTSTORAGE + + return properties; +} + +} // End namespace PropertyEditorUtils. + +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.h new file mode 100644 index 00000000000..2d675d37ba2 --- /dev/null +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.h @@ -0,0 +1,16 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +namespace QmlDesigner { + +namespace PropertyEditorUtils { + +PropertyMetaInfos filteredPropertes(const NodeMetaInfo &metaInfo); + +} // End namespace PropertyEditorUtils. + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index c14d0cf5c33..f9f58e44e32 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -10,6 +10,7 @@ #include "designmodewidget.h" #include "nodemetainfo.h" #include "nodeproperty.h" +#include "propertyeditorutils.h" #include "propertyeditorview.h" #include "qmldesignerplugin.h" #include "qmlitemnode.h" @@ -70,7 +71,7 @@ static bool cleverColorCompare(const QVariant &value1, const QVariant &value2) // "red" is the same color as "#ff0000" // To simplify editing we convert all explicit color names in the hash format -static void fixAmbigousColorNames(const ModelNode &modelNode, const PropertyName &name, QVariant *value) +static void fixAmbigousColorNames(const ModelNode &modelNode, PropertyNameView name, QVariant *value) { if (auto metaInfo = modelNode.metaInfo(); metaInfo.property(name).propertyType().isColor()) { if (value->typeId() == QMetaType::QColor) { @@ -85,7 +86,7 @@ static void fixAmbigousColorNames(const ModelNode &modelNode, const PropertyName } } -static void fixUrl(const ModelNode &modelNode, const PropertyName &name, QVariant *value) +static void fixUrl(const ModelNode &modelNode, PropertyNameView name, QVariant *value) { if (auto metaInfo = modelNode.metaInfo(); metaInfo.property(name).propertyType().isUrl()) { if (!value->isValid()) @@ -191,7 +192,7 @@ bool PropertyEditorValue::isInModel() const return modelNode().hasProperty(name()); } -PropertyName PropertyEditorValue::name() const +PropertyNameView PropertyEditorValue::name() const { return m_name; } @@ -201,7 +202,7 @@ QString PropertyEditorValue::nameAsQString() const return QString::fromUtf8(m_name); } -void PropertyEditorValue::setName(const PropertyName &name) +void PropertyEditorValue::setName(PropertyNameView name) { m_name = name; } @@ -272,7 +273,7 @@ bool PropertyEditorValue::isAvailable() const const auto mcuAllowedItemProperties = mcuManager.allowedItemProperties(); const auto mcuBannedComplexProperties = mcuManager.bannedComplexProperties(); - const QList list = name().split('.'); + const QList list = name().toByteArray().split('.'); const QByteArray pureName = list.constFirst(); const QString pureNameStr = QString::fromUtf8(pureName); @@ -622,7 +623,7 @@ ModelNode PropertyEditorNodeWrapper::parentModelNode() const return m_editorValue->modelNode(); } -PropertyName PropertyEditorNodeWrapper::propertyName() const +PropertyNameView PropertyEditorNodeWrapper::propertyName() const { return m_editorValue->name(); } @@ -713,7 +714,8 @@ void PropertyEditorNodeWrapper::setup() qDeleteAll(m_valuesPropertyMap.children()); if (QmlObjectNode qmlObjectNode = m_modelNode) { - const PropertyMetaInfos props = m_modelNode.metaInfo().properties(); + const PropertyMetaInfos props = PropertyEditorUtils::filteredPropertes( + m_modelNode.metaInfo()); for (const auto &property : props) { const auto &propertyName = property.name(); auto valueObject = new PropertyEditorValue(&m_valuesPropertyMap); @@ -759,10 +761,10 @@ static QObject *variantToQObject(const QVariant &value) } void PropertyEditorSubSelectionWrapper::createPropertyEditorValue(const QmlObjectNode &qmlObjectNode, - const PropertyName &name, + PropertyNameView name, const QVariant &value) { - PropertyName propertyName(name); + Utils::SmallString propertyName = name.toByteArray(); propertyName.replace('.', '_'); auto valueObject = qobject_cast(variantToQObject(m_valuesPropertyMap.value(QString::fromUtf8(propertyName)))); if (!valueObject) { @@ -834,9 +836,12 @@ PropertyEditorSubSelectionWrapper::PropertyEditorSubSelectionWrapper(const Model { QmlObjectNode qmlObjectNode(modelNode); + return; + QTC_ASSERT(qmlObjectNode.isValid(), return ); - for (const auto &property : qmlObjectNode.modelNode().metaInfo().properties()) { + for (const auto &property : + PropertyEditorUtils::filteredPropertes(qmlObjectNode.modelNode().metaInfo())) { auto propertyName = property.name(); createPropertyEditorValue(qmlObjectNode, propertyName, @@ -896,14 +901,13 @@ void PropertyEditorSubSelectionWrapper::changeValue(const QString &name) } } -void PropertyEditorSubSelectionWrapper::setValueFromModel(const PropertyName &name, - const QVariant &value) +void PropertyEditorSubSelectionWrapper::setValueFromModel(PropertyNameView name, const QVariant &value) { m_locked = true; QmlObjectNode qmlObjectNode(m_modelNode); - PropertyName propertyName = name; + Utils::SmallString propertyName = name; propertyName.replace('.', '_'); auto propertyValue = qobject_cast( variantToQObject(m_valuesPropertyMap.value(QString::fromUtf8(propertyName)))); @@ -912,7 +916,7 @@ void PropertyEditorSubSelectionWrapper::setValueFromModel(const PropertyName &na m_locked = false; } -void PropertyEditorSubSelectionWrapper::resetValue(const PropertyName &name) +void PropertyEditorSubSelectionWrapper::resetValue(PropertyNameView name) { auto propertyValue = qobject_cast( variantToQObject(m_valuesPropertyMap.value(QString::fromUtf8(name)))); @@ -959,7 +963,7 @@ void PropertyEditorSubSelectionWrapper::changeExpression(const QString &property }); /* end of transaction */ } -void PropertyEditorSubSelectionWrapper::removePropertyFromModel(const PropertyName &propertyName) +void PropertyEditorSubSelectionWrapper::removePropertyFromModel(PropertyNameView propertyName) { QTC_ASSERT(m_modelNode.isValid(), return ); @@ -977,7 +981,7 @@ void PropertyEditorSubSelectionWrapper::removePropertyFromModel(const PropertyNa m_locked = false; } -void PropertyEditorSubSelectionWrapper::commitVariantValueToModel(const PropertyName &propertyName, +void PropertyEditorSubSelectionWrapper::commitVariantValueToModel(PropertyNameView propertyName, const QVariant &value) { QTC_ASSERT(m_modelNode.isValid(), return ); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h index c4b09f6b5af..5f734d59733 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h @@ -30,15 +30,17 @@ public: Q_INVOKABLE void deleteModelNode(); - void setValueFromModel(const PropertyName &name, const QVariant &value); - void resetValue(const PropertyName &name); + void setValueFromModel(PropertyNameView name, const QVariant &value); + void resetValue(PropertyNameView name); bool isRelevantModelNode(const ModelNode &modelNode) const; private: void changeValue(const QString &name); void changeExpression(const QString &propertyName); - void createPropertyEditorValue(const QmlObjectNode &qmlObjectNode, const PropertyName &name, const QVariant &value); + void createPropertyEditorValue(const QmlObjectNode &qmlObjectNode, + PropertyNameView name, + const QVariant &value); void exportPropertyAsAlias(const QString &name); void removeAliasExport(const QString &name); bool locked() const; @@ -46,8 +48,8 @@ private: ModelNode m_modelNode; QQmlPropertyMap m_valuesPropertyMap; bool m_locked = false; - void removePropertyFromModel(const PropertyName &propertyName); - void commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value); + void removePropertyFromModel(PropertyNameView propertyName); + void commitVariantValueToModel(PropertyNameView propertyName, const QVariant &value); AbstractView *view() const; }; @@ -67,7 +69,7 @@ public: QString type() const; QQmlPropertyMap *properties(); ModelNode parentModelNode() const; - PropertyName propertyName() const; + PropertyNameView propertyName() const; public slots: void add(const QString &type = QString()); @@ -142,9 +144,9 @@ public: bool isAvailable() const; - PropertyName name() const; + PropertyNameView name() const; QString nameAsQString() const; - void setName(const PropertyName &name); + void setName(PropertyNameView name); ModelNode modelNode() const; void setModelNode(const ModelNode &modelNode); @@ -205,7 +207,7 @@ private: ModelNode m_modelNode; QVariant m_value; QString m_expression; - PropertyName m_name; + Utils::SmallString m_name; bool m_isInSubState = false; bool m_isInModel = false; bool m_isBound = false; diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index bc77f70b2c8..5c88998c906 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -47,12 +47,12 @@ enum { namespace QmlDesigner { -static bool propertyIsAttachedLayoutProperty(const PropertyName &propertyName) +static bool propertyIsAttachedLayoutProperty(PropertyNameView propertyName) { return propertyName.contains("Layout."); } -static bool propertyIsAttachedInsightProperty(const PropertyName &propertyName) +static bool propertyIsAttachedInsightProperty(PropertyNameView propertyName) { return propertyName.contains("InsightCategory."); } @@ -317,7 +317,7 @@ void PropertyEditorView::refreshMetaInfos(const TypeIds &deletedTypeIds) } void PropertyEditorView::setExpressionOnObjectNode(const QmlObjectNode &constObjectNode, - const PropertyName &name, + PropertyNameView name, const QString &newExpression) { auto qmlObjectNode = constObjectNode; @@ -367,9 +367,9 @@ void PropertyEditorView::setExpressionOnObjectNode(const QmlObjectNode &constObj } } - if (qmlObjectNode.expression(name) != expression + if (qmlObjectNode.expression(name) != newExpression || !qmlObjectNode.propertyAffectedByCurrentState(name)) - qmlObjectNode.setBindingProperty(name, expression); + qmlObjectNode.setBindingProperty(name, newExpression); } void PropertyEditorView::generateAliasForProperty(const ModelNode &modelNode, const QString &name) @@ -662,7 +662,7 @@ void PropertyEditorView::setupQmlBackend() #endif // QDS_USE_PROJECTSTORAGE } -void PropertyEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value) +void PropertyEditorView::commitVariantValueToModel(PropertyNameView propertyName, const QVariant &value) { m_locked = true; try { @@ -680,11 +680,11 @@ void PropertyEditorView::commitVariantValueToModel(const PropertyName &propertyN m_locked = false; } -void PropertyEditorView::commitAuxValueToModel(const PropertyName &propertyName, const QVariant &value) +void PropertyEditorView::commitAuxValueToModel(PropertyNameView propertyName, const QVariant &value) { m_locked = true; - PropertyName name = propertyName; + PropertyNameView name = propertyName; name.chop(5); try { @@ -704,7 +704,7 @@ void PropertyEditorView::commitAuxValueToModel(const PropertyName &propertyName, m_locked = false; } -void PropertyEditorView::removePropertyFromModel(const PropertyName &propertyName) +void PropertyEditorView::removePropertyFromModel(PropertyNameView propertyName) { m_locked = true; try { @@ -794,45 +794,51 @@ void PropertyEditorView::propertiesRemoved(const QList &proper if (node == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == node) { m_locked = true; - PropertyName propertyName = property.name(); - propertyName.replace('.', '_'); + const PropertyName propertyName = property.name().toByteArray(); + PropertyName convertedpropertyName = propertyName; + + convertedpropertyName.replace('.', '_'); PropertyEditorValue *value = m_qmlBackEndForCurrentType->propertyValueForName( - QString::fromUtf8(propertyName)); + QString::fromUtf8(convertedpropertyName)); if (value) { value->resetValue(); m_qmlBackEndForCurrentType ->setValue(m_selectedNode, - property.name(), - QmlObjectNode(m_selectedNode).instanceValue(property.name())); + propertyName, + QmlObjectNode(m_selectedNode).instanceValue(propertyName)); } m_locked = false; - if (propertyIsAttachedLayoutProperty(property.name())) { - m_qmlBackEndForCurrentType->setValueforLayoutAttachedProperties(m_selectedNode, property.name()); - - if (property.name() == "Layout.margins") { - m_qmlBackEndForCurrentType->setValueforLayoutAttachedProperties(m_selectedNode, "Layout.topMargin"); - m_qmlBackEndForCurrentType->setValueforLayoutAttachedProperties(m_selectedNode, "Layout.bottomMargin"); - m_qmlBackEndForCurrentType->setValueforLayoutAttachedProperties(m_selectedNode, "Layout.leftMargin"); - m_qmlBackEndForCurrentType->setValueforLayoutAttachedProperties(m_selectedNode, "Layout.rightMargin"); + if (propertyIsAttachedLayoutProperty(propertyName)) { + m_qmlBackEndForCurrentType->setValueforLayoutAttachedProperties(m_selectedNode, + propertyName); + if (propertyName == "Layout.margins") { + m_qmlBackEndForCurrentType + ->setValueforLayoutAttachedProperties(m_selectedNode, "Layout.topMargin"); + m_qmlBackEndForCurrentType + ->setValueforLayoutAttachedProperties(m_selectedNode, "Layout.bottomMargin"); + m_qmlBackEndForCurrentType + ->setValueforLayoutAttachedProperties(m_selectedNode, "Layout.leftMargin"); + m_qmlBackEndForCurrentType + ->setValueforLayoutAttachedProperties(m_selectedNode, "Layout.rightMargin"); } } - if (propertyIsAttachedInsightProperty(property.name())) { + if (propertyIsAttachedInsightProperty(propertyName)) { m_qmlBackEndForCurrentType->setValueforInsightAttachedProperties(m_selectedNode, - property.name()); + propertyName); } - if ("width" == property.name() || "height" == property.name()) { + if ("width" == propertyName || "height" == propertyName) { const QmlItemNode qmlItemNode = m_selectedNode; if (qmlItemNode.isInLayout()) resetPuppet(); } - if (property.name().contains("anchor")) + if (propertyName.contains("anchor")) m_qmlBackEndForCurrentType->backendAnchorBinding().invalidate(m_selectedNode); } } @@ -980,7 +986,6 @@ WidgetInfo PropertyEditorView::widgetInfo() return createWidgetInfo(m_stackedWidget, QStringLiteral("Properties"), WidgetInfo::RightPane, - 0, tr("Properties"), tr("Property Editor view")); } @@ -1066,7 +1071,7 @@ void PropertyEditorView::dragEnded() } void PropertyEditorView::setValue(const QmlObjectNode &qmlObjectNode, - const PropertyName &name, + PropertyNameView name, const QVariant &value) { m_locked = true; diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h index ef2b71f558e..128914cfb6e 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h @@ -85,7 +85,7 @@ public: void refreshMetaInfos(const TypeIds &deletedTypeIds) override; static void setExpressionOnObjectNode(const QmlObjectNode &objectNode, - const PropertyName &name, + PropertyNameView name, const QString &expression); static void generateAliasForProperty(const ModelNode &modelNode, @@ -97,7 +97,7 @@ public: protected: void timerEvent(QTimerEvent *event) override; void setupPane(const TypeName &typeName); - void setValue(const QmlObjectNode &fxObjectNode, const PropertyName &name, const QVariant &value); + void setValue(const QmlObjectNode &fxObjectNode, PropertyNameView name, const QVariant &value); bool eventFilter(QObject *obj, QEvent *event) override; private: //functions @@ -111,9 +111,9 @@ private: //functions void delayedResetView(); void setupQmlBackend(); - void commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value); - void commitAuxValueToModel(const PropertyName &propertyName, const QVariant &value); - void removePropertyFromModel(const PropertyName &propertyName); + void commitVariantValueToModel(PropertyNameView propertyName, const QVariant &value); + void commitAuxValueToModel(PropertyNameView propertyName, const QVariant &value); + void removePropertyFromModel(PropertyNameView propertyName); bool noValidSelection() const; diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertynamevalidator.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertynamevalidator.cpp new file mode 100644 index 00000000000..2af3d1bf9aa --- /dev/null +++ b/src/plugins/qmldesigner/components/propertyeditor/propertynamevalidator.cpp @@ -0,0 +1,36 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "propertynamevalidator.h" + +#include "modelutils.h" + +#include + +PropertyNameValidator::PropertyNameValidator(QObject *parent) + : QValidator(parent) +{} + +QValidator::State PropertyNameValidator::validate(QString &input, int &) const +{ + if (input.isEmpty()) + return QValidator::Intermediate; + + // Property names must begin with a lower case letter and can only contain letters, numbers + // and underscores. JavaScript reserved words are not valid property names. + + if (QmlDesigner::ModelUtils::isQmlKeyword(input)) + return QValidator::Intermediate; + + static QRegularExpression regExp(R"(^[a-z]\w*$)"); + + if (input.contains(regExp)) + return QValidator::Acceptable; + + return QValidator::Invalid; +} + +void PropertyNameValidator::registerDeclarativeType() +{ + qmlRegisterType("HelperWidgets", 2, 0, "PropertyNameValidator"); +} diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertynamevalidator.h b/src/plugins/qmldesigner/components/propertyeditor/propertynamevalidator.h new file mode 100644 index 00000000000..dd9d0042ee6 --- /dev/null +++ b/src/plugins/qmldesigner/components/propertyeditor/propertynamevalidator.h @@ -0,0 +1,21 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include +#include + +class PropertyNameValidator : public QValidator +{ + Q_OBJECT + +public: + explicit PropertyNameValidator(QObject *parent = nullptr); + + QValidator::State validate(QString &input, int &pos) const override; + + static void registerDeclarativeType(); +}; + +QML_DECLARE_TYPE(PropertyNameValidator) diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp index 1cff0e55e68..2799773c01e 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp @@ -46,6 +46,11 @@ void QmlModelNodeProxy::emitSelectionChanged() emit selectionChanged(); } +void QmlModelNodeProxy::refresh() +{ + emit refreshRequired(); +} + QmlObjectNode QmlModelNodeProxy::qmlObjectNode() const { return m_qmlObjectNode; @@ -245,7 +250,7 @@ void QmlModelNodeProxy::changeType(int internalId, const QString &typeName) } void QmlModelNodeProxy::handleInstancePropertyChanged(const ModelNode &modelNode, - const PropertyName &propertyName) + PropertyNameView propertyName) { const QmlObjectNode qmlObjectNode(modelNode); diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h index d8a49d7e100..0d613694715 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h +++ b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h @@ -28,6 +28,7 @@ public: void emitSelectionToBeChanged(); void emitSelectionChanged(); + void refresh(); QmlObjectNode qmlObjectNode() const; @@ -60,7 +61,7 @@ public: Q_INVOKABLE void changeType(int internalId, const QString &typeName); - void handleInstancePropertyChanged(const ModelNode &modelNode, const PropertyName &propertyName); + void handleInstancePropertyChanged(const ModelNode &modelNode, PropertyNameView propertyName); void handleBindingPropertyChanged(const BindingProperty &property); void handleVariantPropertyChanged(const VariantProperty &property); @@ -70,6 +71,7 @@ signals: void modelNodeChanged(); void selectionToBeChanged(); void selectionChanged(); + void refreshRequired(); private: QList allChildren(const ModelNode &modelNode) const; diff --git a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp index 59fbbffc9ca..78514fc91a0 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp @@ -22,6 +22,7 @@ #include "propertyeditorqmlbackend.h" #include "propertyeditorvalue.h" #include "propertymodel.h" +#include "propertynamevalidator.h" #include "qmlanchorbindingproxy.h" #include "richtexteditor/richtexteditorproxy.h" #include "selectiondynamicpropertiesproxymodel.h" @@ -65,6 +66,7 @@ void Quick2PropertyEditorView::registerQmlTypes() DynamicPropertyRow::registerDeclarativeType(); PropertyChangesModel::registerDeclarativeType(); PropertyModel::registerDeclarativeType(); + PropertyNameValidator::registerDeclarativeType(); const QString resourcePath = PropertyEditorQmlBackend::propertyEditorResourcesPath(); diff --git a/src/plugins/qmldesigner/components/stateseditor/propertymodel.cpp b/src/plugins/qmldesigner/components/stateseditor/propertymodel.cpp index db07dd22080..54212be829e 100644 --- a/src/plugins/qmldesigner/components/stateseditor/propertymodel.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/propertymodel.cpp @@ -42,7 +42,7 @@ QVariant PropertyModel::data(const QModelIndex &index, int role) const switch (role) { case Name: { - return m_properties.at(index.row()).name(); + return m_properties.at(index.row()).name().toByteArray(); } case Value: { diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp index 33351baf5ea..afdeb95d3ad 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp @@ -462,6 +462,21 @@ void StatesEditorModel::setCanAddNewStates(bool b) emit canAddNewStatesChanged(); } +QColor StatesEditorModel::backgroundColor() const +{ + return m_backgrounColor; +} + +void StatesEditorModel::setBackgroundColor(const QColor &c) +{ + if (c == m_backgrounColor) + return; + + m_backgrounColor = c; + + emit backgroundColorChanged(); +} + bool StatesEditorModel::isMCUs() const { return DesignerMcuManager::instance().isMCUProject(); diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.h b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.h index 12d66e29bf2..48212f5eb03 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include namespace QmlDesigner { @@ -16,6 +17,8 @@ class StatesEditorModel : public QAbstractListModel Q_PROPERTY(bool canAddNewStates READ canAddNewStates WRITE setCanAddNewStates NOTIFY canAddNewStatesChanged) + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY + backgroundColorChanged FINAL) enum { StateNameRole = Qt::DisplayRole, @@ -93,6 +96,9 @@ public: bool canAddNewStates() const; void setCanAddNewStates(bool b); + QColor backgroundColor() const; + void setBackgroundColor(const QColor &c); + bool isMCUs() const; signals: @@ -104,6 +110,7 @@ signals: void activeStateGroupIndexChanged(); void stateGroupsChanged(); void canAddNewStatesChanged(); + void backgroundColorChanged(); void isMCUsChanged(); private: @@ -111,6 +118,7 @@ private: bool m_hasExtend; QStringList m_extendedStates; bool m_canAddNewStates = false; + QColor m_backgrounColor = Qt::transparent; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp index 26530647d86..8b906854558 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp @@ -14,6 +14,8 @@ #include +#include +#include #include #include #include @@ -68,7 +70,6 @@ WidgetInfo StatesEditorView::widgetInfo() return createWidgetInfo(m_statesEditorWidget.data(), "StatesEditor", WidgetInfo::BottomPane, - 0, tr("States")); } @@ -171,7 +172,7 @@ void StatesEditorView::createNewState() } executeInTransaction("createNewState", [this, newStateName]() { - activeStatesGroupNode().validId(); + activeStatesGroupNode().ensureIdExists(); ModelNode newState = activeStateGroup().addState(newStateName); setCurrentState(newState); @@ -719,6 +720,13 @@ void StatesEditorView::modelAttached(Model *model) resetModel(); resetStateGroups(); + // Initially set background color from auxiliary data + if (rootModelNode().hasAuxiliaryData(formeditorColorProperty)) { + QColor color = rootModelNode().auxiliaryDataWithDefault(formeditorColorProperty).value(); + m_statesEditorModel->setBackgroundColor( + color == BackgroundAction::ContextImage ? Qt::transparent : color); + } + emit m_statesEditorModel->activeStateGroupChanged(); emit m_statesEditorModel->activeStateGroupIndexChanged(); } @@ -880,6 +888,17 @@ void StatesEditorView::variantPropertiesChanged(const QList &pr } } +void StatesEditorView::auxiliaryDataChanged(const ModelNode &, + AuxiliaryDataKeyView key, + const QVariant &data) +{ + if (key == formeditorColorProperty) { + QColor color = data.value(); + m_statesEditorModel->setBackgroundColor( + color == BackgroundAction::ContextImage ? Qt::transparent : color); + } +} + void StatesEditorView::customNotification(const AbstractView * /*view*/, const QString &identifier, const QList & /*nodeList*/, diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h index 502e5d2ac6f..919518683ea 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h @@ -64,15 +64,15 @@ public: PropertyChangeFlags propertyChange) override; void variantPropertiesChanged(const QList &propertyList, PropertyChangeFlags propertyChange) override; - + void auxiliaryDataChanged(const ModelNode &node, + AuxiliaryDataKeyView key, + const QVariant &data) override; void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data) override; void rewriterBeginTransaction() override; void rewriterEndTransaction() override; - - // AbstractView void currentStateChanged(const ModelNode &node) override; void instancesPreviewImageChanged(const QVector &nodeList) override; diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp index 59b6474252f..52245e264b0 100644 --- a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp +++ b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp @@ -115,7 +115,6 @@ WidgetInfo TextEditorView::widgetInfo() return createWidgetInfo(m_widget, "TextEditor", WidgetInfo::CentralPane, - 0, tr("Code"), tr("Code view"), DesignerWidgetFlags::IgnoreErrors); diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp index 127780f9181..e70ddb68d84 100644 --- a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp +++ b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp @@ -115,7 +115,7 @@ void TextEditorWidget::jumpToModelNode(const ModelNode &modelNode) if (nodeOffset > 0) { int line, column; m_textEditor->editorWidget()->convertPosition(nodeOffset, &line, &column); - m_textEditor->editorWidget()->gotoLine(line + 1, column); + m_textEditor->editorWidget()->gotoLine(line, column); highlightToModelNode(modelNode); } diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp index b13d06aa15a..57eb7237d47 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp @@ -67,17 +67,17 @@ TextureEditorQmlBackend::~TextureEditorQmlBackend() { } -PropertyName TextureEditorQmlBackend::auxNamePostFix(const PropertyName &propertyName) +PropertyName TextureEditorQmlBackend::auxNamePostFix(PropertyNameView propertyName) { return propertyName + "__AUX"; } void TextureEditorQmlBackend::createPropertyEditorValue(const QmlObjectNode &qmlObjectNode, - const PropertyName &name, - const QVariant &value, - TextureEditorView *textureEditor) + PropertyNameView name, + const QVariant &value, + TextureEditorView *textureEditor) { - PropertyName propertyName(name); + PropertyName propertyName(name.toByteArray()); propertyName.replace('.', '_'); auto valueObject = qobject_cast(variantToQObject(backendValuesPropertyMap().value(QString::fromUtf8(propertyName)))); if (!valueObject) { @@ -107,7 +107,9 @@ void TextureEditorQmlBackend::createPropertyEditorValue(const QmlObjectNode &qml } } -void TextureEditorQmlBackend::setValue(const QmlObjectNode &, const PropertyName &name, const QVariant &value) +void TextureEditorQmlBackend::setValue(const QmlObjectNode &, + PropertyNameView name, + const QVariant &value) { // Vector*D values need to be split into their subcomponents if (value.typeId() == QVariant::Vector2D) { @@ -145,7 +147,7 @@ void TextureEditorQmlBackend::setValue(const QmlObjectNode &, const PropertyName propertyValue->setValue(QVariant(vecValue[i])); } } else { - PropertyName propertyName = name; + PropertyName propertyName = name.toByteArray(); propertyName.replace('.', '_'); auto propertyValue = qobject_cast(variantToQObject(m_backendValuesPropertyMap.value(QString::fromUtf8(propertyName)))); if (propertyValue) diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h index f69c46a5698..954017c7987 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h @@ -37,7 +37,7 @@ public: void setup(const QmlObjectNode &selectedTextureNode, const QString &stateName, const QUrl &qmlSpecificsFile, TextureEditorView *textureEditor); - void setValue(const QmlObjectNode &fxObjectNode, const PropertyName &name, const QVariant &value); + void setValue(const QmlObjectNode &fxObjectNode, PropertyNameView name, const QVariant &value); QQmlContext *context() const; TextureEditorContextObject *contextObject() const; @@ -58,9 +58,10 @@ public: private: void createPropertyEditorValue(const QmlObjectNode &qmlObjectNode, - const PropertyName &name, const QVariant &value, + PropertyNameView name, + const QVariant &value, TextureEditorView *textureEditor); - PropertyName auxNamePostFix(const PropertyName &propertyName); + PropertyName auxNamePostFix(PropertyNameView propertyName); // to avoid a crash while destructing DesignerPropertyMap in the QQmlData // this needs be destructed after m_quickWidget->engine() is destructed diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp index 6dd56060171..ba62634ae39 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp @@ -12,17 +12,18 @@ #include #include +#include #include #include #include #include #include #include -#include -#include #include #include #include +#include +#include #include @@ -48,6 +49,8 @@ #include #include +using namespace Qt::StringLiterals; + namespace QmlDesigner { TextureEditorView::TextureEditorView(AsynchronousImageCache &imageCache, @@ -55,6 +58,7 @@ TextureEditorView::TextureEditorView(AsynchronousImageCache &imageCache, : AbstractView{externalDependencies} , m_imageCache(imageCache) , m_stackedWidget(new QStackedWidget) + , m_createTexture(new CreateTexture(this)) , m_dynamicPropertiesModel(new DynamicPropertiesModel(true, this)) { m_updateShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_F12), m_stackedWidget); @@ -289,7 +293,8 @@ bool TextureEditorView::locked() const void TextureEditorView::currentTimelineChanged(const ModelNode &) { - m_qmlBackEnd->contextObject()->setHasActiveTimeline(QmlTimeline::hasActiveTimeline(this)); + if (m_qmlBackEnd) + m_qmlBackEnd->contextObject()->setHasActiveTimeline(QmlTimeline::hasActiveTimeline(this)); } DynamicPropertiesModel *TextureEditorView::dynamicPropertiesModel() const @@ -375,21 +380,7 @@ void TextureEditorView::handleToolBarAction(int action) case TextureEditorContextObject::AddNewTexture: { if (!model()) break; - executeInTransaction("TextureEditorView:handleToolBarAction", [&] { - ModelNode matLib = Utils3D::materialLibraryNode(this); - if (!matLib.isValid()) - return; -#ifdef QDS_USE_PROJECTSTORAGE - ModelNode newTextureNode = createModelNode("Texture"); -#else - NodeMetaInfo metaInfo = model()->metaInfo("QtQuick3D.Texture"); - ModelNode newTextureNode = createModelNode("QtQuick3D.Texture", - metaInfo.majorVersion(), - metaInfo.minorVersion()); -#endif - newTextureNode.validId(); - matLib.defaultNodeListProperty().reparentHere(newTextureNode); - }); + m_createTexture->execute(); break; } @@ -484,7 +475,7 @@ void TextureEditorView::setupQmlBackend() #endif } -void TextureEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value) +void TextureEditorView::commitVariantValueToModel(PropertyNameView propertyName, const QVariant &value) { m_locked = true; executeInTransaction("TextureEditorView:commitVariantValueToModel", [&] { @@ -493,11 +484,11 @@ void TextureEditorView::commitVariantValueToModel(const PropertyName &propertyNa m_locked = false; } -void TextureEditorView::commitAuxValueToModel(const PropertyName &propertyName, const QVariant &value) +void TextureEditorView::commitAuxValueToModel(PropertyNameView propertyName, const QVariant &value) { m_locked = true; - PropertyName name = propertyName; + PropertyNameView name = propertyName; name.chop(5); try { @@ -512,7 +503,7 @@ void TextureEditorView::commitAuxValueToModel(const PropertyName &propertyName, m_locked = false; } -void TextureEditorView::removePropertyFromModel(const PropertyName &propertyName) +void TextureEditorView::removePropertyFromModel(PropertyNameView propertyName) { m_locked = true; executeInTransaction("MaterialEditorView:removePropertyFromModel", [&] { @@ -557,8 +548,10 @@ void TextureEditorView::modelAboutToBeDetached(Model *model) { AbstractView::modelAboutToBeDetached(model); m_dynamicPropertiesModel->reset(); - m_qmlBackEnd->textureEditorTransaction()->end(); - m_qmlBackEnd->contextObject()->setHasMaterialLibrary(false); + if (m_qmlBackEnd) { + m_qmlBackEnd->textureEditorTransaction()->end(); + m_qmlBackEnd->contextObject()->setHasMaterialLibrary(false); + } } void TextureEditorView::propertiesRemoved(const QList &propertyList) @@ -572,18 +565,21 @@ void TextureEditorView::propertiesRemoved(const QList &propert if (node.isRootNode()) m_qmlBackEnd->contextObject()->setHasAliasExport(QmlObjectNode(m_selectedTexture).isAliasExported()); + auto propertyName = property.name().toByteArray(); if (node == m_selectedTexture || QmlObjectNode(m_selectedTexture).propertyChangeForCurrentState() == node) { // TODO: workaround for bug QDS-8539. To be removed once it is fixed. if (node.metaInfo().property(property.name()).propertyType().isUrl()) { resetPuppet(); } else { - setValue(m_selectedTexture, property.name(), - QmlObjectNode(m_selectedTexture).instanceValue(property.name())); + setValue(m_selectedTexture, + propertyName, + QmlObjectNode(m_selectedTexture).instanceValue(propertyName)); } } - if (property.name() == "materials" && (node == m_selectedModel - || QmlObjectNode(m_selectedModel).propertyChangeForCurrentState() == node)) { + if (propertyName == "materials" + && (node == m_selectedModel + || QmlObjectNode(m_selectedModel).propertyChangeForCurrentState() == node)) { m_qmlBackEnd->contextObject()->setHasSingleModelSelection(false); } @@ -601,10 +597,16 @@ void TextureEditorView::variantPropertiesChanged(const QList &p if (node == m_selectedTexture || QmlObjectNode(m_selectedTexture).propertyChangeForCurrentState() == node) { if (property.isDynamic()) m_dynamicPropertiesModel->updateItem(property); - if (m_selectedTexture.property(property.name()).isBindingProperty()) - setValue(m_selectedTexture, property.name(), QmlObjectNode(m_selectedTexture).instanceValue(property.name())); - else - setValue(m_selectedTexture, property.name(), QmlObjectNode(m_selectedTexture).modelValue(property.name())); + auto propertyName = property.name().toByteArray(); + if (m_selectedTexture.property(propertyName).isBindingProperty()) { + setValue(m_selectedTexture, + propertyName, + QmlObjectNode(m_selectedTexture).instanceValue(propertyName)); + } else { + setValue(m_selectedTexture, + propertyName, + QmlObjectNode(m_selectedTexture).modelValue(propertyName)); + } } dynamicPropertiesModel()->dispatchPropertyChanges(property); @@ -622,17 +624,25 @@ void TextureEditorView::bindingPropertiesChanged(const QList &p if (property.isAliasExport()) m_qmlBackEnd->contextObject()->setHasAliasExport(QmlObjectNode(m_selectedTexture).isAliasExported()); + auto propertyName = property.name().toByteArray(); + if (node == m_selectedTexture || QmlObjectNode(m_selectedTexture).propertyChangeForCurrentState() == node) { if (property.isDynamic()) m_dynamicPropertiesModel->updateItem(property); - if (QmlObjectNode(m_selectedTexture).modelNode().property(property.name()).isBindingProperty()) - setValue(m_selectedTexture, property.name(), QmlObjectNode(m_selectedTexture).instanceValue(property.name())); - else - setValue(m_selectedTexture, property.name(), QmlObjectNode(m_selectedTexture).modelValue(property.name())); + if (QmlObjectNode(m_selectedTexture).modelNode().property(propertyName).isBindingProperty()) { + setValue(m_selectedTexture, + propertyName, + QmlObjectNode(m_selectedTexture).instanceValue(propertyName)); + } else { + setValue(m_selectedTexture, + propertyName, + QmlObjectNode(m_selectedTexture).modelValue(propertyName)); + } } - if (property.name() == "materials" && (node == m_selectedModel - || QmlObjectNode(m_selectedModel).propertyChangeForCurrentState() == node)) { + if (propertyName == "materials" + && (node == m_selectedModel + || QmlObjectNode(m_selectedModel).propertyChangeForCurrentState() == node)) { bool hasMaterials = QmlObjectNode(m_selectedModel).hasBindingProperty("materials"); m_qmlBackEnd->contextObject()->setHasSingleModelSelection(hasMaterials); } @@ -683,7 +693,6 @@ WidgetInfo TextureEditorView::widgetInfo() return createWidgetInfo(m_stackedWidget, "TextureEditor", WidgetInfo::RightPane, - 0, tr("Texture Editor"), tr("Texture Editor view")); } @@ -769,7 +778,7 @@ void TextureEditorView::duplicateTexture(const ModelNode &texture) QmlObjectNode duplicateTex = createModelNode(matType, metaInfo.majorVersion(), metaInfo.minorVersion()); #endif duplicateTextureNode = duplicateTex .modelNode(); - duplicateTextureNode.validId(); + duplicateTextureNode.ensureIdExists(); // sync properties. Only the base state is duplicated. const QList props = texture.properties(); @@ -885,7 +894,9 @@ void TextureEditorView::dragEnded() } // from model to texture editor -void TextureEditorView::setValue(const QmlObjectNode &qmlObjectNode, const PropertyName &name, const QVariant &value) +void TextureEditorView::setValue(const QmlObjectNode &qmlObjectNode, + PropertyNameView name, + const QVariant &value) { m_locked = true; m_qmlBackEnd->setValue(qmlObjectNode, name, value); diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h index dd5e0b0cc98..28f76448538 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h @@ -18,6 +18,7 @@ QT_END_NAMESPACE namespace QmlDesigner { +class CreateTexture; class DynamicPropertiesModel; class ModelNode; class TextureEditorQmlBackend; @@ -82,7 +83,7 @@ public slots: protected: void timerEvent(QTimerEvent *event) override; - void setValue(const QmlObjectNode &fxObjectNode, const PropertyName &name, const QVariant &value); + void setValue(const QmlObjectNode &fxObjectNode, PropertyNameView name, const QVariant &value); bool eventFilter(QObject *obj, QEvent *event) override; private: @@ -95,9 +96,9 @@ private: void setupQmlBackend(); - void commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value); - void commitAuxValueToModel(const PropertyName &propertyName, const QVariant &value); - void removePropertyFromModel(const PropertyName &propertyName); + void commitVariantValueToModel(PropertyNameView propertyName, const QVariant &value); + void commitAuxValueToModel(PropertyNameView propertyName, const QVariant &value); + void removePropertyFromModel(PropertyNameView propertyName); void duplicateTexture(const ModelNode &texture); bool noValidSelection() const; @@ -118,6 +119,7 @@ private: bool m_initializingPreviewData = false; QPointer m_colorDialog; + QPointer m_createTexture; DynamicPropertiesModel *m_dynamicPropertiesModel = nullptr; }; diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineactions.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineactions.cpp index b6e8b0f77dd..e78e517ce8c 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineactions.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineactions.cpp @@ -90,7 +90,7 @@ void TimelineActions::pasteKeyframesToTarget(const ModelNode &targetNode, view.executeInTransaction("TimelineActions::pasteKeyframesToTarget", [=, &view](){ ModelNode nonConstTargetNode = targetNode; - nonConstTargetNode.validId(); + nonConstTargetNode.ensureIdExists(); if (QmlTimelineKeyframeGroup::checkKeyframesType(rootNode)) { /* Single selection */ diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinesectionitem.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinesectionitem.cpp index 1aeb97e677e..4d5417c0d6b 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinesectionitem.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinesectionitem.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp index 098221bb34f..8bd1fb05fe4 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp @@ -344,7 +344,7 @@ const QmlTimeline TimelineView::addNewTimeline() metaInfo.majorVersion(), metaInfo.minorVersion()); #endif - timelineNode.validId(); + timelineNode.ensureIdExists(); timelineNode.variantProperty("startFrame").setValue(0); timelineNode.variantProperty("endFrame").setValue(1000); @@ -385,7 +385,7 @@ ModelNode TimelineView::addAnimation(QmlTimeline timeline) metaInfo.minorVersion()); animationNode.variantProperty("duration").setValue(timeline.duration()); #endif - animationNode.validId(); + animationNode.ensureIdExists(); animationNode.variantProperty("from").setValue(timeline.startKeyframe()); animationNode.variantProperty("to").setValue(timeline.endKeyframe()); @@ -650,7 +650,6 @@ WidgetInfo TimelineView::widgetInfo() return createWidgetInfo(createWidget(), QStringLiteral("Timelines"), WidgetInfo::BottomPane, - 0, tr("Timeline"), tr("Timeline view")); } diff --git a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp index cb84183f927..47465ebe7bf 100644 --- a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp +++ b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp @@ -763,6 +763,11 @@ bool ToolBarBackend::isDocumentDirty() const && Core::EditorManager::currentDocument()->isModified(); } +bool ToolBarBackend::isLiteModeEnabled() const +{ + return QmlDesignerBasePlugin::isLiteModeEnabled(); +} + void ToolBarBackend::launchGlobalAnnotations() { QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_TOOLBAR_EDIT_GLOBAL_ANNOTATION); diff --git a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.h b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.h index 02bdae17170..1ffc28aec9d 100644 --- a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.h +++ b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.h @@ -99,6 +99,8 @@ class ToolBarBackend : public QObject Q_PROPERTY(bool isSharingEnabled READ isSharingEnabled NOTIFY isSharingEnabledChanged) Q_PROPERTY(bool isDocumentDirty READ isDocumentDirty NOTIFY isDocumentDirtyChanged) + Q_PROPERTY(bool isLiteModeEnabled READ isLiteModeEnabled CONSTANT) + public: ToolBarBackend(QObject *parent = nullptr); static void registerDeclarativeType(); @@ -150,6 +152,8 @@ public: bool isDocumentDirty() const; + bool isLiteModeEnabled() const; + static void launchGlobalAnnotations(); signals: diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsectionitem.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsectionitem.cpp index cbe0e0b1c1f..5b1b4159b39 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsectionitem.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsectionitem.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp index ef10b77dac9..1bbc535b656 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp @@ -250,7 +250,7 @@ ModelNode TransitionEditorView::addNewTransition() }}); #endif transition.setAuxiliaryData(transitionDurationProperty, 2000); - transition.validId(); + transition.ensureIdExists(); root.nodeListProperty("transitions").reparentHere(transition); for (auto it = idPropertyList.cbegin(); it != idPropertyList.cend(); ++it) { @@ -327,7 +327,6 @@ WidgetInfo TransitionEditorView::widgetInfo() return createWidgetInfo(createWidget(), "TransitionEditor", WidgetInfo::BottomPane, - 0, tr("Transitions"), tr("Transitions view")); } diff --git a/src/plugins/qmldesigner/designercore/generatedcomponentutils.cpp b/src/plugins/qmldesigner/designercore/designercoreutils/generatedcomponentutils.cpp similarity index 89% rename from src/plugins/qmldesigner/designercore/generatedcomponentutils.cpp rename to src/plugins/qmldesigner/designercore/designercoreutils/generatedcomponentutils.cpp index da40c4d387d..75f4cbf4aa2 100644 --- a/src/plugins/qmldesigner/designercore/generatedcomponentutils.cpp +++ b/src/plugins/qmldesigner/designercore/designercoreutils/generatedcomponentutils.cpp @@ -131,6 +131,25 @@ Utils::FilePath GeneratedComponentUtils::effectBundlePath() const return basePath.resolvePath(QLatin1String(Constants::COMPONENT_BUNDLES_EFFECT_BUNDLE_TYPE)); } +Utils::FilePath GeneratedComponentUtils::userBundlePath(const QString &bundleId) const +{ + Utils::FilePath basePath = componentBundlesBasePath(); + if (basePath.isEmpty()) + return {}; + + if (bundleId == userMaterialsBundleId()) + return basePath.pathAppended(Constants::COMPONENT_BUNDLES_USER_MATERIAL_BUNDLE_TYPE); + + if (bundleId == userEffectsBundleId()) + return basePath.pathAppended(Constants::COMPONENT_BUNDLES_USER_EFFECT_BUNDLE_TYPE); + + if (bundleId == user3DBundleId()) + return basePath.pathAppended(Constants::COMPONENT_BUNDLES_USER_3D_BUNDLE_TYPE); + + qWarning() << __FUNCTION__ << "no bundleType for bundleId:" << bundleId; + return {}; +} + Utils::FilePath GeneratedComponentUtils::projectModulePath(bool generateIfNotExists) const { using Utils::FilePath; @@ -273,6 +292,21 @@ QString GeneratedComponentUtils::effectsBundleType() const return componentBundlesTypePrefix() + '.' + effectsBundleId(); } +QString GeneratedComponentUtils::userBundleType(const QString &bundleId) const +{ + if (bundleId == userMaterialsBundleId()) + return userMaterialsBundleType(); + + if (bundleId == userEffectsBundleId()) + return userEffectsBundleType(); + + if (bundleId == user3DBundleId()) + return user3DBundleType(); + + qWarning() << __FUNCTION__ << "no bundleType for bundleId:" << bundleId; + return {}; +} + QString GeneratedComponentUtils::userMaterialsBundleType() const { return componentBundlesTypePrefix() + '.' + userMaterialsBundleId(); diff --git a/src/plugins/qmldesigner/designercore/generatedcomponentutils.h b/src/plugins/qmldesigner/designercore/designercoreutils/generatedcomponentutils.h similarity index 93% rename from src/plugins/qmldesigner/designercore/generatedcomponentutils.h rename to src/plugins/qmldesigner/designercore/designercoreutils/generatedcomponentutils.h index ceddb405a34..f35dee554a7 100644 --- a/src/plugins/qmldesigner/designercore/generatedcomponentutils.h +++ b/src/plugins/qmldesigner/designercore/designercoreutils/generatedcomponentutils.h @@ -23,6 +23,7 @@ public: Utils::FilePath import3dBasePath() const; Utils::FilePath materialBundlePath() const; Utils::FilePath effectBundlePath() const; + Utils::FilePath userBundlePath(const QString &bundleId) const; Utils::FilePath projectModulePath(bool generateIfNotExists = false) const; bool isImport3dPath(const QString &path) const; @@ -44,6 +45,7 @@ public: QString materialsBundleType() const; QString effectsBundleType() const; + QString userBundleType(const QString &bundleId) const; QString userMaterialsBundleType() const; QString userEffectsBundleType() const; QString user3DBundleType() const; diff --git a/src/plugins/qmldesigner/designercore/model/modelmerger.cpp b/src/plugins/qmldesigner/designercore/designercoreutils/modelmerger.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/modelmerger.cpp rename to src/plugins/qmldesigner/designercore/designercoreutils/modelmerger.cpp diff --git a/src/plugins/qmldesigner/designercore/include/modelmerger.h b/src/plugins/qmldesigner/designercore/designercoreutils/modelmerger.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/modelmerger.h rename to src/plugins/qmldesigner/designercore/designercoreutils/modelmerger.h diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp b/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp new file mode 100644 index 00000000000..e392bffe730 --- /dev/null +++ b/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp @@ -0,0 +1,501 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "modelutils.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include + +namespace QmlDesigner::ModelUtils { + +namespace { + +enum class ImportError { EmptyImportName, HasAlreadyImport, NoModule }; + +template +constexpr auto toSortedArray(const Entries &...entries) +{ + std::array sortedArray = {entries...}; + + std::sort(std::begin(sortedArray), std::end(sortedArray)); + + return sortedArray; +} + +// alias, print, console are not part of qmljs +constexpr auto qmlKeywords = toSortedArray(u"abstract", + u"alias", + u"as", + u"boolean", + u"break", + u"byte", + u"case", + u"catch", + u"char", + u"class", + u"component", + u"console", + u"const", + u"continue", + u"debugger", + u"default", + u"delete", + u"do", + u"double", + u"else", + u"enum", + u"export", + u"extends", + u"false", + u"final", + u"finally", + u"float", + u"for", + u"from", + u"function", + u"get", + u"goto", + u"if", + u"implements", + u"import", + u"in", + u"instanceof", + u"int", + u"interface", + u"let", + u"long", + u"native", + u"new", + u"null", + u"of", + u"on", + u"package", + u"pragma", + u"print", + u"private", + u"property", + u"protected", + u"public", + u"readonly", + u"required", + u"return", + u"set", + u"short", + u"signal", + u"static", + u"super", + u"switch", + u"synchronized", + u"this", + u"throw", + u"throws", + u"transient", + u"true", + u"try", + u"typeof", + u"var", + u"void", + u"volatile", + u"while", + u"with", + u"yield"); + +constexpr auto qmlDiscouragedIds = toSortedArray(u"action", + u"anchors", + u"baseState", + u"border", + u"bottom", + u"clip", + u"data", + u"enabled", + u"flow", + u"focus", + u"font", + u"height", + u"id", + u"item", + u"layer", + u"left", + u"margin", + u"opacity", + u"padding", + u"parent", + u"right", + u"scale", + u"shaderInfo", + u"source", + u"sprite", + u"spriteSequence", + u"state", + u"text", + u"texture", + u"time", + u"top", + u"visible", + u"width", + u"x", + u"y", + u"z"); + +constexpr auto qmlBuiltinTypes = toSortedArray(u"bool", + u"color", + u"date", + u"double", + u"enumeration", + u"font", + u"int", + u"list", + u"matrix4x4", + u"point", + u"quaternion", + u"real", + u"rect", + u"size", + u"string", + u"url", + u"var", + u"variant", + u"vector", + u"vector2d", + u"vector3d", + u"vector4d"); + +constexpr auto createBannedQmlIds() +{ + std::array ids; + + auto idsEnd = std::copy(std::begin(qmlKeywords), std::end(qmlKeywords), ids.begin()); + idsEnd = std::copy(std::begin(qmlDiscouragedIds), std::end(qmlDiscouragedIds), idsEnd); + std::copy(std::begin(qmlBuiltinTypes), std::end(qmlBuiltinTypes), idsEnd); + + std::sort(ids.begin(), ids.end()); + + return ids; +} + +::Utils::expected findImport(const QString &importName, + const std::function &predicate, + const Imports &imports, + const Imports &modules) +{ + if (importName.isEmpty()) + return ::Utils::make_unexpected(ImportError::EmptyImportName); + + auto hasName = [&](const auto &import) { + return import.url() == importName || import.file() == importName; + }; + + bool hasImport = std::any_of(imports.begin(), imports.end(), hasName); + + if (hasImport) + return ::Utils::make_unexpected(ImportError::HasAlreadyImport); + + auto foundModule = std::find_if(modules.begin(), modules.end(), [&](const Import &import) { + return hasName(import) && predicate(import); + }); + + if (foundModule == modules.end()) + return ::Utils::make_unexpected(ImportError::NoModule); + + return *foundModule; +} + +} // namespace + +bool addImportWithCheck(const QString &importName, + const std::function &predicate, + Model *model) +{ + return addImportsWithCheck({importName}, predicate, model); +} + +bool addImportWithCheck(const QString &importName, Model *model) +{ + return addImportWithCheck( + importName, [](const Import &) { return true; }, model); +} + +bool addImportsWithCheck(const QStringList &importNames, Model *model) +{ + return addImportsWithCheck( + importNames, [](const Import &) { return true; }, model); +} + +bool addImportsWithCheck(const QStringList &importNames, + const std::function &predicate, + Model *model) +{ + const Imports &imports = model->imports(); + const Imports &modules = model->possibleImports(); + + Imports importsToAdd; + importsToAdd.reserve(importNames.size()); + + for (const QString &importName : importNames) { + auto import = findImport(importName, predicate, imports, modules); + + if (import) { + importsToAdd.push_back(*import); + } else { + if (import.error() == ImportError::NoModule) + return false; + else + continue; + } + } + + if (!importsToAdd.isEmpty()) + model->changeImports(std::move(importsToAdd), {}); + + return true; +} + +PropertyMetaInfo metainfo(const AbstractProperty &property) +{ + return metainfo(property.parentModelNode(), property.name()); +} + +PropertyMetaInfo metainfo(const ModelNode &node, PropertyNameView propertyName) +{ + return node.metaInfo().property(propertyName); +} + +QString componentFilePath([[maybe_unused]] const PathCacheType &pathCache, const NodeMetaInfo &metaInfo) +{ +#ifdef QDS_USE_PROJECTSTORAGE + auto typeSourceId = metaInfo.sourceId(); + + if (typeSourceId && metaInfo.isFileComponent()) { + return pathCache.sourcePath(typeSourceId).toQString(); + } + + return {}; +#else + return metaInfo.componentFileName(); +#endif +} + +QString componentFilePath(const ModelNode &node) +{ + if (node) { + const auto &pathCache = node.model()->pathCache(); + return ModelUtils::componentFilePath(pathCache, node.metaInfo()); + } + + return {}; +} + +QList pruneChildren(const QList &nodes) +{ + QList forwardNodes; + QList backNodes; + + auto pushIfIsNotChild = [](QList &container, const ModelNode &node) { + bool hasAncestor = Utils::anyOf(container, [node](const ModelNode &testNode) -> bool { + return testNode.isAncestorOf(node); + }); + if (!hasAncestor) + container.append(node); + }; + + for (const ModelNode &node : nodes | Utils::views::reverse) { + if (node) + pushIfIsNotChild(forwardNodes, node); + } + + for (const ModelNode &node : forwardNodes | Utils::views::reverse) + pushIfIsNotChild(backNodes, node); + + return backNodes; +} + +QList allModelNodesWithId(AbstractView *view) +{ + QTC_ASSERT(view->isAttached(), return {}); + return Utils::filtered(view->allModelNodes(), [&](const ModelNode &node) { return node.hasId(); }); +} + +bool isThisOrAncestorLocked(const ModelNode &node) +{ + if (!node.isValid()) + return false; + + if (node.locked()) + return true; + + if (node.isRootNode() || !node.hasParentProperty()) + return false; + + return isThisOrAncestorLocked(node.parentProperty().parentModelNode()); +} + +/*! + * \brief The lowest common ancestor node for node1 and node2. If one of the nodes (Node A) is + * the ancestor of the other node, the return value is Node A and not the parent of Node A. + * \param node1 First node + * \param node2 Second node + * \param depthOfLCA Depth of the return value + * \param depthOfNode1 Depth of node1. Use this parameter for optimization + * \param depthOfNode2 Depth of node2. Use this parameter for optimization + */ +namespace { +ModelNode lowestCommonAncestor(const ModelNode &node1, + const ModelNode &node2, + int &depthOfLCA, + const int &depthOfNode1 = -1, + const int &depthOfNode2 = -1) +{ + auto depthOfNode = [](const ModelNode &node) -> int { + int depth = 0; + ModelNode parentNode = node; + while (parentNode && !parentNode.isRootNode()) { + depth++; + parentNode = parentNode.parentProperty().parentModelNode(); + } + + return depth; + }; + + if (node1 == node2) { + depthOfLCA = (depthOfNode1 < 0) ? ((depthOfNode2 < 0) ? depthOfNode(node1) : depthOfNode2) + : depthOfNode1; + return node1; + } + + if (node1.model() != node2.model()) { + depthOfLCA = -1; + return {}; + } + + if (node1.isRootNode()) { + depthOfLCA = 0; + return node1; + } + + if (node2.isRootNode()) { + depthOfLCA = 0; + return node2; + } + + ModelNode nodeLower = node1; + ModelNode nodeHigher = node2; + int depthLower = (depthOfNode1 < 0) ? depthOfNode(nodeLower) : depthOfNode1; + int depthHigher = (depthOfNode2 < 0) ? depthOfNode(nodeHigher) : depthOfNode2; + + if (depthLower > depthHigher) { + std::swap(depthLower, depthHigher); + std::swap(nodeLower, nodeHigher); + } + + int depthDiff = depthHigher - depthLower; + while (depthDiff--) + nodeHigher = nodeHigher.parentProperty().parentModelNode(); + + while (nodeLower != nodeHigher) { + nodeLower = nodeLower.parentProperty().parentModelNode(); + nodeHigher = nodeHigher.parentProperty().parentModelNode(); + --depthLower; + } + + depthOfLCA = depthLower; + return nodeLower; +} +} // namespace + +/*! + * \brief The lowest common node containing all nodes. If one of the nodes (Node A) is + * the ancestor of the other nodes, the return value is Node A and not the parent of Node A. + */ +ModelNode lowestCommonAncestor(Utils::span nodes) +{ + if (nodes.empty()) + return {}; + + ModelNode accumulatedNode = nodes.front(); + int accumulatedNodeDepth = -1; + for (const ModelNode &node : nodes.subspan(1)) { + accumulatedNode = lowestCommonAncestor(accumulatedNode, + node, + accumulatedNodeDepth, + accumulatedNodeDepth); + if (!accumulatedNode) + return {}; + } + + return accumulatedNode; +} + +bool isQmlKeyword(QStringView id) +{ + return std::binary_search(std::begin(qmlKeywords), std::end(qmlKeywords), toStdStringView(id)); +} + +bool isDiscouragedQmlId(QStringView id) +{ + return std::binary_search(std::begin(qmlDiscouragedIds), + std::end(qmlDiscouragedIds), + toStdStringView(id)); +} + +bool isQmlBuiltinType(QStringView id) +{ + return std::binary_search(std::begin(qmlBuiltinTypes), + std::end(qmlBuiltinTypes), + toStdStringView(id)); +} + +bool isBannedQmlId(QStringView id) +{ + static constexpr auto invalidIds = createBannedQmlIds(); + return std::binary_search(invalidIds.begin(), invalidIds.end(), toStdStringView(id)); +} + +bool isValidQmlIdentifier(QStringView id) +{ + static QRegularExpression idExpr(R"(^[a-z_]\w*$)"); + return id.contains(idExpr); +} + +QStringList expressionToList(QStringView expression) +{ + QStringView cleanedExp = (expression.startsWith('[') && expression.endsWith(']')) + ? expression.sliced(1, expression.size() - 2) + : expression; + QList tokens = cleanedExp.split(','); + + QStringList expList; + expList.reserve(tokens.size()); + for (QStringView token : tokens) { + token = token.trimmed(); + if (!token.isEmpty()) + expList.append(token.toString()); + } + + return expList; +} + +QString listToExpression(const QStringList &stringList) +{ + if (stringList.size() > 1) + return QString("[" + stringList.join(",") + "]"); + + if (stringList.size() == 1) + return stringList.first(); + + return QString(); +} + +} // namespace QmlDesigner::ModelUtils diff --git a/src/plugins/qmldesigner/designercore/model/modelutils.h b/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.h similarity index 79% rename from src/plugins/qmldesigner/designercore/model/modelutils.h rename to src/plugins/qmldesigner/designercore/designercoreutils/modelutils.h index 2cef2e1fb26..450a4fa7dfb 100644 --- a/src/plugins/qmldesigner/designercore/model/modelutils.h +++ b/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.h @@ -31,8 +31,7 @@ QMLDESIGNERCORE_EXPORT bool addImportWithCheck(const QString &importName, QMLDESIGNERCORE_EXPORT bool addImportWithCheck(const QString &importName, Model *model); QMLDESIGNERCORE_EXPORT PropertyMetaInfo metainfo(const AbstractProperty &property); -QMLDESIGNERCORE_EXPORT PropertyMetaInfo metainfo(const ModelNode &node, - const PropertyName &propertyName); +QMLDESIGNERCORE_EXPORT PropertyMetaInfo metainfo(const ModelNode &node, PropertyNameView propertyName); QMLDESIGNERCORE_EXPORT QString componentFilePath(const PathCacheType &pathCache, const NodeMetaInfo &metaInfo); @@ -46,9 +45,20 @@ QMLDESIGNERCORE_EXPORT QList allModelNodesWithId(AbstractView *view); QMLDESIGNERCORE_EXPORT bool isThisOrAncestorLocked(const ModelNode &node); QMLDESIGNERCORE_EXPORT ModelNode lowestCommonAncestor(Utils::span nodes); +QMLDESIGNERCORE_EXPORT bool isQmlKeyword(QStringView id); +QMLDESIGNERCORE_EXPORT bool isDiscouragedQmlId(QStringView id); +QMLDESIGNERCORE_EXPORT bool isQmlBuiltinType(QStringView id); +QMLDESIGNERCORE_EXPORT bool isBannedQmlId(QStringView id); +QMLDESIGNERCORE_EXPORT bool isValidQmlIdentifier(QStringView id); + constexpr std::u16string_view toStdStringView(QStringView view) { return {view.utf16(), Utils::usize(view)}; } +QMLDESIGNERCORE_EXPORT QStringList expressionToList(QStringView exp); + +QMLDESIGNERCORE_EXPORT QString listToExpression(const QStringList &stringList); +; + } // namespace QmlDesigner::ModelUtils diff --git a/src/plugins/qmldesigner/designercore/model/skipiterator.h b/src/plugins/qmldesigner/designercore/designercoreutils/skipiterator.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/skipiterator.h rename to src/plugins/qmldesigner/designercore/designercoreutils/skipiterator.h diff --git a/src/plugins/qmldesigner/designercore/model/stylesheetmerger.cpp b/src/plugins/qmldesigner/designercore/designercoreutils/stylesheetmerger.cpp similarity index 99% rename from src/plugins/qmldesigner/designercore/model/stylesheetmerger.cpp rename to src/plugins/qmldesigner/designercore/designercoreutils/stylesheetmerger.cpp index 4f744d54e6c..50059428841 100644 --- a/src/plugins/qmldesigner/designercore/model/stylesheetmerger.cpp +++ b/src/plugins/qmldesigner/designercore/designercoreutils/stylesheetmerger.cpp @@ -89,7 +89,7 @@ void StylesheetMerger::syncNodeProperties(ModelNode &outputNode, const ModelNode continue; ModelNode newNode = createReplacementNode(oldNode, oldNode); // cache the property name as removing it will invalidate it - PropertyName propertyName = nodeProperty.name(); + PropertyNameView propertyName = nodeProperty.name(); // remove property first to prevent invalid reparenting situation outputNode.removeProperty(propertyName); outputNode.nodeProperty(propertyName).reparentHere(newNode); @@ -169,7 +169,8 @@ ModelNode StylesheetMerger::createReplacementNode(const ModelNode& styleNode, Mo continue; if (isTextAlignmentProperty(variantProperty) && !m_options.preserveTextAlignment && !styleNode.hasProperty(variantProperty.name())) continue; - propertyList.append(QPair(variantProperty.name(), variantProperty.value())); + propertyList.append(QPair(variantProperty.name().toByteArray(), + variantProperty.value())); } #ifdef QDS_USE_PROJECTSTORAGE @@ -278,7 +279,7 @@ void StylesheetMerger::replaceNode(ModelNode &replacedNode, ModelNode &newNode) for (const NodeProperty &prop : parentModelNode.nodeProperties()) { if (prop.modelNode().id() == replacedNode.id()) { isNodeProperty = true; - reparentName = prop.name(); + reparentName = prop.name().toByteArray(); } } ReparentInfo info; diff --git a/src/plugins/qmldesigner/designercore/include/stylesheetmerger.h b/src/plugins/qmldesigner/designercore/designercoreutils/stylesheetmerger.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/stylesheetmerger.h rename to src/plugins/qmldesigner/designercore/designercoreutils/stylesheetmerger.h diff --git a/src/plugins/qmldesigner/designercore/uniquename.cpp b/src/plugins/qmldesigner/designercore/designercoreutils/uniquename.cpp similarity index 59% rename from src/plugins/qmldesigner/designercore/uniquename.cpp rename to src/plugins/qmldesigner/designercore/designercoreutils/uniquename.cpp index d7506164dbe..e22ab6cb985 100644 --- a/src/plugins/qmldesigner/designercore/uniquename.cpp +++ b/src/plugins/qmldesigner/designercore/designercoreutils/uniquename.cpp @@ -3,7 +3,7 @@ #include "uniquename.h" -#include +#include #include #include @@ -12,48 +12,57 @@ namespace QmlDesigner::UniqueName { using namespace Qt::Literals; -constexpr QLatin1StringView keywords[] { - "anchors"_L1, "as"_L1, "baseState"_L1, - "border"_L1, "bottom"_L1, "break"_L1, - "case"_L1, "catch"_L1, "clip"_L1, - "color"_L1, "continue"_L1, "data"_L1, - "debugger"_L1, "default"_L1, "delete"_L1, - "do"_L1, "else"_L1, "enabled"_L1, - "finally"_L1, "flow"_L1, "focus"_L1, - "font"_L1, "for"_L1, "function"_L1, - "height"_L1, "if"_L1, "import"_L1, - "in"_L1, "instanceof"_L1, "item"_L1, - "layer"_L1, "left"_L1, "margin"_L1, - "new"_L1, "opacity"_L1, "padding"_L1, - "parent"_L1, "print"_L1, "rect"_L1, - "return"_L1, "right"_L1, "scale"_L1, - "shaderInfo"_L1, "source"_L1, "sprite"_L1, - "spriteSequence"_L1, "state"_L1, "switch"_L1, - "text"_L1, "this"_L1, "throw"_L1, - "top"_L1, "try"_L1, "typeof"_L1, - "var"_L1, "visible"_L1, "void"_L1, - "while"_L1, "with"_L1, "x"_L1, - "y"_L1 -}; - namespace { -QString toCamelCase(const QString &input) +bool isAsciiLetter(QChar c) { - QString result = input.at(0).toLower(); + return (c >= u'A' && c <= u'Z') || (c >= u'a' && c <= u'z'); +} + +bool isValidLetter(QChar c) +{ + return c == u'_' || c.isDigit() || isAsciiLetter(c); +} + +QString filterInvalidLettersAndCapitalizeAfterInvalidLetter(QStringView id) +{ + QString result; bool capitalizeNext = false; - - for (const QChar &c : Utils::span{input}.subspan(1)) { - bool isValidChar = c.isLetterOrNumber() || c == '_'; - if (isValidChar) + for (const QChar &c : id) { + if (isValidLetter(c)) { result += capitalizeNext ? c.toUpper() : c; - - capitalizeNext = !isValidChar; + capitalizeNext = false; + } else { + capitalizeNext = true; + } } return result; } +void lowerFirstLetter(QString &id) +{ + if (id.size()) + id.front() = id.front().toLower(); +} + +void prependUnderscoreIfBanned(QString &id) +{ + if (id.size() && (id.front().isDigit() || ModelUtils::isBannedQmlId(id))) + id.prepend(u'_'); +} + +QString toValidId(QStringView id) +{ + QString validId = filterInvalidLettersAndCapitalizeAfterInvalidLetter(id); + + lowerFirstLetter(validId); + + prependUnderscoreIfBanned(validId); + + return validId; +} + } // namespace /** @@ -136,27 +145,47 @@ QString generatePath(const QString &path) * @brief Generates a unique ID based on the provided id * * This works similar to get() with additional restrictions: - * - Removes non-Latin1 characters - * - Removes spaces + * - Removes all characters except A-Z, a-z, 0-9, and underscore. * - Ensures the first letter is lowercase - * - Converts spaces to camel case + * - Converts to camel case by making the following character of an invalid character uppercase. * - Prepends an underscore if id starts with a number or is a reserved word * * @param id The original id to be made unique. + * @param predicate Called with a new version of generated id until predicate returns true. * @return A unique Id (when predicate() returns false) */ -QString generateId(const QString &id, std::function predicate) +QString generateId(QStringView id, std::function predicate) { - // remove non word (non A-Z, a-z, 0-9) or space characters - QString newId = id.trimmed(); + QString newId = toValidId(id); + if (!predicate || newId.isEmpty()) + return newId; - newId = toCamelCase(newId); + return UniqueName::generate(newId, predicate); +} - // prepend _ if starts with a digit or invalid id (such as reserved words) - if (newId.at(0).isDigit() || std::binary_search(std::begin(keywords), std::end(keywords), newId)) - newId.prepend('_'); +/** + * @brief Generates a unique ID based on the provided id + * + * This works similar to get() with additional restrictions: + * - Removes all characters except A-Z, a-z, 0-9, and underscore. + * - Ensures the first letter is lowercase + * - Converts to camel case by making the following character of an invalid character uppercase. + * - Prepends an underscore if id starts with a number or is a reserved word + * + * @param id The original id to be made unique. + * @param fallbackId This is used when the id is empty or contains only invalid chars. + * @param predicate Called with a new version of generated id until predicate returns true. + * @return A unique Id (when predicate() returns false) + */ +QString generateId(QStringView id, + const QString &fallbackId, + std::function predicate) +{ + QString newId = toValidId(id); + if (newId.isEmpty()) + newId = fallbackId; - if (!predicate) + if (newId.isEmpty() || !predicate) return newId; return UniqueName::generate(newId, predicate); diff --git a/src/plugins/qmldesigner/designercore/uniquename.h b/src/plugins/qmldesigner/designercore/designercoreutils/uniquename.h similarity index 64% rename from src/plugins/qmldesigner/designercore/uniquename.h rename to src/plugins/qmldesigner/designercore/designercoreutils/uniquename.h index 85927c45147..20bcacefdd1 100644 --- a/src/plugins/qmldesigner/designercore/uniquename.h +++ b/src/plugins/qmldesigner/designercore/designercoreutils/uniquename.h @@ -11,7 +11,11 @@ namespace QmlDesigner::UniqueName { QString generate(const QString &name, std::function predicate); QString generatePath(const QString &path); -QMLDESIGNERCORE_EXPORT QString generateId(const QString &id, + +QMLDESIGNERCORE_EXPORT QString generateId(QStringView id, + std::function predicate = {}); +QMLDESIGNERCORE_EXPORT QString generateId(QStringView id, + const QString &fallbackId, std::function predicate = {}); } // namespace QmlDesigner::UniqueName diff --git a/src/plugins/qmldesigner/designercore/filemanager/addpropertyvisitor.cpp b/src/plugins/qmldesigner/designercore/filemanager/addpropertyvisitor.cpp index 88cbbda09a6..2807477b70a 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/addpropertyvisitor.cpp +++ b/src/plugins/qmldesigner/designercore/filemanager/addpropertyvisitor.cpp @@ -10,18 +10,18 @@ namespace Internal { AddPropertyVisitor::AddPropertyVisitor(TextModifier &modifier, quint32 parentLocation, - const PropertyName &name, + PropertyNameView name, const QString &value, QmlRefactoring::PropertyType propertyType, const PropertyNameList &propertyOrder, - const TypeName &dynamicTypeName) : - QMLRewriter(modifier), - m_parentLocation(parentLocation), - m_name(name), - m_value(value), - m_propertyType(propertyType), - m_propertyOrder(propertyOrder), - m_dynamicTypeName(dynamicTypeName) + const TypeName &dynamicTypeName) + : QMLRewriter(modifier) + , m_parentLocation(parentLocation) + , m_name(name) + , m_value(value) + , m_propertyType(propertyType) + , m_propertyOrder(propertyOrder) + , m_dynamicTypeName(dynamicTypeName) { } diff --git a/src/plugins/qmldesigner/designercore/filemanager/addpropertyvisitor.h b/src/plugins/qmldesigner/designercore/filemanager/addpropertyvisitor.h index e6440bf84b3..4710ecfb54d 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/addpropertyvisitor.h +++ b/src/plugins/qmldesigner/designercore/filemanager/addpropertyvisitor.h @@ -15,7 +15,7 @@ public: public: AddPropertyVisitor(TextModifier &modifier, quint32 parentLocation, - const PropertyName &name, + PropertyNameView name, const QString &value, QmlRefactoring::PropertyType propertyType, const PropertyNameList &propertyOrder, @@ -30,7 +30,7 @@ private: private: quint32 m_parentLocation; - PropertyName m_name; + PropertyNameView m_name; QString m_value; QmlRefactoring::PropertyType m_propertyType; PropertyNameList m_propertyOrder; diff --git a/src/plugins/qmldesigner/designercore/filemanager/moveobjectvisitor.cpp b/src/plugins/qmldesigner/designercore/filemanager/moveobjectvisitor.cpp index 65d14bc11a9..73165b3f14f 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/moveobjectvisitor.cpp +++ b/src/plugins/qmldesigner/designercore/filemanager/moveobjectvisitor.cpp @@ -18,16 +18,16 @@ class Inserter: public QMLRewriter public: Inserter(TextModifier &modifier, quint32 targetParentObjectLocation, - const PropertyName &targetPropertyName, + PropertyNameView targetPropertyName, bool targetIsArrayBinding, TextModifier::MoveInfo moveInfo, - const PropertyNameList &propertyOrder): - QMLRewriter(modifier), - targetParentObjectLocation(targetParentObjectLocation), - targetPropertyName(targetPropertyName), - targetIsArrayBinding(targetIsArrayBinding), - moveInfo(moveInfo), - propertyOrder(propertyOrder) + const PropertyNameList &propertyOrder) + : QMLRewriter(modifier) + , targetParentObjectLocation(targetParentObjectLocation) + , targetPropertyName(targetPropertyName) + , targetIsArrayBinding(targetIsArrayBinding) + , moveInfo(moveInfo) + , propertyOrder(propertyOrder) {} protected: @@ -124,7 +124,7 @@ private: private: quint32 targetParentObjectLocation; - PropertyName targetPropertyName; + PropertyNameView targetPropertyName; bool targetIsArrayBinding; TextModifier::MoveInfo moveInfo; PropertyNameList propertyOrder; @@ -132,16 +132,16 @@ private: MoveObjectVisitor::MoveObjectVisitor(TextModifier &modifier, quint32 objectLocation, - const PropertyName &targetPropertyName, + PropertyNameView targetPropertyName, bool targetIsArrayBinding, quint32 targetParentObjectLocation, - const PropertyNameList &propertyOrder): - QMLRewriter(modifier), - objectLocation(objectLocation), - targetPropertyName(targetPropertyName), - targetIsArrayBinding(targetIsArrayBinding), - targetParentObjectLocation(targetParentObjectLocation), - propertyOrder(propertyOrder) + const PropertyNameList &propertyOrder) + : QMLRewriter(modifier) + , objectLocation(objectLocation) + , targetPropertyName(targetPropertyName) + , targetIsArrayBinding(targetIsArrayBinding) + , targetParentObjectLocation(targetParentObjectLocation) + , propertyOrder(propertyOrder) { } diff --git a/src/plugins/qmldesigner/designercore/filemanager/moveobjectvisitor.h b/src/plugins/qmldesigner/designercore/filemanager/moveobjectvisitor.h index 53659b748f5..5619261b540 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/moveobjectvisitor.h +++ b/src/plugins/qmldesigner/designercore/filemanager/moveobjectvisitor.h @@ -13,7 +13,7 @@ class MoveObjectVisitor: public QMLRewriter public: MoveObjectVisitor(QmlDesigner::TextModifier &modifier, quint32 objectLocation, - const QmlDesigner::PropertyName &targetPropertyName, + PropertyNameView targetPropertyName, bool targetIsArrayBinding, quint32 targetParentObjectLocation, const PropertyNameList &propertyOrder); @@ -31,7 +31,7 @@ private: private: QList parents; quint32 objectLocation; - PropertyName targetPropertyName; + PropertyNameView targetPropertyName; bool targetIsArrayBinding; quint32 targetParentObjectLocation; PropertyNameList propertyOrder; diff --git a/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.cpp b/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.cpp index 34796d9a4c5..648741293c7 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.cpp +++ b/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.cpp @@ -63,7 +63,9 @@ bool QmlRefactoring::removeImport(const Import &import) return visitor.remove(qmlDocument->qmlProgram(), import); } -bool QmlRefactoring::addToArrayMemberList(int parentLocation, const PropertyName &propertyName, const QString &content) +bool QmlRefactoring::addToArrayMemberList(int parentLocation, + PropertyNameView propertyName, + const QString &content) { if (parentLocation < 0) return false; @@ -83,7 +85,7 @@ bool QmlRefactoring::addToObjectMemberList(int parentLocation, const QString &co } bool QmlRefactoring::addProperty(int parentLocation, - const PropertyName &name, + PropertyNameView name, const QString &value, PropertyType propertyType, const TypeName &dynamicTypeName) @@ -95,7 +97,10 @@ bool QmlRefactoring::addProperty(int parentLocation, return visit(qmlDocument->qmlProgram()); } -bool QmlRefactoring::changeProperty(int parentLocation, const PropertyName &name, const QString &value, PropertyType propertyType) +bool QmlRefactoring::changeProperty(int parentLocation, + PropertyNameView name, + const QString &value, + PropertyType propertyType) { if (parentLocation < 0) return false; @@ -117,7 +122,10 @@ bool QmlRefactoring::changeObjectType(int nodeLocation, const QString &newType) return visit(qmlDocument->qmlProgram()); } -bool QmlRefactoring::moveObject(int objectLocation, const PropertyName &targetPropertyName, bool targetIsArrayBinding, int targetParentObjectLocation) +bool QmlRefactoring::moveObject(int objectLocation, + PropertyNameView targetPropertyName, + bool targetIsArrayBinding, + int targetParentObjectLocation) { if (objectLocation < 0 || targetParentObjectLocation < 0) return false; @@ -150,7 +158,7 @@ bool QmlRefactoring::removeObject(int nodeLocation) return visit(qmlDocument->qmlProgram()); } -bool QmlRefactoring::removeProperty(int parentLocation, const PropertyName &name) +bool QmlRefactoring::removeProperty(int parentLocation, PropertyNameView name) { if (parentLocation < 0 || name.isEmpty()) return false; diff --git a/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.h b/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.h index 9427acffde7..54194ab1360 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.h +++ b/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.h @@ -30,21 +30,27 @@ public: bool addImport(const Import &import); bool removeImport(const Import &import); - bool addToArrayMemberList(int parentLocation, const PropertyName &propertyName, const QString &content); + bool addToArrayMemberList(int parentLocation, PropertyNameView propertyName, const QString &content); bool addToObjectMemberList(int parentLocation, const QString &content); bool addProperty(int parentLocation, - const PropertyName &name, + PropertyNameView name, const QString &value, PropertyType propertyType, const TypeName &dynamicTypeName = TypeName()); - bool changeProperty(int parentLocation, const PropertyName &name, const QString &value, PropertyType propertyType); + bool changeProperty(int parentLocation, + PropertyNameView name, + const QString &value, + PropertyType propertyType); bool changeObjectType(int nodeLocation, const QString &newType); - bool moveObject(int objectLocation, const PropertyName &targetPropertyName, bool targetIsArray, int targetParentObjectLocation); + bool moveObject(int objectLocation, + PropertyNameView targetPropertyName, + bool targetIsArray, + int targetParentObjectLocation); bool moveObjectBeforeObject(int movingObjectLocation, int beforeObjectLocation, bool inDefaultProperty); bool removeObject(int nodeLocation); - bool removeProperty(int parentLocation, const PropertyName &name); + bool removeProperty(int parentLocation, PropertyNameView name); private: QmlJS::Document::Ptr qmlDocument; diff --git a/src/plugins/qmldesigner/designercore/filemanager/qmlrewriter.cpp b/src/plugins/qmldesigner/designercore/filemanager/qmlrewriter.cpp index 20b22ade170..b5b1feb8b6f 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/qmlrewriter.cpp +++ b/src/plugins/qmldesigner/designercore/filemanager/qmlrewriter.cpp @@ -231,9 +231,10 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(QmlJS::AS } // FIXME: duplicate code in the QmlJS::Rewriter class, remove this -QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(QmlJS::AST::UiObjectMemberList *members, - const QmlDesigner::PropertyName &propertyName, - const QmlDesigner::PropertyNameList &propertyOrder) +QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter( + QmlJS::AST::UiObjectMemberList *members, + PropertyNameView propertyName, + const QmlDesigner::PropertyNameList &propertyOrder) { if (!members) return nullptr; // empty members diff --git a/src/plugins/qmldesigner/designercore/filemanager/qmlrewriter.h b/src/plugins/qmldesigner/designercore/filemanager/qmlrewriter.h index fe0b6933ea8..efbc25a0e27 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/qmlrewriter.h +++ b/src/plugins/qmldesigner/designercore/filemanager/qmlrewriter.h @@ -52,7 +52,10 @@ protected: void includeLeadingEmptyLine(int &start) const; static QmlJS::AST::UiObjectMemberList *searchMemberToInsertAfter(QmlJS::AST::UiObjectMemberList *members, const PropertyNameList &propertyOrder); - static QmlJS::AST::UiObjectMemberList *searchMemberToInsertAfter(QmlJS::AST::UiObjectMemberList *members, const QmlDesigner::PropertyName &propertyName, const PropertyNameList &propertyOrder); + static QmlJS::AST::UiObjectMemberList *searchMemberToInsertAfter( + QmlJS::AST::UiObjectMemberList *members, + PropertyNameView propertyName, + const PropertyNameList &propertyOrder); protected: bool didRewriting() const diff --git a/src/plugins/qmldesigner/designercore/include/abstractproperty.h b/src/plugins/qmldesigner/designercore/include/abstractproperty.h index 811be48870f..67a8b0084ee 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractproperty.h +++ b/src/plugins/qmldesigner/designercore/include/abstractproperty.h @@ -3,9 +3,12 @@ #pragma once +#include "qmldesignercorelib_global.h" + +#include + #include #include -#include "qmldesignercorelib_global.h" #include @@ -53,12 +56,12 @@ public: AbstractProperty &operator=(AbstractProperty &&) noexcept = default; ~AbstractProperty(); AbstractProperty(const AbstractProperty &property, AbstractView *view); - AbstractProperty(const PropertyName &propertyName, + AbstractProperty(PropertyNameView propertyName, const Internal::InternalNodePointer &internalNode, Model *model, AbstractView *view); - const PropertyName &name() const; + PropertyNameView name() const & { return m_propertyName; } bool isValid() const; explicit operator bool() const { return isValid(); } @@ -139,7 +142,7 @@ protected: Internal::ModelPrivate *privateModel() const; private: - PropertyName m_propertyName; + Utils::SmallString m_propertyName; Internal::InternalNodePointer m_internalNode; QPointer m_model; QPointer m_view; diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index 450a51afdd0..b5fd8e12433 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -39,7 +39,6 @@ enum DesignerWidgetFlags { }; class WidgetInfo { - public: enum PlacementHint { NoPane, @@ -54,7 +53,6 @@ public: QString tabName; QString feedbackDisplayName; QWidget *widget = nullptr; - int placementPriority; PlacementHint placementHint; DesignerWidgetFlags widgetFlags = DesignerWidgetFlags::DisableOnError; }; @@ -132,9 +130,8 @@ public: void emitDocumentMessage(const QList &errors, const QList &warnings = {}); void emitDocumentMessage(const QString &error); - void emitCustomNotification(const QString &identifier); - void emitCustomNotification(const QString &identifier, const QList &nodeList); - void emitCustomNotification(const QString &identifier, const QList &nodeList, const QList &data); + void emitCustomNotification(const QString &identifier, const QList &nodeList = {}, + const QList &data = {}); void emitInstancePropertyChange(const QList > &propertyList); void emitInstanceErrorChange(const QVector &instanceIds); @@ -148,7 +145,9 @@ public: void emitInstanceToken(const QString &token, int number, const QVector &nodeVector); void emitRenderImage3DChanged(const QImage &image); void emitUpdateActiveScene3D(const QVariantMap &sceneState); - void emitModelNodelPreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap); + void emitModelNodelPreviewPixmapChanged(const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId); void emitImport3DSupportChanged(const QVariantMap &supportMap); void emitNodeAtPosResult(const ModelNode &modelNode, const QVector3D &pos3d); void emitView3DAction(View3DActionType type, const QVariant &value); @@ -227,7 +226,9 @@ public: virtual void updateActiveScene3D(const QVariantMap &sceneState); virtual void updateImport3DSupport(const QVariantMap &supportMap); virtual void nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos3d); - virtual void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap); + virtual void modelNodePreviewPixmapChanged(const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId); virtual void view3DAction(View3DActionType type, const QVariant &value); @@ -293,7 +294,6 @@ protected: QWidget *widget = nullptr, const QString &uniqueId = QString(), WidgetInfo::PlacementHint placementHint = WidgetInfo::NoPane, - int placementPriority = 0, const QString &tabName = QString(), const QString &feedbackDisplayName = QString(), DesignerWidgetFlags widgetFlags = DesignerWidgetFlags::DisableOnError); diff --git a/src/plugins/qmldesigner/designercore/include/auxiliarydataproperties.h b/src/plugins/qmldesigner/designercore/include/auxiliarydataproperties.h index b6bb22290a7..709069d77d4 100644 --- a/src/plugins/qmldesigner/designercore/include/auxiliarydataproperties.h +++ b/src/plugins/qmldesigner/designercore/include/auxiliarydataproperties.h @@ -115,6 +115,8 @@ inline constexpr AuxiliaryDataKeyView bakeLightsManualProperty{AuxiliaryDataType "bakeLightsManual"}; inline constexpr AuxiliaryDataKeyView contextImageProperty{AuxiliaryDataType::Temporary, "contextImage"}; +inline constexpr AuxiliaryDataKeyView formeditorColorProperty{AuxiliaryDataType::Persistent, + "formeditorColor"}; // Most material preview aux properties are duplicated as document and instance types, as they // are both required to be persistent and used at runtime to control material preview rendering diff --git a/src/plugins/qmldesigner/designercore/include/bindingproperty.h b/src/plugins/qmldesigner/designercore/include/bindingproperty.h index 022ae17cf08..a32aee3b2af 100644 --- a/src/plugins/qmldesigner/designercore/include/bindingproperty.h +++ b/src/plugins/qmldesigner/designercore/include/bindingproperty.h @@ -39,10 +39,12 @@ public: static QVariant convertToLiteral(const TypeName &typeName, const QString &expression); - BindingProperty(const PropertyName &propertyName, + BindingProperty(Utils::SmallStringView propertyName, const Internal::InternalNodePointer &internalNode, Model *model, - AbstractView *view); + AbstractView *view) + : AbstractProperty(propertyName, internalNode, model, view) + {} private: ModelNode resolveBinding(const QString &binding, ModelNode currentNode) const; diff --git a/src/plugins/qmldesigner/designercore/include/import.h b/src/plugins/qmldesigner/designercore/include/import.h index cde683a105d..2d75371d761 100644 --- a/src/plugins/qmldesigner/designercore/include/import.h +++ b/src/plugins/qmldesigner/designercore/include/import.h @@ -12,37 +12,9 @@ #include "qmldesignercorelib_global.h" -#include - namespace QmlDesigner { -class Version -{ -public: - friend bool operator==(Version first, Version second) - { - return first.major == second.major && first.minor == second.minor; - } - - friend bool operator<(Version first, Version second) - { - return std::tie(first.major, first.minor) < std::tie(second.major, second.minor); - } - - friend bool operator>(Version first, Version second) { return second < first; } - friend bool operator<=(Version first, Version second) { return !(second < first); } - friend bool operator>=(Version first, Version second) { return !(first < second); } - - bool isEmpty() const - { - return major == std::numeric_limits::max() || minor == std::numeric_limits::max(); - } - -public: - int major = std::numeric_limits::max(); - int minor = std::numeric_limits::max(); -}; - +class Version; class QMLDESIGNERCORE_EXPORT Import { using Imports = QList; diff --git a/src/plugins/qmldesigner/designercore/include/model.h b/src/plugins/qmldesigner/designercore/include/model.h index 39b5cdaa811..98de7bb587f 100644 --- a/src/plugins/qmldesigner/designercore/include/model.h +++ b/src/plugins/qmldesigner/designercore/include/model.h @@ -249,6 +249,7 @@ public: const QList &warnings); QList selectedNodes(AbstractView *view) const; + void setSelectedModelNodes(const QList &selectedNodeList); void clearMetaInfoCache(); diff --git a/src/plugins/qmldesigner/designercore/include/modelfwd.h b/src/plugins/qmldesigner/designercore/include/modelfwd.h index 91c533fe7b6..a168a780560 100644 --- a/src/plugins/qmldesigner/designercore/include/modelfwd.h +++ b/src/plugins/qmldesigner/designercore/include/modelfwd.h @@ -14,39 +14,6 @@ using PropertyName = QByteArray; using PropertyNameView = QByteArrayView; using PropertyNameList = QList; -template -class ByteArrayViewLiteral : public QByteArrayView -{ -public: - constexpr ByteArrayViewLiteral() noexcept - : QByteArrayView{Text, Size - 1} - {} - - const QByteArray &toByteArray() const noexcept - { - static auto b = QByteArray::fromRawData(Text, Size - 1); - - return b; - } - - operator const QByteArray &() const noexcept { return toByteArray(); } -}; - -#define MakeCppPropertyViewLiteral(name, text) \ - constexpr char name##InternalString[] = text; \ - constexpr ByteArrayViewLiteral name{}; \ - /* */ - -#define MakeHeaderPropertyViewLiteral(name, text) \ - inline constexpr char name##InternalString[] = text; \ - inline constexpr ByteArrayViewLiteral name{}; \ - /* */ - -#define MakeFunctionPropertyViewLiteral(name, text) \ - static constexpr char name##InternalString[] = text; \ - static constexpr ByteArrayViewLiteral name{}; \ - /* */ - using TypeName = QByteArray; using TypeNameView = QByteArrayView; using PropertyTypeList = QList; diff --git a/src/plugins/qmldesigner/designercore/include/modelnode.h b/src/plugins/qmldesigner/designercore/include/modelnode.h index 0517599f5be..b0e5eeb7308 100644 --- a/src/plugins/qmldesigner/designercore/include/modelnode.h +++ b/src/plugins/qmldesigner/designercore/include/modelnode.h @@ -110,14 +110,14 @@ public: //### - AbstractProperty property(const PropertyName &name) const; - VariantProperty variantProperty(const PropertyName &name) const; - BindingProperty bindingProperty(const PropertyName &name) const; - SignalHandlerProperty signalHandlerProperty(const PropertyName &name) const; - SignalDeclarationProperty signalDeclarationProperty(const PropertyName &name) const; - NodeListProperty nodeListProperty(const PropertyName &name) const; - NodeProperty nodeProperty(const PropertyName &name) const; - NodeAbstractProperty nodeAbstractProperty(const PropertyName &name) const; + AbstractProperty property(PropertyNameView name) const; + VariantProperty variantProperty(PropertyNameView name) const; + BindingProperty bindingProperty(PropertyNameView name) const; + SignalHandlerProperty signalHandlerProperty(PropertyNameView name) const; + SignalDeclarationProperty signalDeclarationProperty(PropertyNameView name) const; + NodeListProperty nodeListProperty(PropertyNameView name) const; + NodeProperty nodeProperty(PropertyNameView name) const; + NodeAbstractProperty nodeAbstractProperty(PropertyNameView name) const; NodeAbstractProperty defaultNodeAbstractProperty() const; NodeListProperty defaultNodeListProperty() const; NodeProperty defaultNodeProperty() const; @@ -152,9 +152,10 @@ public: void destroy(); QString id() const; - QString validId(); - void setIdWithRefactoring(const QString &id); - void setIdWithoutRefactoring(const QString &id); + void ensureIdExists() const; + [[nodiscard]] QString validId() const; + void setIdWithRefactoring(const QString &id) const; + void setIdWithoutRefactoring(const QString &id) const; static bool isValidId(const QString &id); static QString getIdValidityErrorMessage(const QString &id); @@ -191,6 +192,7 @@ public: void removeAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name) const; bool hasAuxiliaryData(AuxiliaryDataKeyView key) const; bool hasAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView name) const; + bool hasAuxiliaryData(AuxiliaryDataType type) const; AuxiliaryDatasForType auxiliaryData(AuxiliaryDataType type) const; AuxiliaryDatasView auxiliaryData() const; diff --git a/src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h b/src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h index a0ff96b0d58..1790810f8b9 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h +++ b/src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h @@ -35,10 +35,12 @@ public: friend auto qHash(const NodeAbstractProperty &property) { qHash(AbstractProperty(property)); } - NodeAbstractProperty(const PropertyName &propertyName, + NodeAbstractProperty(PropertyNameView propertyName, const Internal::InternalNodePointer &internalNode, Model *model, - AbstractView *view); + AbstractView *view) + : AbstractProperty(propertyName, internalNode, model, view) + {} protected: NodeAbstractProperty(const Internal::InternalNodeAbstractPropertyPointer &property, Model *model, AbstractView *view); diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstance.h b/src/plugins/qmldesigner/designercore/include/nodeinstance.h index a6f8f9a27d5..9e35aca428b 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstance.h +++ b/src/plugins/qmldesigner/designercore/include/nodeinstance.h @@ -51,12 +51,12 @@ public: QPixmap renderPixmap() const; QPixmap blurredRenderPixmap() const; - QVariant property(const PropertyName &name) const; - bool hasProperty(const PropertyName &name) const; - bool hasBindingForProperty(const PropertyName &name) const; - QPair anchor(const PropertyName &name) const; - bool hasAnchor(const PropertyName &name) const; - TypeName instanceType(const PropertyName &name) const; + QVariant property(PropertyNameView name) const; + bool hasProperty(PropertyNameView name) const; + bool hasBindingForProperty(PropertyNameView name) const; + QPair anchor(PropertyNameView name) const; + bool hasAnchor(PropertyNameView name) const; + TypeName instanceType(PropertyNameView name) const; qint32 parentId() const; qint32 instanceId() const; @@ -72,7 +72,7 @@ public: QStringList allStateNames() const; protected: - void setProperty(const PropertyName &name, const QVariant &value); + void setProperty(PropertyNameView name, const QVariant &value); InformationName setInformation(InformationName name, const QVariant &information, const QVariant &secondInformation, @@ -94,10 +94,13 @@ protected: InformationName setInformationIsAnchoredByChildren(bool isAnchoredByChildren); InformationName setInformationIsAnchoredBySibling(bool isAnchoredBySibling); InformationName setInformationHasContent(bool hasContent); - InformationName setInformationHasAnchor(const PropertyName &sourceAnchorLine, bool hasAnchor); - InformationName setInformationAnchor(const PropertyName &sourceAnchorLine, const PropertyName &targetAnchorLine, qint32 targetInstanceId); - InformationName setInformationInstanceTypeForProperty(const PropertyName &property, const TypeName &type); - InformationName setInformationHasBindingForProperty(const PropertyName &property, bool hasProperty); + InformationName setInformationHasAnchor(PropertyNameView sourceAnchorLine, bool hasAnchor); + InformationName setInformationAnchor(PropertyNameView sourceAnchorLine, + const PropertyName &targetAnchorLine, + qint32 targetInstanceId); + InformationName setInformationInstanceTypeForProperty(PropertyNameView property, + const TypeName &type); + InformationName setInformationHasBindingForProperty(PropertyNameView, bool hasProperty); InformationName setAllStates(const QStringList &states); void setParentId(qint32 instanceId); diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h index 80727bf5a9e..24e2a9258e2 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h @@ -134,13 +134,18 @@ public: void sendInputEvent(QEvent *e) const; void view3DAction(View3DActionType type, const QVariant &value) override; - void requestModelNodePreviewImage(const ModelNode &node, const ModelNode &renderNode) const; + void requestModelNodePreviewImage(const ModelNode &node, + const ModelNode &renderNode, + const QSize &size = {}, + const QByteArray &requestId = {}) const; void edit3DViewResized(const QSize &size) const; void handlePuppetToCreatorCommand(const PuppetToCreatorCommand &command) override; QVariant previewImageDataForGenericNode(const ModelNode &modelNode, - const ModelNode &renderNode) const; + const ModelNode &renderNode, + const QSize &size = {}, + const QByteArray &requestId = {}) const; QVariant previewImageDataForImageNode(const ModelNode &modelNode) const; void setCrashCallback(std::function crashCallback) @@ -226,14 +231,17 @@ private: // functions QString info; }; QVariant modelNodePreviewImageDataToVariant(const ModelNodePreviewImageData &imageData) const; - void updatePreviewImageForNode(const ModelNode &modelNode, const QImage &image); + void updatePreviewImageForNode(const ModelNode &modelNode, + const QImage &image, + const QByteArray &requestId); void updateWatcher(const QString &path); void handleShaderChanges(); void handleQsbProcessExit(Utils::Process *qsbProcess, const QString &shader); void updateQsbPathToFilterMap(); void updateRotationBlocks(); - void maybeResetOnPropertyChange(const PropertyName &name, const ModelNode &node, + void maybeResetOnPropertyChange(PropertyNameView name, + const ModelNode &node, PropertyChangeFlags flags); private: @@ -254,6 +262,8 @@ private: QList loadInstancesFromCache(const QList &nodeList, const NodeInstanceCacheData &cache); + QString fullyQualifyPropertyIfApplies(const BindingProperty &property) const; + mutable QHash m_imageDataMap; NodeInstance m_rootNodeInstance; diff --git a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h b/src/plugins/qmldesigner/designercore/include/nodelistproperty.h index 2f7a4423f09..d056957adcb 100644 --- a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h +++ b/src/plugins/qmldesigner/designercore/include/nodelistproperty.h @@ -166,10 +166,13 @@ public: using reference = ModelNode; NodeListProperty(); - NodeListProperty(const PropertyName &propertyName, + + NodeListProperty(PropertyNameView propertyName, const Internal::InternalNodePointer &internalNode, Model *model, - AbstractView *view); + AbstractView *view) + : NodeAbstractProperty(propertyName, internalNode, model, view) + {} QList toModelNodeList() const; QList toQmlObjectNodeList() const; void slide(int, int) const; diff --git a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h index fd3f2f9be8d..ceb5fe8eff2 100644 --- a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h +++ b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h @@ -75,8 +75,6 @@ public: MetaInfoType type() const; bool isFileComponent() const; - bool isProjectComponent() const; - bool isInProjectModule() const; FlagIs canBeContainer() const; FlagIs forceClip() const; FlagIs doesLayoutChildren() const; @@ -94,7 +92,7 @@ public: bool hasProperty(::Utils::SmallStringView propertyName) const; PropertyMetaInfos properties() const; PropertyMetaInfos localProperties() const; - PropertyMetaInfo property(const PropertyName &propertyName) const; + PropertyMetaInfo property(PropertyNameView propertyName) const; PropertyNameList signalNames() const; PropertyNameList slotNames() const; PropertyName defaultPropertyName() const; diff --git a/src/plugins/qmldesigner/designercore/include/nodeproperty.h b/src/plugins/qmldesigner/designercore/include/nodeproperty.h index c0c266c6f3d..b9afe1d4188 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeproperty.h +++ b/src/plugins/qmldesigner/designercore/include/nodeproperty.h @@ -24,10 +24,13 @@ public: void setDynamicTypeNameAndsetModelNode(const TypeName &typeName, const ModelNode &modelNode); NodeProperty(); - NodeProperty(const PropertyName &propertyName, + + NodeProperty(PropertyNameView propertyName, const Internal::InternalNodePointer &internalNode, Model *model, - AbstractView *view); + AbstractView *view) + : NodeAbstractProperty(propertyName, internalNode, model, view) + {} }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/projectstorageids.h b/src/plugins/qmldesigner/designercore/include/projectstorageids.h index 7c2e8c4b252..6a8c5b95a87 100644 --- a/src/plugins/qmldesigner/designercore/include/projectstorageids.h +++ b/src/plugins/qmldesigner/designercore/include/projectstorageids.h @@ -15,7 +15,7 @@ enum class BasicIdType { Type, PropertyType, PropertyDeclaration, - Source, + SourceName, SourceContext, StorageCacheIndex, FunctionDeclaration, @@ -51,10 +51,10 @@ using SourceContextIds = std::vector; template using SmallSourceContextIds = QVarLengthArray; -using SourceId = Sqlite::BasicId; -using SourceIds = std::vector; +using SourceNameId = Sqlite::BasicId; +using SourceNameIds = std::vector; template -using SmallSourceIds = QVarLengthArray; +using SmallSourceNameIds = QVarLengthArray; using ModuleId = Sqlite::BasicId; using ModuleIds = std::vector; @@ -75,4 +75,9 @@ using ExportedTypeNameIds = std::vector; using ModuleExportedImportId = Sqlite::BasicId; using ModuleExportedImportIds = std::vector; +using SourceId = Sqlite::CompoundBasicId; +using SourceIds = std::vector; +template +using SmallSourceIds = QVarLengthArray; + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/propertymetainfo.h b/src/plugins/qmldesigner/designercore/include/propertymetainfo.h index 42429d1480d..4221d5eb8d7 100644 --- a/src/plugins/qmldesigner/designercore/include/propertymetainfo.h +++ b/src/plugins/qmldesigner/designercore/include/propertymetainfo.h @@ -9,6 +9,8 @@ #include #include +#include + #include #include @@ -25,7 +27,8 @@ class QMLDESIGNERCORE_EXPORT PropertyMetaInfo public: PropertyMetaInfo(); PropertyMetaInfo(std::shared_ptr nodeMetaInfoPrivateData, - const PropertyName &propertyName); + PropertyNameView propertyName); + PropertyMetaInfo([[maybe_unused]] PropertyDeclarationId id, [[maybe_unused]] NotNullPointer projectStorage) #ifdef QDS_USE_PROJECTSTORAGE diff --git a/src/plugins/qmldesigner/designercore/include/qml3dnode.h b/src/plugins/qmldesigner/designercore/include/qml3dnode.h index 280691c7a9f..7dbabac046a 100644 --- a/src/plugins/qmldesigner/designercore/include/qml3dnode.h +++ b/src/plugins/qmldesigner/designercore/include/qml3dnode.h @@ -30,8 +30,8 @@ public: static bool isValidQml3DNode(const ModelNode &modelNode); static bool isValidVisualRoot(const ModelNode &modelNode); - bool handleEulerRotation(const PropertyName &name); - bool isBlocked(const PropertyName &propName) const; + bool handleEulerRotation(PropertyNameView name); + bool isBlocked(PropertyNameView propName) const; friend auto qHash(const Qml3DNode &node) { return qHash(node.modelNode()); } diff --git a/src/plugins/qmldesigner/designercore/include/qmlchangeset.h b/src/plugins/qmldesigner/designercore/include/qmlchangeset.h index 67d7a910840..bc2043809f4 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlchangeset.h +++ b/src/plugins/qmldesigner/designercore/include/qmlchangeset.h @@ -34,7 +34,7 @@ public: bool isValid() const; explicit operator bool() const { return isValid(); } static bool isValidQmlPropertyChanges(const ModelNode &modelNode); - void removeProperty(const PropertyName &name); + void removeProperty(PropertyNameView name); }; } //QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h index e11f201cdb2..c2ac5579900 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h @@ -214,7 +214,7 @@ public: static const PropertyNameList &mouseSignals() { return s_mouseSignals; } protected: - QList transitionsForProperty(const PropertyName &propertyName, const ModelNode &modelNode); + QList transitionsForProperty(PropertyNameView propertyName, const ModelNode &modelNode); private: static PropertyNameList s_mouseSignals; diff --git a/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h b/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h index a4fa1ab8ed8..71adf56e69d 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h @@ -51,26 +51,26 @@ public: QmlModelState currentState() const; QmlTimeline currentTimeline() const; - void setVariantProperty(const PropertyName &name, const QVariant &value); - void setBindingProperty(const PropertyName &name, const QString &expression); - NodeAbstractProperty nodeAbstractProperty(const PropertyName &name) const; + void setVariantProperty(PropertyNameView name, const QVariant &value); + void setBindingProperty(PropertyNameView name, const QString &expression); + NodeAbstractProperty nodeAbstractProperty(PropertyNameView name) const; NodeAbstractProperty defaultNodeAbstractProperty() const; - NodeProperty nodeProperty(const PropertyName &name) const; - NodeListProperty nodeListProperty(const PropertyName &name) const; + NodeProperty nodeProperty(PropertyNameView name) const; + NodeListProperty nodeListProperty(PropertyNameView name) const; - bool instanceHasValue(const PropertyName &name) const; - QVariant instanceValue(const PropertyName &name) const; - TypeName instanceType(const PropertyName &name) const; + bool instanceHasValue(PropertyNameView name) const; + QVariant instanceValue(PropertyNameView name) const; + TypeName instanceType(PropertyNameView name) const; - bool hasProperty(const PropertyName &name) const; - bool hasBindingProperty(const PropertyName &name) const; - bool instanceHasBinding(const PropertyName &name) const; - bool propertyAffectedByCurrentState(const PropertyName &name) const; - QVariant modelValue(const PropertyName &name) const; - bool isTranslatableText(const PropertyName &name) const; - QString stripedTranslatableText(const PropertyName &name) const; - BindingProperty bindingProperty(const PropertyName &name) const; - QString expression(const PropertyName &name) const; + bool hasProperty(PropertyNameView name) const; + bool hasBindingProperty(PropertyNameView name) const; + bool instanceHasBinding(PropertyNameView name) const; + bool propertyAffectedByCurrentState(PropertyNameView name) const; + QVariant modelValue(PropertyNameView name) const; + bool isTranslatableText(PropertyNameView name) const; + QString stripedTranslatableText(PropertyNameView name) const; + BindingProperty bindingProperty(PropertyNameView name) const; + QString expression(PropertyNameView name) const; bool isInBaseState() const; bool timelineIsActive() const; QmlPropertyChanges propertyChangeForCurrentState() const; @@ -87,7 +87,7 @@ public: QList allAffectingStates() const; QList allAffectingStatesOperations() const; - void removeProperty(const PropertyName &name); + void removeProperty(PropertyNameView name); void setParent(const QmlObjectNode &newParent); @@ -99,7 +99,7 @@ public: bool hasDefaultPropertyName() const; PropertyName defaultPropertyName() const; - static QVariant instanceValue(const ModelNode &modelNode, const PropertyName &name); + static QVariant instanceValue(const ModelNode &modelNode, PropertyNameView name); static QString generateTranslatableText(const QString &text, const DesignerSettings &designerSettings); diff --git a/src/plugins/qmldesigner/designercore/include/qmltimeline.h b/src/plugins/qmldesigner/designercore/include/qmltimeline.h index 7a2809f5287..2cad8d2b901 100644 --- a/src/plugins/qmldesigner/designercore/include/qmltimeline.h +++ b/src/plugins/qmldesigner/designercore/include/qmltimeline.h @@ -25,8 +25,8 @@ public: static bool isValidQmlTimeline(const ModelNode &modelNode); void destroy(); - QmlTimelineKeyframeGroup keyframeGroup(const ModelNode &modelNode, const PropertyName &propertyName); - bool hasTimeline(const ModelNode &modelNode, const PropertyName &propertyName); + QmlTimelineKeyframeGroup keyframeGroup(const ModelNode &modelNode, PropertyNameView propertyName); + bool hasTimeline(const ModelNode &modelNode, PropertyNameView propertyName); qreal startKeyframe() const; qreal endKeyframe() const; @@ -45,8 +45,7 @@ public: QList keyframeGroupsForTarget(const ModelNode &target) const; void destroyKeyframesForTarget(const ModelNode &target); - void removeKeyframesForTargetAndProperty(const ModelNode &target, - const PropertyName &propertyName); + void removeKeyframesForTargetAndProperty(const ModelNode &target, PropertyNameView propertyName); static bool hasActiveTimeline(AbstractView *view); @@ -54,13 +53,13 @@ public: void toogleRecording(bool b) const; void resetGroupRecording() const; - bool hasKeyframeGroup(const ModelNode &node, const PropertyName &propertyName) const; + bool hasKeyframeGroup(const ModelNode &node, PropertyNameView propertyName) const; bool hasKeyframeGroupForTarget(const ModelNode &node) const; - void insertKeyframe(const ModelNode &target, const PropertyName &propertyName); + void insertKeyframe(const ModelNode &target, PropertyNameView propertyName); private: - void addKeyframeGroupIfNotExists(const ModelNode &node, const PropertyName &propertyName); + void addKeyframeGroupIfNotExists(const ModelNode &node, PropertyNameView propertyName); QList allKeyframeGroups() const; }; diff --git a/src/plugins/qmldesigner/designercore/include/qmltimelinekeyframegroup.h b/src/plugins/qmldesigner/designercore/include/qmltimelinekeyframegroup.h index a319c5ac319..632ea93f212 100644 --- a/src/plugins/qmldesigner/designercore/include/qmltimelinekeyframegroup.h +++ b/src/plugins/qmldesigner/designercore/include/qmltimelinekeyframegroup.h @@ -28,7 +28,7 @@ public: void setTarget(const ModelNode &target); PropertyName propertyName() const; - void setPropertyName(const PropertyName &propertyName); + void setPropertyName(PropertyNameView propertyName); void setValue(const QVariant &value, qreal frame); QVariant value(qreal frame) const; diff --git a/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h b/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h index a299d379bcd..f155f4f4687 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h @@ -100,7 +100,7 @@ public: bool isFlowWildcard() const; private: - void setDoubleProperty(const PropertyName &name, double value); + void setDoubleProperty(PropertyNameView name, double value); }; class QMLDESIGNERCORE_EXPORT QmlModelStateGroup diff --git a/src/plugins/qmldesigner/designercore/rewritertransaction.h b/src/plugins/qmldesigner/designercore/include/rewritertransaction.h similarity index 100% rename from src/plugins/qmldesigner/designercore/rewritertransaction.h rename to src/plugins/qmldesigner/designercore/include/rewritertransaction.h diff --git a/src/plugins/qmldesigner/designercore/include/rewriterview.h b/src/plugins/qmldesigner/designercore/include/rewriterview.h index 92c79c78631..46e67116634 100644 --- a/src/plugins/qmldesigner/designercore/include/rewriterview.h +++ b/src/plugins/qmldesigner/designercore/include/rewriterview.h @@ -90,8 +90,8 @@ public: void setTextModifier(TextModifier *textModifier); QString textModifierContent() const; - void reactivateTextMofifierChangeSignals(); - void deactivateTextMofifierChangeSignals(); + void reactivateTextModifierChangeSignals(); + void deactivateTextModifierChangeSignals(); void auxiliaryDataChanged(const ModelNode &node, AuxiliaryDataKeyView key, @@ -196,7 +196,7 @@ private: //variables void handleProjectUpdate(); bool inErrorState() const { return !m_rewritingErrorMessage.isEmpty(); } - TextModifier *m_textModifier = nullptr; + QPointer m_textModifier; int transactionLevel = 0; bool m_modificationGroupActive = false; bool m_checkSemanticErrors = true; diff --git a/src/plugins/qmldesigner/designercore/include/signalhandlerproperty.h b/src/plugins/qmldesigner/designercore/include/signalhandlerproperty.h index 671e61c9823..1d43aa9e6bc 100644 --- a/src/plugins/qmldesigner/designercore/include/signalhandlerproperty.h +++ b/src/plugins/qmldesigner/designercore/include/signalhandlerproperty.h @@ -21,10 +21,15 @@ public: SignalHandlerProperty(); SignalHandlerProperty(const SignalHandlerProperty &property, AbstractView *view); - static PropertyName prefixAdded(const PropertyName &propertyName); - static PropertyName prefixRemoved(const PropertyName &propertyName); + static PropertyName prefixAdded(PropertyNameView propertyName); + static PropertyName prefixRemoved(PropertyNameView propertyName); - SignalHandlerProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view); + SignalHandlerProperty(PropertyNameView propertyName, + const Internal::InternalNodePointer &internalNode, + Model *model, + AbstractView *view) + : AbstractProperty(propertyName, internalNode, model, view) + {} }; class QMLDESIGNERCORE_EXPORT SignalDeclarationProperty final : public AbstractProperty @@ -39,7 +44,13 @@ public: SignalDeclarationProperty(); SignalDeclarationProperty(const SignalDeclarationProperty &property, AbstractView *view); - SignalDeclarationProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view); + + SignalDeclarationProperty(PropertyNameView propertyName, + const Internal::InternalNodePointer &internalNode, + Model *model, + AbstractView *view) + : AbstractProperty(propertyName, internalNode, model, view) + {} }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/variantproperty.h b/src/plugins/qmldesigner/designercore/include/variantproperty.h index dfa6073ff01..ab531912cc8 100644 --- a/src/plugins/qmldesigner/designercore/include/variantproperty.h +++ b/src/plugins/qmldesigner/designercore/include/variantproperty.h @@ -37,7 +37,13 @@ public: VariantProperty(); VariantProperty(const VariantProperty &property, AbstractView *view); - VariantProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view); + + VariantProperty(PropertyNameView propertyName, + const Internal::InternalNodePointer &internalNode, + Model *model, + AbstractView *view) + : AbstractProperty(propertyName, internalNode, model, view) + {} }; QMLDESIGNERCORE_EXPORT QTextStream& operator<<(QTextStream &stream, const VariantProperty &property); diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp index 414a05683e3..2290ce5e0d9 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp @@ -43,18 +43,17 @@ public: bool isInLayoutable{false}; bool directUpdates{false}; - - QHash propertyValues; - QHash hasBindingForProperty; - QHash hasAnchors; - QHash instanceTypes; + std::map> propertyValues; + std::map> hasBindingForProperty; + std::map> hasAnchors; + std::map> instanceTypes; QPixmap renderPixmap; QPixmap blurredRenderPixmap; QString errorMessage; - QHash > anchors; + std::map, std::less<>> anchors; QStringList allStates; }; @@ -285,17 +284,32 @@ int NodeInstance::penWidth() const return 1; } -QVariant NodeInstance::property(const PropertyName &name) const +namespace { + +template +auto value(const std::map &dict, + PropertyNameView key, + typename std::map::mapped_type defaultValue = {}) +{ + if (auto found = dict.find(key); found != dict.end()) + return found->second; + + return defaultValue; +} + +} // namespace + +QVariant NodeInstance::property(PropertyNameView name) const { if (isValid()) { - if (d->propertyValues.contains(name)) { - return d->propertyValues.value(name); + if (auto found = d->propertyValues.find(name); found != d->propertyValues.end()) { + return found->second; } else { // Query may be for a subproperty, e.g. scale.x - const int index = name.indexOf('.'); + const auto index = name.indexOf('.'); if (index != -1) { - PropertyName parentPropName = name.left(index); - QVariant varValue = d->propertyValues.value(parentPropName); + PropertyNameView parentPropName = name.left(index); + QVariant varValue = value(d->propertyValues, parentPropName); if (varValue.typeId() == QVariant::Vector2D) { auto value = varValue.value(); char subProp = name.right(1)[0]; @@ -361,7 +375,7 @@ QVariant NodeInstance::property(const PropertyName &name) const return QVariant(); } -bool NodeInstance::hasProperty(const PropertyName &name) const +bool NodeInstance::hasProperty(PropertyNameView name) const { if (isValid()) return d->propertyValues.contains(name); @@ -369,18 +383,18 @@ bool NodeInstance::hasProperty(const PropertyName &name) const return false; } -bool NodeInstance::hasBindingForProperty(const PropertyName &name) const +bool NodeInstance::hasBindingForProperty(PropertyNameView name) const { if (isValid()) - return d->hasBindingForProperty.value(name, false); + return value(d->hasBindingForProperty, name, false); return false; } -TypeName NodeInstance::instanceType(const PropertyName &name) const +TypeName NodeInstance::instanceType(PropertyNameView name) const { if (isValid()) - return d->instanceTypes.value(name); + return value(d->instanceTypes, name); return TypeName(); } @@ -393,28 +407,28 @@ qint32 NodeInstance::parentId() const return false; } -bool NodeInstance::hasAnchor(const PropertyName &name) const +bool NodeInstance::hasAnchor(PropertyNameView name) const { if (isValid()) - return d->hasAnchors.value(name, false); + return value(d->hasAnchors, name, false); return false; } -QPair NodeInstance::anchor(const PropertyName &name) const +QPair NodeInstance::anchor(PropertyNameView name) const { if (isValid()) - return d->anchors.value(name, QPair(PropertyName(), qint32(-1))); + return value(d->anchors, name, QPair(PropertyName(), qint32(-1))); return QPair(PropertyName(), -1); } -void NodeInstance::setProperty(const PropertyName &name, const QVariant &value) +void NodeInstance::setProperty(PropertyNameView name, const QVariant &value) { - const int index = name.indexOf('.'); + const auto index = name.indexOf('.'); if (index != -1) { - PropertyName parentPropName = name.left(index); - QVariant oldValue = d->propertyValues.value(parentPropName); + PropertyNameView parentPropName = name.left(index); + QVariant oldValue = QmlDesigner::value(d->propertyValues, parentPropName); QVariant newValueVar; bool update = false; if (oldValue.typeId() == QVariant::Vector2D) { @@ -464,12 +478,12 @@ void NodeInstance::setProperty(const PropertyName &name, const QVariant &value) newValueVar = newValue; } if (update) { - d->propertyValues.insert(parentPropName, newValueVar); + d->propertyValues.emplace(parentPropName, newValueVar); return; } } - d->propertyValues.insert(name, value); + d->propertyValues.emplace(name, value); } QPixmap NodeInstance::renderPixmap() const @@ -671,41 +685,50 @@ InformationName NodeInstance::setInformationHasContent(bool hasContent) return NoInformationChange; } -InformationName NodeInstance::setInformationHasAnchor(const PropertyName &sourceAnchorLine, bool hasAnchor) +InformationName NodeInstance::setInformationHasAnchor(PropertyNameView sourceAnchorLine, bool hasAnchor) { - if (d->hasAnchors.value(sourceAnchorLine) != hasAnchor) { - d->hasAnchors.insert(sourceAnchorLine, hasAnchor); + if (auto found = d->hasAnchors.find(sourceAnchorLine); + found == d->hasAnchors.end() || found->second != hasAnchor) { + d->hasAnchors.emplace_hint(found, sourceAnchorLine, hasAnchor); return HasAnchor; } return NoInformationChange; } -InformationName NodeInstance::setInformationAnchor(const PropertyName &sourceAnchorLine, const PropertyName &targetAnchorLine, qint32 targetInstanceId) +InformationName NodeInstance::setInformationAnchor(PropertyNameView sourceAnchorLine, + const PropertyName &targetAnchorLine, + qint32 targetInstanceId) { - QPair anchorPair = QPair(targetAnchorLine, targetInstanceId); - if (d->anchors.value(sourceAnchorLine) != anchorPair) { - d->anchors.insert(sourceAnchorLine, anchorPair); + std::pair anchorPair = std::pair(targetAnchorLine, + targetInstanceId); + if (auto found = d->anchors.find(sourceAnchorLine); + found == d->anchors.end() || found->second != anchorPair) { + d->anchors.emplace_hint(found, sourceAnchorLine, anchorPair); return Anchor; } return NoInformationChange; } -InformationName NodeInstance::setInformationInstanceTypeForProperty(const PropertyName &property, const TypeName &type) +InformationName NodeInstance::setInformationInstanceTypeForProperty(PropertyNameView property, + const TypeName &type) { - if (d->instanceTypes.value(property) != type) { - d->instanceTypes.insert(property, type); + if (auto found = d->instanceTypes.find(property); + found == d->instanceTypes.end() || found->second != type) { + d->instanceTypes.emplace_hint(found, property, type); return InstanceTypeForProperty; } return NoInformationChange; } -InformationName NodeInstance::setInformationHasBindingForProperty(const PropertyName &property, bool hasProperty) +InformationName NodeInstance::setInformationHasBindingForProperty(PropertyNameView property, + bool hasProperty) { - if (d->hasBindingForProperty.value(property) != hasProperty) { - d->hasBindingForProperty.insert(property, hasProperty); + if (auto found = d->hasBindingForProperty.find(property); + found == d->hasBindingForProperty.end() || found->second != hasProperty) { + d->hasBindingForProperty.emplace_hint(found, property, hasProperty); return HasBindingForProperty; } diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index 0296af2e0e3..d965b9ae177 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include @@ -470,7 +470,7 @@ void NodeInstanceView::propertiesAboutToBeRemoved(const QList& m_nodeInstanceServer->removeProperties(createRemovePropertiesCommand(nonNodePropertyList)); for (const AbstractProperty &property : propertyList) { - const PropertyName &name = property.name(); + const PropertyNameView name = property.name(); if (name == "anchors.fill") { resetHorizontalAnchors(property.parentModelNode()); resetVerticalAnchors(property.parentModelNode()); @@ -602,7 +602,7 @@ void NodeInstanceView::nodeOrderChanged(const NodeListProperty &listProperty) { QTC_ASSERT(m_nodeInstanceServer, return); QVector containerList; - PropertyName propertyName = listProperty.name(); + PropertyNameView propertyName = listProperty.name(); qint32 containerInstanceId = -1; ModelNode containerNode = listProperty.parentModelNode(); if (hasInstanceForModelNode(containerNode)) @@ -613,7 +613,11 @@ void NodeInstanceView::nodeOrderChanged(const NodeListProperty &listProperty) qint32 instanceId = -1; if (hasInstanceForModelNode(node)) { instanceId = instanceForModelNode(node).instanceId(); - ReparentContainer container(instanceId, containerInstanceId, propertyName, containerInstanceId, propertyName); + ReparentContainer container(instanceId, + containerInstanceId, + propertyName.toByteArray(), + containerInstanceId, + propertyName.toByteArray()); containerList.append(container); } } @@ -1135,7 +1139,11 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand() for (const NodeInstance &instance : std::as_const(instanceList)) { if (instance.modelNode().hasParentProperty()) { NodeAbstractProperty parentProperty = instance.modelNode().parentProperty(); - ReparentContainer container(instance.instanceId(), -1, PropertyName(), instanceForModelNode(parentProperty.parentModelNode()).instanceId(), parentProperty.name()); + ReparentContainer container(instance.instanceId(), + -1, + PropertyName(), + instanceForModelNode(parentProperty.parentModelNode()).instanceId(), + parentProperty.name().toByteArray()); reparentContainerList.append(container); } } @@ -1164,7 +1172,12 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand() ModelNode node = property.parentModelNode(); if (node.isValid() && hasInstanceForModelNode(node)) { NodeInstance instance = instanceForModelNode(node); - PropertyBindingContainer container(instance.instanceId(), property.name(), property.expression(), property.dynamicTypeName()); + const QString expression = fullyQualifyPropertyIfApplies(property); + + PropertyBindingContainer container(instance.instanceId(), + property.name().toByteArray(), + expression, + property.dynamicTypeName()); bindingContainerList.append(container); } } @@ -1307,7 +1320,11 @@ ReparentInstancesCommand NodeInstanceView::createReparentInstancesCommand(const for (const NodeInstance &instance : instanceList) { if (instance.modelNode().hasParentProperty()) { NodeAbstractProperty parentProperty = instance.modelNode().parentProperty(); - ReparentContainer container(instance.instanceId(), -1, PropertyName(), instanceForModelNode(parentProperty.parentModelNode()).instanceId(), parentProperty.name()); + ReparentContainer container(instance.instanceId(), + -1, + PropertyName(), + instanceForModelNode(parentProperty.parentModelNode()).instanceId(), + parentProperty.name().toByteArray()); containerList.append(container); } } @@ -1329,8 +1346,11 @@ ReparentInstancesCommand NodeInstanceView::createReparentInstancesCommand(const if (oldPropertyParent.isValid() && hasInstanceForModelNode(oldPropertyParent.parentModelNode())) oldParentInstanceId = instanceForModelNode(oldPropertyParent.parentModelNode()).instanceId(); - - ReparentContainer container(instanceForModelNode(node).instanceId(), oldParentInstanceId, oldPropertyParent.name(), newParentInstanceId, newPropertyParent.name()); + ReparentContainer container(instanceForModelNode(node).instanceId(), + oldParentInstanceId, + oldPropertyParent.name().toByteArray(), + newParentInstanceId, + newPropertyParent.name().toByteArray()); containerList.append(container); @@ -1373,7 +1393,11 @@ ChangeBindingsCommand NodeInstanceView::createChangeBindingCommand(const QListrequestModelNodePreviewImage( - RequestModelNodePreviewImageCommand(instance.instanceId(), QSize(dim, dim), - componentPath, renderItemId)); + + if (size.isValid()) { + imageSize = size * ratio; + } else { + const int dim = Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * ratio; + imageSize = {dim, dim}; + } + + m_nodeInstanceServer->requestModelNodePreviewImage(RequestModelNodePreviewImageCommand( + instance.instanceId(), imageSize, componentPath, renderItemId, requestId)); } } } @@ -1994,7 +2027,9 @@ void NodeInstanceView::endNanotrace() } QVariant NodeInstanceView::previewImageDataForGenericNode(const ModelNode &modelNode, - const ModelNode &renderNode) const + const ModelNode &renderNode, + const QSize &size, + const QByteArray &requestId) const { if (!modelNode.isValid()) return {}; @@ -2009,19 +2044,25 @@ QVariant NodeInstanceView::previewImageDataForGenericNode(const ModelNode &model } else { imageData.type = QString::fromLatin1(createQualifiedTypeName(modelNode)); imageData.id = id; - m_imageDataMap.insert(id, imageData); + + // There might be multiple requests for different preview pixmap sizes. + // Here only the one with no request id is stored. + if (requestId.isEmpty()) + m_imageDataMap.insert(id, imageData); } - requestModelNodePreviewImage(modelNode, renderNode); + requestModelNodePreviewImage(modelNode, renderNode, size, requestId); return modelNodePreviewImageDataToVariant(imageData); } -void NodeInstanceView::updatePreviewImageForNode(const ModelNode &modelNode, const QImage &image) +void NodeInstanceView::updatePreviewImageForNode(const ModelNode &modelNode, + const QImage &image, + const QByteArray &requestId) { QPixmap pixmap = QPixmap::fromImage(image); if (m_imageDataMap.contains(modelNode.id())) m_imageDataMap[modelNode.id()].pixmap = pixmap; - emitModelNodelPreviewPixmapChanged(modelNode, pixmap); + emitModelNodelPreviewPixmapChanged(modelNode, pixmap, requestId); } void NodeInstanceView::updateWatcher(const QString &path) @@ -2031,7 +2072,6 @@ void NodeInstanceView::updateWatcher(const QString &path) QStringList oldDirs; QStringList newFiles; QStringList newDirs; - QStringList qsbFiles; const QString projPath = m_externalDependencies.currentProjectDirPath(); @@ -2284,7 +2324,8 @@ void NodeInstanceView::updateRotationBlocks() } } -void NodeInstanceView::maybeResetOnPropertyChange(const PropertyName &name, const ModelNode &node, +void NodeInstanceView::maybeResetOnPropertyChange(PropertyNameView name, + const ModelNode &node, PropertyChangeFlags flags) { bool reset = false; @@ -2329,4 +2370,62 @@ QList NodeInstanceView::loadInstancesFromCache(const QListsetProcessChannelMode(QProcess::ForwardedChannels); + puppetProcess->setProcessChannelMode(QProcess::MergedChannels); QObject::connect(puppetProcess.get(), &QProcess::readyRead, processOutputCallback); } puppetProcess->setWorkingDirectory(workingDirectory); diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 61d78e96a7f..0a0e9e88604 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -1538,44 +1538,6 @@ bool NodeMetaInfo::isFileComponent() const } } -bool NodeMetaInfo::isProjectComponent() const -{ - if constexpr (useProjectStorage()) { - if (!isValid()) - return false; - - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"is project component"_t, category(), keyValue("type id", m_typeId)}; - - auto isProjectComponent = typeData().traits.isProjectComponent; - - tracer.end(keyValue("is project component", isProjectComponent)); - - return isProjectComponent; - } - - return false; -} - -bool NodeMetaInfo::isInProjectModule() const -{ - if constexpr (useProjectStorage()) { - if (!isValid()) - return false; - - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"is project module"_t, category(), keyValue("type id", m_typeId)}; - - auto isInProjectModule = typeData().traits.isInProjectModule; - - tracer.end(keyValue("is project module", isInProjectModule)); - - return isInProjectModule; - } - - return false; -} - FlagIs NodeMetaInfo::canBeContainer() const { if constexpr (useProjectStorage()) { @@ -1950,7 +1912,7 @@ PropertyMetaInfos NodeMetaInfo::localProperties() const } } -PropertyMetaInfo NodeMetaInfo::property(const PropertyName &propertyName) const +PropertyMetaInfo NodeMetaInfo::property(PropertyNameView propertyName) const { if (!isValid()) return {}; @@ -4287,10 +4249,10 @@ PropertyMetaInfo &PropertyMetaInfo::operator=(PropertyMetaInfo &&) = default; PropertyMetaInfo::PropertyMetaInfo( [[maybe_unused]] std::shared_ptr nodeMetaInfoPrivateData, - [[maybe_unused]] const PropertyName &propertyName) + [[maybe_unused]] PropertyNameView propertyName) #ifndef QDS_USE_PROJECTSTORAGE : m_nodeMetaInfoPrivateData{nodeMetaInfoPrivateData} - , m_propertyName{propertyName} + , m_propertyName{propertyName.toByteArray()} #endif {} diff --git a/src/plugins/qmldesigner/designercore/model/propertycontainer.cpp b/src/plugins/qmldesigner/designercore/metainfo/propertycontainer.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/propertycontainer.cpp rename to src/plugins/qmldesigner/designercore/metainfo/propertycontainer.cpp diff --git a/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp b/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp index d8db3ac269d..82ffc76943f 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp @@ -15,6 +15,8 @@ #include #include +#include + namespace QmlDesigner { /*! @@ -23,20 +25,25 @@ namespace QmlDesigner { \brief The AbstractProperty class is a value holder for a property. */ -AbstractProperty::AbstractProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view) - : m_propertyName(propertyName), - m_internalNode(internalNode), - m_model(model), - m_view(view) +AbstractProperty::AbstractProperty(PropertyNameView propertyName, + const Internal::InternalNodePointer &internalNode, + Model *model, + AbstractView *view) + : m_propertyName(propertyName) + , m_internalNode(internalNode) + , m_model(model) + , m_view(view) { Q_ASSERT_X(!m_propertyName.contains(' '), Q_FUNC_INFO, "a property name cannot contain a space"); } -AbstractProperty::AbstractProperty(const Internal::InternalPropertyPointer &property, Model* model, AbstractView *view) - : m_propertyName(property->name()), - m_internalNode(property->propertyOwner()), - m_model(model), - m_view(view) +AbstractProperty::AbstractProperty(const Internal::InternalPropertyPointer &property, + Model *model, + AbstractView *view) + : m_propertyName(property->name()) + , m_internalNode(property->propertyOwner()) + , m_model(model) + , m_view(view) { } @@ -66,17 +73,7 @@ AbstractView *AbstractProperty::view() const return m_view.data(); } - /*! - Holds a value for a property. Returns the value of the property. - - The QVariant is null if the property does not exist. -*/ -const PropertyName &AbstractProperty::name() const -{ - return m_propertyName; -} - - /*! +/*! Checks if the property is valid. A property is valid if the belonging model node @@ -319,12 +316,13 @@ TypeName AbstractProperty::dynamicTypeName() const QDebug operator<<(QDebug debug, const AbstractProperty &property) { return debug.nospace() << "AbstractProperty(" - << (property.isValid() ? property.name() : PropertyName("invalid")) << ')'; + << (property.isValid() ? property.name() : PropertyNameView("invalid")) + << ')'; } QTextStream &operator<<(QTextStream &stream, const AbstractProperty &property) { - stream << "AbstractProperty(" << property.name() << ')'; + stream << "AbstractProperty(" << property.name().toByteArray() << ')'; return stream; } diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 125c7195a8f..75c15c72738 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -132,7 +132,6 @@ void AbstractView::removeModel() WidgetInfo AbstractView::createWidgetInfo(QWidget *widget, const QString &uniqueId, WidgetInfo::PlacementHint placementHint, - int placementPriority, const QString &tabName, const QString &feedbackDisplayName, DesignerWidgetFlags widgetFlags) @@ -142,7 +141,6 @@ WidgetInfo AbstractView::createWidgetInfo(QWidget *widget, widgetInfo.widget = widget; widgetInfo.uniqueId = uniqueId; widgetInfo.placementHint = placementHint; - widgetInfo.placementPriority = placementPriority; widgetInfo.tabName = tabName; widgetInfo.feedbackDisplayName = feedbackDisplayName; widgetInfo.widgetFlags = widgetFlags; @@ -385,7 +383,9 @@ void AbstractView::updateImport3DSupport(const QVariantMap &/*supportMap*/) // position of the requested view position. void AbstractView::nodeAtPosReady(const ModelNode &/*modelNode*/, const QVector3D &/*pos3d*/) {} -void AbstractView::modelNodePreviewPixmapChanged(const ModelNode &/*node*/, const QPixmap &/*pixmap*/) +void AbstractView::modelNodePreviewPixmapChanged(const ModelNode & /*node*/, + const QPixmap & /*pixmap*/, + const QByteArray & /*requestId*/) { } @@ -425,14 +425,7 @@ QList toInternalNodeList(const QList */ void AbstractView::setSelectedModelNodes(const QList &selectedNodeList) { - QList unlockedNodes; - - for (const auto &modelNode : selectedNodeList) { - if (!ModelUtils::isThisOrAncestorLocked(modelNode)) - unlockedNodes.push_back(modelNode); - } - - model()->d->setSelectedNodes(toInternalNodeList(unlockedNodes)); + model()->setSelectedModelNodes(selectedNodeList); } void AbstractView::setSelectedModelNode(const ModelNode &modelNode) @@ -667,17 +660,8 @@ void AbstractView::emitDocumentMessage(const QList &errors, con model()->d->setDocumentMessages(errors, warnings); } -void AbstractView::emitCustomNotification(const QString &identifier) -{ - emitCustomNotification(identifier, QList()); -} - -void AbstractView::emitCustomNotification(const QString &identifier, const QList &nodeList) -{ - emitCustomNotification(identifier, nodeList, QList()); -} - -void AbstractView::emitCustomNotification(const QString &identifier, const QList &nodeList, const QList &data) +void AbstractView::emitCustomNotification(const QString &identifier, const QList &nodeList, + const QList &data) { if (model()) model()->d->notifyCustomNotification(this, identifier, nodeList, data); @@ -749,10 +733,12 @@ void AbstractView::emitUpdateActiveScene3D(const QVariantMap &sceneState) model()->d->notifyUpdateActiveScene3D(sceneState); } -void AbstractView::emitModelNodelPreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) +void AbstractView::emitModelNodelPreviewPixmapChanged(const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId) { if (model()) - model()->d->notifyModelNodePreviewPixmapChanged(node, pixmap); + model()->d->notifyModelNodePreviewPixmapChanged(node, pixmap, requestId); } void AbstractView::emitImport3DSupportChanged(const QVariantMap &supportMap) diff --git a/src/plugins/qmldesigner/designercore/model/auxiliarypropertystorageview.cpp b/src/plugins/qmldesigner/designercore/model/auxiliarypropertystorageview.cpp new file mode 100644 index 00000000000..23d66b29a4b --- /dev/null +++ b/src/plugins/qmldesigner/designercore/model/auxiliarypropertystorageview.cpp @@ -0,0 +1,201 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "auxiliarypropertystorageview.h" + +#include + +#include +#include + +namespace QmlDesigner { + +namespace { +struct Initializer +{ + Initializer(Sqlite::Database &database, bool isInitialized) + { + if (!isInitialized) { + createAuxiliaryPropertiesTable(database); + } + database.setIsInitialized(true); + } + + void createAuxiliaryPropertiesTable(Sqlite::Database &database) + { + Sqlite::StrictTable table; + table.setUseIfNotExists(true); + table.setUseWithoutRowId(true); + table.setName("auxiliaryProperties"); + auto &filePathColumn = table.addColumn("filePath", Sqlite::StrictColumnType::Text); + auto &idColumn = table.addColumn("id", Sqlite::StrictColumnType::Text); + auto &keyColumn = table.addColumn("key", Sqlite::StrictColumnType::Text); + table.addColumn("value", Sqlite::StrictColumnType::Blob); + + table.addPrimaryKeyContraint({filePathColumn, idColumn, keyColumn}); + + table.initialize(database); + } +}; + +struct Entry +{ + Entry(Utils::SmallStringView nodeId, Utils::SmallStringView key, Sqlite::BlobView value) + : nodeId{nodeId} + , key{key} + , value{value} + {} + + Utils::SmallStringView nodeId; + Utils::SmallStringView key; + Sqlite::BlobView value; +}; + +struct ChangeEntry +{ + ChangeEntry(Utils::SmallStringView id, Utils::SmallStringView name) + : id{id} + , name{name} + {} + + friend bool operator<(const ChangeEntry &first, const ChangeEntry &second) + { + return std::tie(first.id, first.name) < std::tie(second.id, second.name); + } + + Utils::SmallString id; + Utils::SmallString name; +}; + +} // namespace + +struct AuxiliaryPropertyStorageView::Data +{ + Data(Sqlite::Database &database) + : database{database} + { + exclusiveTransaction.commit(); + } + + Sqlite::Database &database; + Sqlite::ExclusiveNonThrowingDestructorTransaction exclusiveTransaction{database}; + Initializer initializer{database, database.isInitialized()}; + Sqlite::WriteStatement<4> upsertValue{ + "INSERT INTO auxiliaryProperties(filePath, id, key, value) " + "VALUES(?1, ?2, ?3, ?4) " + "ON CONFLICT DO UPDATE SET value=excluded.value", + database}; + Sqlite::ReadStatement<3, 1> selectValues{ + "SELECT id, key, value FROM auxiliaryProperties WHERE filePath=?1", database}; + Sqlite::WriteStatement<0> removeValues{"DELETE FROM auxiliaryProperties", database}; + Sqlite::WriteStatement<3> removeValue{ + "DELETE FROM auxiliaryProperties WHERE filePath=?1 AND id=?2 AND key=?3", database}; + std::set> changeEntries; +}; + +AuxiliaryPropertyStorageView::AuxiliaryPropertyStorageView( + Sqlite::Database &database, ExternalDependenciesInterface &externalDependencies) + : AbstractView{externalDependencies} + , d{std::make_unique(database)} +{} + +AuxiliaryPropertyStorageView::~AuxiliaryPropertyStorageView() = default; + +void AuxiliaryPropertyStorageView::modelAttached(Model *model) +{ + auto entryRange = d->selectValues.rangeWithTransaction( + Utils::PathString{model->fileUrl().path()}); + + for (const auto entry : entryRange) { + auto node = model->modelNodeForId(QString{entry.nodeId}); + + if (!node) + continue; + + auto array = QByteArray::fromRawData(entry.value.cdata(), entry.value.ssize()); + QDataStream dataStream{array}; + + QVariant value; + dataStream >> value; + + node.setAuxiliaryDataWithoutLock({AuxiliaryDataType::Persistent, entry.key}, value); + } + + AbstractView::modelAttached(model); +} + +void AuxiliaryPropertyStorageView::modelAboutToBeDetached(Model *model) +{ + Utils::PathString filePath{model->fileUrl().path()}; + + auto update = [&] { + for (const auto &[id, name] : d->changeEntries) { + QByteArray array; + QDataStream dataStream{&array, QIODevice::WriteOnly}; + auto node = model->modelNodeForId(id.toQString()); + + auto value = node.auxiliaryData(AuxiliaryDataType::Persistent, name); + if (value) { + dataStream << *value; + + Sqlite::BlobView blob{array}; + + d->upsertValue.write(filePath, id, name, blob); + + } else { + d->removeValue.write(filePath, id, name); + } + } + }; + + if (d->changeEntries.size()) { + Sqlite::withImmediateTransaction(d->database, update); + + d->changeEntries.clear(); + } + + AbstractView::modelAboutToBeDetached(model); +} + +void AuxiliaryPropertyStorageView::nodeIdChanged(const ModelNode &node, + const QString &newIdArg, + const QString &oldIdArg) +{ + Utils::SmallString newId = newIdArg; + Utils::SmallString oldId = oldIdArg; + for (auto entry : node.auxiliaryData()) { + if (entry.first.type != AuxiliaryDataType::Persistent) + continue; + + d->changeEntries.emplace(oldId, entry.first.name); + d->changeEntries.emplace(newId, entry.first.name); + } +} + +void AuxiliaryPropertyStorageView::nodeAboutToBeRemoved(const ModelNode &removedNode) +{ + if (removedNode.hasId()) { + Utils::SmallString id = removedNode.id(); + for (auto entry : removedNode.auxiliaryData()) { + if (entry.first.type != AuxiliaryDataType::Persistent) + continue; + + d->changeEntries.emplace(id, entry.first.name); + } + } +} + +void AuxiliaryPropertyStorageView::auxiliaryDataChanged(const ModelNode &node, + AuxiliaryDataKeyView key, + const QVariant &) +{ + if (isAttached() && key.type == AuxiliaryDataType::Persistent) + d->changeEntries.emplace(Utils::SmallString{node.id()}, key.name); +} + +void AuxiliaryPropertyStorageView::resetForTestsOnly() +{ + Sqlite::withImmediateTransaction(d->database, [&] { d->removeValues.execute(); }); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/auxiliarypropertystorageview.h b/src/plugins/qmldesigner/designercore/model/auxiliarypropertystorageview.h new file mode 100644 index 00000000000..2096afe9596 --- /dev/null +++ b/src/plugins/qmldesigner/designercore/model/auxiliarypropertystorageview.h @@ -0,0 +1,34 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include + +#include + +namespace QmlDesigner { +class AuxiliaryPropertyStorageView final : public AbstractView +{ +public: + AuxiliaryPropertyStorageView(Sqlite::Database &database, + ExternalDependenciesInterface &externalDependencies); + ~AuxiliaryPropertyStorageView(); + + void modelAttached(Model *model) override; + void modelAboutToBeDetached(Model *model) override; + + void nodeIdChanged(const ModelNode &node, const QString &newId, const QString &oldId) override; + + void nodeAboutToBeRemoved(const ModelNode &removedNode) override; + + void auxiliaryDataChanged(const ModelNode &node, + AuxiliaryDataKeyView type, + const QVariant &data) override; + + struct Data; + + void resetForTestsOnly(); + +private: + std::unique_ptr d; +}; +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp b/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp index 23c17dc61a3..3086dbcd8f2 100644 --- a/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp @@ -25,15 +25,7 @@ BindingProperty::BindingProperty() = default; BindingProperty::BindingProperty(const BindingProperty &property, AbstractView *view) : AbstractProperty(property.name(), property.internalNodeSharedPointer(), property.model(), view) -{ -} - - -BindingProperty::BindingProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view) - : AbstractProperty(propertyName, internalNode, model, view) -{ -} - +{} void BindingProperty::setExpression(const QString &expression) { @@ -361,7 +353,7 @@ void BindingProperty::setDynamicTypeNameAndExpression(const TypeName &typeName, QDebug operator<<(QDebug debug, const BindingProperty &property) { if (!property.isValid()) - return debug.nospace() << "BindingProperty(" << PropertyName("invalid") << ')'; + return debug.nospace() << "BindingProperty(" << "invalid" << ')'; else return debug.nospace() << "BindingProperty(" << property.name() << " " << property.expression() << ')'; } @@ -369,9 +361,10 @@ QDebug operator<<(QDebug debug, const BindingProperty &property) QTextStream& operator<<(QTextStream &stream, const BindingProperty &property) { if (!property.isValid()) - stream << "BindingProperty(" << PropertyName("invalid") << ')'; + stream << "BindingProperty(" << "invalid" << ')'; else - stream << "BindingProperty(" << property.name() << " " << property.expression() << ')'; + stream << "BindingProperty(" << property.name().toByteArray() << " " + << property.expression() << ')'; return stream; } diff --git a/src/plugins/qmldesigner/designercore/model/import.cpp b/src/plugins/qmldesigner/designercore/model/import.cpp index f23331edebf..06e277f8fa8 100644 --- a/src/plugins/qmldesigner/designercore/model/import.cpp +++ b/src/plugins/qmldesigner/designercore/model/import.cpp @@ -3,6 +3,8 @@ #include "import.h" +#include + #include #include diff --git a/src/plugins/qmldesigner/designercore/model/internalbindingproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalbindingproperty.cpp index 2e7542c79b1..8c99041b08d 100644 --- a/src/plugins/qmldesigner/designercore/model/internalbindingproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalbindingproperty.cpp @@ -6,7 +6,7 @@ namespace QmlDesigner { namespace Internal { -InternalBindingProperty::InternalBindingProperty(const PropertyName &name, +InternalBindingProperty::InternalBindingProperty(PropertyNameView name, const InternalNodePointer &propertyOwner) : InternalProperty(name, propertyOwner, PropertyType::Binding) { diff --git a/src/plugins/qmldesigner/designercore/model/internalbindingproperty.h b/src/plugins/qmldesigner/designercore/model/internalbindingproperty.h index 9ad0e19fc9e..6744a814925 100644 --- a/src/plugins/qmldesigner/designercore/model/internalbindingproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalbindingproperty.h @@ -14,7 +14,7 @@ public: using Pointer = std::shared_ptr; static constexpr PropertyType type = PropertyType::Binding; - InternalBindingProperty(const PropertyName &name, const InternalNodePointer &propertyOwner); + InternalBindingProperty(PropertyNameView name, const InternalNodePointer &propertyOwner); bool isValid() const override; diff --git a/src/plugins/qmldesigner/designercore/model/internalnode.cpp b/src/plugins/qmldesigner/designercore/model/internalnode.cpp index bf59383747c..4211633d7c6 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnode.cpp @@ -51,6 +51,14 @@ auto find(Type &&auxiliaryDatas, AuxiliaryDataKeyView key) }); } +template +auto find(Type &&auxiliaryDatas, AuxiliaryDataType type) +{ + return std::find_if(auxiliaryDatas.begin(), auxiliaryDatas.end(), [&](const auto &element) { + return element.first.type == type; + }); +} + } // namespace std::optional InternalNode::auxiliaryData(AuxiliaryDataKeyView key) const @@ -99,6 +107,13 @@ bool InternalNode::hasAuxiliaryData(AuxiliaryDataKeyView key) const return found != m_auxiliaryDatas.end(); } +bool InternalNode::hasAuxiliaryData(AuxiliaryDataType type) const +{ + auto found = find(m_auxiliaryDatas, type); + + return found != m_auxiliaryDatas.end(); +} + AuxiliaryDatasForType InternalNode::auxiliaryData(AuxiliaryDataType type) const { AuxiliaryDatasForType data; @@ -114,8 +129,17 @@ AuxiliaryDatasForType InternalNode::auxiliaryData(AuxiliaryDataType type) const PropertyNameList InternalNode::propertyNameList() const { - return Utils::transform(m_nameProperties, - [](const auto &entry) { return entry.first; }); + return Utils::transform(m_nameProperties, [](const auto &entry) { + return entry.first.toQByteArray(); + }); +} + +PropertyNameViews InternalNode::propertyNameViews() const +{ + return Utils::transform(m_nameProperties, + [](const auto &entry) -> PropertyNameView { + return entry.first; + }); } QList InternalNode::allSubNodes() const diff --git a/src/plugins/qmldesigner/designercore/model/internalnode_p.h b/src/plugins/qmldesigner/designercore/model/internalnode_p.h index 8d0bf8880bc..9e3a32ef7f6 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode_p.h +++ b/src/plugins/qmldesigner/designercore/model/internalnode_p.h @@ -76,6 +76,7 @@ public: bool setAuxiliaryData(AuxiliaryDataKeyView key, const QVariant &data); bool removeAuxiliaryData(AuxiliaryDataKeyView key); bool hasAuxiliaryData(AuxiliaryDataKeyView key) const; + bool hasAuxiliaryData(AuxiliaryDataType type) const; AuxiliaryDatasForType auxiliaryData(AuxiliaryDataType type) const; AuxiliaryDatasView auxiliaryData() const { return std::as_const(m_auxiliaryDatas); } @@ -143,7 +144,7 @@ public: auto nodeProperty(PropertyNameView name) const { return property(name); } template - Type *addProperty(const PropertyName &name) + Type *addProperty(PropertyNameView name) { auto newProperty = std::make_shared(name, shared_from_this()); auto pointer = newProperty.get(); @@ -152,32 +153,32 @@ public: return pointer; } - auto addBindingProperty(const PropertyName &name) + auto addBindingProperty(PropertyNameView name) { return addProperty(name); } - auto addSignalHandlerProperty(const PropertyName &name) + auto addSignalHandlerProperty(PropertyNameView name) { return addProperty(name); } - auto addSignalDeclarationProperty(const PropertyName &name) + auto addSignalDeclarationProperty(PropertyNameView name) { return addProperty(name); } - auto addNodeListProperty(const PropertyName &name) + auto addNodeListProperty(PropertyNameView name) { return addProperty(name); } - auto addVariantProperty(const PropertyName &name) + auto addVariantProperty(PropertyNameView name) { return addProperty(name); } - auto addNodeProperty(const PropertyName &name, const TypeName &dynamicTypeName) + auto addNodeProperty(PropertyNameView name, const TypeName &dynamicTypeName) { auto property = addProperty(name); property->setDynamicTypeName(dynamicTypeName); @@ -186,6 +187,9 @@ public: } PropertyNameList propertyNameList() const; + PropertyNameViews propertyNameViews() const; + + bool hasProperties() const { return m_nameProperties.size(); } QList allSubNodes() const; QList allDirectSubNodes() const; @@ -214,7 +218,7 @@ public: m_nameProperties.erase(found); // C++ 23 -> m_nameProperties.erase(name) } - using PropertyDict = std::map>; + using PropertyDict = std::map>; PropertyDict::const_iterator begin() const { return m_nameProperties.begin(); } diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.cpp index 6dff33436e4..d7afff29b3b 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.cpp @@ -7,7 +7,7 @@ namespace QmlDesigner { namespace Internal { -InternalNodeAbstractProperty::InternalNodeAbstractProperty(const PropertyName &name, +InternalNodeAbstractProperty::InternalNodeAbstractProperty(PropertyNameView name, const InternalNode::Pointer &propertyOwner, PropertyType propertyType) : InternalProperty(name, propertyOwner, propertyType) diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h b/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h index 7205fe7377d..5a10861dfc5 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h @@ -24,7 +24,7 @@ public: bool isValid() const override; protected: - InternalNodeAbstractProperty(const PropertyName &name, + InternalNodeAbstractProperty(PropertyNameView name, const InternalNodePointer &propertyOwner, PropertyType propertyType); virtual void remove(const InternalNodePointer &node) = 0; diff --git a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp index 975927c097c..49fa67f9c2c 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp @@ -8,7 +8,7 @@ namespace QmlDesigner { namespace Internal { -InternalNodeListProperty::InternalNodeListProperty(const PropertyName &name, +InternalNodeListProperty::InternalNodeListProperty(PropertyNameView name, const InternalNodePointer &propertyOwner) : InternalNodeAbstractProperty(name, propertyOwner, PropertyType::NodeList) { diff --git a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h index 01b508b80ab..9072e571afc 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h @@ -17,7 +17,7 @@ public: using Pointer = std::shared_ptr; static constexpr PropertyType type = PropertyType::NodeList; - InternalNodeListProperty(const PropertyName &name, const InternalNodePointer &propertyOwner); + InternalNodeListProperty(PropertyNameView name, const InternalNodePointer &propertyOwner); bool isValid() const override; diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp index ff9d71d6fdb..d6bf0daf68a 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp @@ -7,7 +7,7 @@ namespace QmlDesigner { namespace Internal { -InternalNodeProperty::InternalNodeProperty(const PropertyName &name, +InternalNodeProperty::InternalNodeProperty(PropertyNameView name, const InternalNode::Pointer &propertyOwner) : InternalNodeAbstractProperty(name, propertyOwner, PropertyType::Node) { diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h index bd4b66304e7..b1572962c25 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h @@ -14,7 +14,7 @@ public: using Pointer = std::shared_ptr; static constexpr PropertyType type = PropertyType::Node; - InternalNodeProperty(const PropertyName &name, const InternalNodePointer &node); + InternalNodeProperty(PropertyNameView name, const InternalNodePointer &node); bool isValid() const override; bool isEmpty() const override; diff --git a/src/plugins/qmldesigner/designercore/model/internalproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalproperty.cpp index 06a1d903739..7f8417a0ad6 100644 --- a/src/plugins/qmldesigner/designercore/model/internalproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalproperty.cpp @@ -41,7 +41,7 @@ namespace Internal { InternalProperty::~InternalProperty() = default; -InternalProperty::InternalProperty(const PropertyName &name, +InternalProperty::InternalProperty(PropertyNameView name, const InternalNode::Pointer &propertyOwner, PropertyType propertyType) : m_name(name) @@ -57,7 +57,7 @@ bool InternalProperty::isValid() const return !m_propertyOwner.expired() && !m_name.isEmpty(); } -PropertyName InternalProperty::name() const +PropertyNameView InternalProperty::name() const { return m_name; } diff --git a/src/plugins/qmldesigner/designercore/model/internalproperty.h b/src/plugins/qmldesigner/designercore/model/internalproperty.h index f5ca983969c..3f30fb9c2d8 100644 --- a/src/plugins/qmldesigner/designercore/model/internalproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalproperty.h @@ -103,7 +103,7 @@ public: virtual bool isValid() const; - PropertyName name() const; + PropertyNameView name() const; bool isBindingProperty() const { return m_propertyType == PropertyType::Binding; } bool isVariantProperty() const { return m_propertyType == PropertyType::Variant; } @@ -182,14 +182,14 @@ public: PropertyType type() const { return m_propertyType; } protected: // functions - InternalProperty(const PropertyName &name, + InternalProperty(PropertyNameView name, const InternalNodePointer &propertyOwner, PropertyType propertyType); void setDynamicTypeName(const TypeName &name); private: - PropertyName m_name; + Utils::SmallString m_name; TypeName m_dynamicType; std::weak_ptr m_propertyOwner; PropertyType m_propertyType = PropertyType::None; diff --git a/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.cpp index d199ad4b8c9..61197feedb2 100644 --- a/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.cpp @@ -6,7 +6,7 @@ namespace QmlDesigner { namespace Internal { -InternalSignalHandlerProperty::InternalSignalHandlerProperty(const PropertyName &name, +InternalSignalHandlerProperty::InternalSignalHandlerProperty(PropertyNameView name, const InternalNodePointer &propertyOwner) : InternalProperty(name, propertyOwner, PropertyType::SignalHandler) { @@ -46,7 +46,7 @@ void InternalSignalDeclarationProperty::setSignature(const QString &signature) } InternalSignalDeclarationProperty::InternalSignalDeclarationProperty( - const PropertyName &name, const InternalNodePointer &propertyOwner) + PropertyNameView name, const InternalNodePointer &propertyOwner) : InternalProperty(name, propertyOwner, PropertyType::SignalDeclaration) { setDynamicTypeName("signal"); diff --git a/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.h b/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.h index f0d88e2d239..35b589ec0ac 100644 --- a/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.h @@ -14,7 +14,7 @@ public: using Pointer = std::shared_ptr; static constexpr PropertyType type = PropertyType::SignalHandler; - InternalSignalHandlerProperty(const PropertyName &name, const InternalNodePointer &propertyOwner); + InternalSignalHandlerProperty(PropertyNameView name, const InternalNodePointer &propertyOwner); bool isValid() const override; @@ -31,8 +31,7 @@ public: using Pointer = std::shared_ptr; static constexpr PropertyType type = PropertyType::SignalDeclaration; - InternalSignalDeclarationProperty(const PropertyName &name, - const InternalNodePointer &propertyOwner); + InternalSignalDeclarationProperty(PropertyNameView name, const InternalNodePointer &propertyOwner); bool isValid() const override; diff --git a/src/plugins/qmldesigner/designercore/model/internalvariantproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalvariantproperty.cpp index 04ff6fff708..c031f73ba8c 100644 --- a/src/plugins/qmldesigner/designercore/model/internalvariantproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalvariantproperty.cpp @@ -6,8 +6,7 @@ namespace QmlDesigner { namespace Internal { -InternalVariantProperty::InternalVariantProperty(const PropertyName &name, - const InternalNodePointer &node) +InternalVariantProperty::InternalVariantProperty(PropertyNameView name, const InternalNodePointer &node) : InternalProperty(name, node, PropertyType::Variant) { } diff --git a/src/plugins/qmldesigner/designercore/model/internalvariantproperty.h b/src/plugins/qmldesigner/designercore/model/internalvariantproperty.h index f9bb85d38d7..bf97c3d68a3 100644 --- a/src/plugins/qmldesigner/designercore/model/internalvariantproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalvariantproperty.h @@ -14,7 +14,7 @@ public: using Pointer = std::shared_ptr; static constexpr PropertyType type = PropertyType::Variant; - InternalVariantProperty(const PropertyName &name, const InternalNodePointer &propertyOwner); + InternalVariantProperty(PropertyNameView name, const InternalNodePointer &propertyOwner); bool isValid() const override; diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 5442e819728..8d06929f119 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -4,6 +4,7 @@ #include "model.h" #include "internalnode_p.h" #include "model_p.h" +#include "modelutils.h" #include #include "../projectstorage/sourcepath.h" @@ -39,6 +40,7 @@ #include #include +#include #include #include @@ -165,15 +167,25 @@ void ModelPrivate::detachAllViews() namespace { Storage::Imports createStorageImports(const Imports &imports, + Utils::SmallStringView localDirectoryPath, ProjectStorageType &projectStorage, SourceId fileId) { - return Utils::transform(imports, [&](const Import &import) { - using Storage::ModuleKind; + using Storage::ModuleKind; + Storage::Imports storageImports; + storageImports.reserve(Utils::usize(imports) + 1); + + for (const Import &import : imports) { auto moduleKind = import.isLibraryImport() ? ModuleKind::QmlLibrary : ModuleKind::PathLibrary; auto moduleId = projectStorage.moduleId(Utils::SmallString{import.url()}, moduleKind); - return Storage::Import{moduleId, import.majorVersion(), import.minorVersion(), fileId}; - }); + storageImports.emplace_back(moduleId, import.majorVersion(), import.minorVersion(), fileId); + } + + auto localDirectoryModuleId = projectStorage.moduleId(localDirectoryPath, ModuleKind::PathLibrary); + + storageImports.emplace_back(localDirectoryModuleId, Storage::Version{}, fileId); + + return storageImports; } } // namespace @@ -195,7 +207,7 @@ void ModelPrivate::changeImports(Imports toBeAddedImports, Imports toBeRemovedIm if (!removedImports.isEmpty() || !allNewAddedImports.isEmpty()) { if (useProjectStorage()) { - auto imports = createStorageImports(m_imports, *projectStorage, m_sourceId); + auto imports = createStorageImports(m_imports, m_localPath, *projectStorage, m_sourceId); projectStorage->synchronizeDocumentImports(std::move(imports), m_sourceId); } notifyImportsChanged(allNewAddedImports, removedImports); @@ -264,7 +276,10 @@ void ModelPrivate::setFileUrl(const QUrl &fileUrl) if (oldPath != fileUrl) { m_fileUrl = fileUrl; if constexpr (useProjectStorage()) { - m_sourceId = pathCache->sourceId(SourcePath{fileUrl.path()}); + auto path = fileUrl.path(); + m_sourceId = pathCache->sourceId(SourcePath{path}); + auto found = std::find(path.rbegin(), path.rend(), u'/').base(); + m_localPath = Utils::PathString{QStringView{path.begin(), std::prev(found)}}; } for (const QPointer &view : std::as_const(m_viewList)) @@ -333,9 +348,9 @@ InternalNodePointer ModelPrivate::createNode(TypeNameView typeName, notifyNodeCreated(newNode); - if (!newNode->propertyNameList().isEmpty()) + if (newNode->hasProperties()) notifyVariantPropertiesChanged(newNode, - newNode->propertyNameList(), + newNode->propertyNameViews(), AbstractView::PropertiesAdded); return newNode; @@ -459,7 +474,7 @@ void ModelPrivate::removeNode(const InternalNodePointer &node) removeNodeFromModel(node); InternalNodePointer parentNode; - PropertyName parentPropertyName; + PropertyNameView parentPropertyName; if (oldParentProperty) { parentNode = oldParentProperty->propertyOwner(); parentPropertyName = oldParentProperty->name(); @@ -715,10 +730,12 @@ void ModelPrivate::notifyUpdateActiveScene3D(const QVariantMap &sceneState) notifyInstanceChanges([&](AbstractView *view) { view->updateActiveScene3D(sceneState); }); } -void ModelPrivate::notifyModelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) +void ModelPrivate::notifyModelNodePreviewPixmapChanged(const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId) { notifyInstanceChanges( - [&](AbstractView *view) { view->modelNodePreviewPixmapChanged(node, pixmap); }); + [&](AbstractView *view) { view->modelNodePreviewPixmapChanged(node, pixmap, requestId); }); } void ModelPrivate::notifyImport3DSupportChanged(const QVariantMap &supportMap) @@ -907,7 +924,7 @@ void ModelPrivate::notifyNodeAboutToBeRemoved(const InternalNodePointer &interna void ModelPrivate::notifyNodeRemoved(const InternalNodePointer &removedNode, const InternalNodePointer &parentNode, - const PropertyName &parentPropertyName, + PropertyNameView parentPropertyName, AbstractView::PropertyChangeFlags propertyChange) { notifyNormalViewsLast([&](AbstractView *view) { @@ -1010,12 +1027,12 @@ void ModelPrivate::notifyScriptFunctionsChanged(const InternalNodePointer &node, } void ModelPrivate::notifyVariantPropertiesChanged(const InternalNodePointer &node, - const PropertyNameList &propertyNameList, + const PropertyNameViews &propertyNameViews, AbstractView::PropertyChangeFlags propertyChange) { notifyNodeInstanceViewLast([&](AbstractView *view) { QList propertyList; - for (const PropertyName &propertyName : propertyNameList) { + for (PropertyNameView propertyName : propertyNameViews) { VariantProperty property(propertyName, node, m_model, view); propertyList.append(property); } @@ -1026,9 +1043,9 @@ void ModelPrivate::notifyVariantPropertiesChanged(const InternalNodePointer &nod void ModelPrivate::notifyNodeAboutToBeReparent(const InternalNodePointer &node, const InternalNodePointer &newParent, - const PropertyName &newPropertyName, + PropertyNameView newPropertyName, const InternalNodePointer &oldParent, - const PropertyName &oldPropertyName, + PropertyNameView oldPropertyName, AbstractView::PropertyChangeFlags propertyChange) { notifyNodeInstanceViewLast([&](AbstractView *view) { @@ -1053,7 +1070,7 @@ void ModelPrivate::notifyNodeAboutToBeReparent(const InternalNodePointer &node, void ModelPrivate::notifyNodeReparent(const InternalNodePointer &node, const InternalNodeAbstractProperty *newPropertyParent, const InternalNodePointer &oldParent, - const PropertyName &oldPropertyName, + PropertyNameView oldPropertyName, AbstractView::PropertyChangeFlags propertyChange) { notifyNodeInstanceViewLast([&](AbstractView *view) { @@ -1332,7 +1349,7 @@ void ModelPrivate::removeProperties(const QList &properties) } void ModelPrivate::setBindingProperty(const InternalNodePointer &node, - const PropertyName &name, + PropertyNameView name, const QString &expression) { AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; @@ -1365,7 +1382,9 @@ void ModelPrivate::setBindingProperties(const ModelResourceSet::SetExpressions & notifyBindingPropertiesChanged(bindingProperties, propertyChange); } -void ModelPrivate::setSignalHandlerProperty(const InternalNodePointer &node, const PropertyName &name, const QString &source) +void ModelPrivate::setSignalHandlerProperty(const InternalNodePointer &node, + PropertyNameView name, + const QString &source) { AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; InternalSignalHandlerProperty *signalHandlerProperty = nullptr; @@ -1380,7 +1399,9 @@ void ModelPrivate::setSignalHandlerProperty(const InternalNodePointer &node, con notifySignalHandlerPropertiesChanged({signalHandlerProperty}, propertyChange); } -void ModelPrivate::setSignalDeclarationProperty(const InternalNodePointer &node, const PropertyName &name, const QString &signature) +void ModelPrivate::setSignalDeclarationProperty(const InternalNodePointer &node, + PropertyNameView name, + const QString &signature) { AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; InternalSignalDeclarationProperty *signalDeclarationProperty = nullptr; @@ -1395,7 +1416,9 @@ void ModelPrivate::setSignalDeclarationProperty(const InternalNodePointer &node, notifySignalDeclarationPropertiesChanged({signalDeclarationProperty}, propertyChange); } -void ModelPrivate::setVariantProperty(const InternalNodePointer &node, const PropertyName &name, const QVariant &value) +void ModelPrivate::setVariantProperty(const InternalNodePointer &node, + PropertyNameView name, + const QVariant &value) { AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; InternalVariantProperty *variantProperty = nullptr; @@ -1408,11 +1431,11 @@ void ModelPrivate::setVariantProperty(const InternalNodePointer &node, const Pro variantProperty->setValue(value); variantProperty->resetDynamicTypeName(); - notifyVariantPropertiesChanged(node, PropertyNameList({name}), propertyChange); + notifyVariantPropertiesChanged(node, PropertyNameViews({name}), propertyChange); } void ModelPrivate::setDynamicVariantProperty(const InternalNodePointer &node, - const PropertyName &name, + PropertyNameView name, const TypeName &dynamicPropertyType, const QVariant &value) { @@ -1426,11 +1449,11 @@ void ModelPrivate::setDynamicVariantProperty(const InternalNodePointer &node, } variantProperty->setDynamicValue(dynamicPropertyType, value); - notifyVariantPropertiesChanged(node, PropertyNameList({name}), propertyChange); + notifyVariantPropertiesChanged(node, PropertyNameViews({name}), propertyChange); } void ModelPrivate::setDynamicBindingProperty(const InternalNodePointer &node, - const PropertyName &name, + PropertyNameView name, const TypeName &dynamicPropertyType, const QString &expression) { @@ -1449,7 +1472,7 @@ void ModelPrivate::setDynamicBindingProperty(const InternalNodePointer &node, } void ModelPrivate::reparentNode(const InternalNodePointer &parentNode, - const PropertyName &name, + PropertyNameView name, const InternalNodePointer &childNode, bool list, const TypeName &dynamicTypeName) @@ -1458,7 +1481,7 @@ void ModelPrivate::reparentNode(const InternalNodePointer &parentNode, InternalNodeAbstractPropertyPointer oldParentProperty(childNode->parentProperty()); InternalNodePointer oldParentNode; - PropertyName oldParentPropertyName; + Utils::SmallString oldParentPropertyName; if (oldParentProperty && oldParentProperty->isValid()) { oldParentNode = childNode->parentProperty()->propertyOwner(); oldParentPropertyName = childNode->parentProperty()->name(); @@ -1503,7 +1526,7 @@ void ModelPrivate::clearParent(const InternalNodePointer &node) { InternalNodeAbstractPropertyPointer oldParentProperty(node->parentProperty()); InternalNodePointer oldParentNode; - PropertyName oldParentPropertyName; + Utils::SmallString oldParentPropertyName; if (oldParentProperty->isValid()) { oldParentNode = node->parentProperty()->propertyOwner(); oldParentPropertyName = node->parentProperty()->name(); @@ -1547,7 +1570,10 @@ void ModelPrivate::setNodeSource(const InternalNodePointer &node, const QString notifyNodeSourceChanged(node, nodeSource); } -void ModelPrivate::changeNodeOrder(const InternalNodePointer &parentNode, const PropertyName &listPropertyName, int from, int to) +void ModelPrivate::changeNodeOrder(const InternalNodePointer &parentNode, + PropertyNameView listPropertyName, + int from, + int to) { auto nodeList = parentNode->nodeListProperty(listPropertyName); Q_ASSERT(nodeList); @@ -1865,12 +1891,7 @@ bool Model::hasImport(const QString &importUrl) const QString Model::generateNewId(const QString &prefixName, const QString &fallbackPrefix) const { - QString newId = prefixName; - - if (newId.isEmpty()) - newId = fallbackPrefix; - - return UniqueName::generateId(prefixName, [&] (const QString &id) { + return UniqueName::generateId(prefixName, fallbackPrefix, [&](const QString &id) { // Properties of the root node are not allowed for ids, because they are available in the // complete context without qualification. return hasId(id) || d->rootNode()->property(id.toUtf8()); @@ -2037,6 +2058,18 @@ QList Model::selectedNodes(AbstractView *view) const return d->toModelNodeList(d->selectedNodes(), view); } +void Model::setSelectedModelNodes(const QList &selectedNodeList) +{ + QList unlockedNodes; + + for (const auto &modelNode : selectedNodeList) { + if (!ModelUtils::isThisOrAncestorLocked(modelNode)) + unlockedNodes.push_back(modelNode); + } + + d->setSelectedNodes(toInternalNodeList(unlockedNodes)); +} + void Model::clearMetaInfoCache() { d->m_nodeMetaInfoCache.clear(); @@ -2062,7 +2095,6 @@ SourceId Model::fileUrlSourceId() const */ void Model::setFileUrl(const QUrl &url) { - QTC_ASSERT(url.isValid() && url.isLocalFile(), qDebug() << "url:" << url; return); Internal::WriteLocker locker(d.get()); d->setFileUrl(url); } diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index d666e2b820e..d32a0973d62 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -50,7 +50,7 @@ class InternalVariantProperty; class InternalNodeAbstractProperty; class InternalNodeListProperty; -using PropertyPair = QPair; +using PropertyPair = std::pair; class ModelPrivate; @@ -162,19 +162,19 @@ public: void notifyNodeCreated(const InternalNodePointer &newNode); void notifyNodeAboutToBeReparent(const InternalNodePointer &node, const InternalNodePointer &newParent, - const PropertyName &newPropertyName, + PropertyNameView newPropertyName, const InternalNodePointer &oldParent, - const PropertyName &oldPropertyName, + PropertyNameView oldPropertyName, AbstractView::PropertyChangeFlags propertyChange); void notifyNodeReparent(const InternalNodePointer &node, const InternalNodeAbstractProperty *newPropertyParent, const InternalNodePointer &oldParent, - const PropertyName &oldPropertyName, + PropertyNameView oldPropertyName, AbstractView::PropertyChangeFlags propertyChange); void notifyNodeAboutToBeRemoved(const InternalNodePointer &node); void notifyNodeRemoved(const InternalNodePointer &removedNode, const InternalNodePointer &parentNode, - const PropertyName &parentPropertyName, + PropertyNameView parentPropertyName, AbstractView::PropertyChangeFlags propertyChange); void notifyNodeIdChanged(const InternalNodePointer &node, const QString &newId, const QString &oldId); void notifyNodeTypeChanged(const InternalNodePointer &node, const TypeName &type, int majorVersion, int minorVersion); @@ -192,7 +192,9 @@ public: void notifySignalDeclarationPropertiesChanged( const QVector &propertyList, AbstractView::PropertyChangeFlags propertyChange); - void notifyVariantPropertiesChanged(const InternalNodePointer &node, const PropertyNameList &propertyNameList, AbstractView::PropertyChangeFlags propertyChange); + void notifyVariantPropertiesChanged(const InternalNodePointer &node, + const PropertyNameViews &propertyNameList, + AbstractView::PropertyChangeFlags propertyChange); void notifyScriptFunctionsChanged(const InternalNodePointer &node, const QStringList &scriptFunctionList); void notifyNodeOrderChanged(const QmlDesigner::Internal::InternalNodeListProperty *internalListProperty, @@ -221,7 +223,9 @@ public: void notifyRenderImage3DChanged(const QImage &image); void notifyUpdateActiveScene3D(const QVariantMap &sceneState); - void notifyModelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap); + void notifyModelNodePreviewPixmapChanged(const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId); void notifyImport3DSupportChanged(const QVariantMap &supportMap); void notifyNodeAtPosResult(const ModelNode &modelNode, const QVector3D &pos3d); void notifyView3DAction(View3DActionType type, const QVariant &value); @@ -258,24 +262,42 @@ public: void notifyUsedImportsChanged(const Imports &usedImportsChanged); //node state property manipulation - void addProperty(const InternalNodePointer &node, const PropertyName &name); - void setPropertyValue(const InternalNodePointer &node,const PropertyName &name, const QVariant &value); + void addProperty(const InternalNodePointer &node, PropertyNameView name); + void setPropertyValue(const InternalNodePointer &node, PropertyNameView name, const QVariant &value); void removePropertyAndRelatedResources(InternalProperty *property); void removeProperty(InternalProperty *property); void removeProperties(const QList &properties); void setBindingProperty(const InternalNodePointer &node, - const PropertyName &name, + PropertyNameView name, const QString &expression); void setBindingProperties(const ModelResourceSet::SetExpressions &setExpressions); - void setSignalHandlerProperty(const InternalNodePointer &node, const PropertyName &name, const QString &source); - void setSignalDeclarationProperty(const InternalNodePointer &node, const PropertyName &name, const QString &signature); - void setVariantProperty(const InternalNodePointer &node, const PropertyName &name, const QVariant &value); - void setDynamicVariantProperty(const InternalNodePointer &node, const PropertyName &name, const TypeName &propertyType, const QVariant &value); - void setDynamicBindingProperty(const InternalNodePointer &node, const PropertyName &name, const TypeName &dynamicPropertyType, const QString &expression); - void reparentNode(const InternalNodePointer &parentNode, const PropertyName &name, const InternalNodePointer &childNode, - bool list = true, const TypeName &dynamicTypeName = TypeName()); - void changeNodeOrder(const InternalNodePointer &parentNode, const PropertyName &listPropertyName, int from, int to); + void setSignalHandlerProperty(const InternalNodePointer &node, + PropertyNameView name, + const QString &source); + void setSignalDeclarationProperty(const InternalNodePointer &node, + PropertyNameView name, + const QString &signature); + void setVariantProperty(const InternalNodePointer &node, + PropertyNameView name, + const QVariant &value); + void setDynamicVariantProperty(const InternalNodePointer &node, + PropertyNameView name, + const TypeName &propertyType, + const QVariant &value); + void setDynamicBindingProperty(const InternalNodePointer &node, + PropertyNameView name, + const TypeName &dynamicPropertyType, + const QString &expression); + void reparentNode(const InternalNodePointer &parentNode, + PropertyNameView name, + const InternalNodePointer &childNode, + bool list = true, + const TypeName &dynamicTypeName = TypeName()); + void changeNodeOrder(const InternalNodePointer &parentNode, + PropertyNameView listPropertyName, + int from, + int to); static bool propertyNameIsValid(PropertyNameView propertyName); void clearParent(const InternalNodePointer &node); void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion); @@ -353,6 +375,7 @@ private: InternalNodePointer m_currentTimelineNode; std::unique_ptr m_resourceManagement; QUrl m_fileUrl; + Utils::PathString m_localPath; SourceId m_sourceId; QPointer m_rewriterView; QPointer m_nodeInstanceView; diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp index 94d431dda6f..f5bce0d96ee 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp @@ -80,50 +80,23 @@ QString ModelNode::id() const return m_internalNode->id; } -QString ModelNode::validId() +void ModelNode::ensureIdExists() const { - if (id().isEmpty()) - setIdWithRefactoring(model()->generateNewId(simplifiedTypeName())); + if (!hasId()) + setIdWithoutRefactoring(model()->generateNewId(simplifiedTypeName())); +} + +QString ModelNode::validId() const +{ + ensureIdExists(); return id(); } -namespace { -bool isQmlKeyWord(QStringView id) -{ - static constexpr auto keywords = Utils::to_array( - {u"as", u"break", u"case", u"catch", u"continue", u"debugger", - u"default", u"delete", u"do", u"else", u"finally", u"for", - u"function", u"if", u"import", u"in", u"instanceof", u"new", - u"print", u"return", u"switch", u"this", u"throw", u"try", - u"typeof", u"var", u"void", u"while", u"with"}); - - return std::binary_search(keywords.begin(), keywords.end(), ModelUtils::toStdStringView(id)); -} - -bool isIdToAvoid(QStringView id) -{ - static constexpr auto token = Utils::to_array( - {u"anchors", u"baseState", u"border", u"bottom", u"clip", u"color", - u"data", u"enabled", u"flow", u"focus", u"font", u"height", - u"item", u"layer", u"left", u"margin", u"opacity", u"padding", - u"parent", u"rect", u"right", u"scale", u"shaderInfo", u"source", - u"sprite", u"spriteSequence", u"state", u"text", u"texture", u"top", - u"visible", u"width", u"x", u"y"}); - - return std::binary_search(token.begin(), token.end(), ModelUtils::toStdStringView(id)); -} - -bool idContainsWrongLetter(const QString &id) -{ - static QRegularExpression idExpr(QStringLiteral("^[a-z_][a-zA-Z0-9_]*$")); - return !id.contains(idExpr); -} - -} // namespace bool ModelNode::isValidId(const QString &id) { - return id.isEmpty() || (!idContainsWrongLetter(id) && !isQmlKeyWord(id) && !isIdToAvoid(id)); + using namespace ModelUtils; + return isValidQmlIdentifier(id) && !isBannedQmlId(id); } QString ModelNode::getIdValidityErrorMessage(const QString &id) @@ -140,10 +113,13 @@ QString ModelNode::getIdValidityErrorMessage(const QString &id) if (id.contains(' ')) return QObject::tr("ID cannot include whitespace (%1).").arg(id); - if (isQmlKeyWord(id)) + if (ModelUtils::isQmlKeyword(id)) return QObject::tr("%1 is a reserved QML keyword.").arg(id); - if (isIdToAvoid(id)) + if (ModelUtils::isQmlBuiltinType(id)) + return QObject::tr("%1 is a reserved Qml type.").arg(id); + + if (ModelUtils::isDiscouragedQmlId(id)) return QObject::tr("%1 is a reserved property keyword.").arg(id); return QObject::tr("ID includes invalid characters (%1).").arg(id); @@ -157,7 +133,7 @@ bool ModelNode::hasId() const return !m_internalNode->id.isEmpty(); } -void ModelNode::setIdWithRefactoring(const QString &id) +void ModelNode::setIdWithRefactoring(const QString &id) const { if (isValid()) { if (model()->rewriterView() && !id.isEmpty() @@ -169,7 +145,7 @@ void ModelNode::setIdWithRefactoring(const QString &id) } } -void ModelNode::setIdWithoutRefactoring(const QString &id) +void ModelNode::setIdWithoutRefactoring(const QString &id) const { Internal::WriteLocker locker(m_model.data()); if (!isValid()) @@ -362,7 +338,7 @@ bool ModelNode::hasParentProperty() const \return BindingProperty named name */ -BindingProperty ModelNode::bindingProperty(const PropertyName &name) const +BindingProperty ModelNode::bindingProperty(PropertyNameView name) const { if (!isValid()) return {}; @@ -370,7 +346,7 @@ BindingProperty ModelNode::bindingProperty(const PropertyName &name) const return BindingProperty(name, m_internalNode, model(), view()); } -SignalHandlerProperty ModelNode::signalHandlerProperty(const PropertyName &name) const +SignalHandlerProperty ModelNode::signalHandlerProperty(PropertyNameView name) const { if (!isValid()) return {}; @@ -378,7 +354,7 @@ SignalHandlerProperty ModelNode::signalHandlerProperty(const PropertyName &name) return SignalHandlerProperty(name, m_internalNode, model(), view()); } -SignalDeclarationProperty ModelNode::signalDeclarationProperty(const PropertyName &name) const +SignalDeclarationProperty ModelNode::signalDeclarationProperty(PropertyNameView name) const { if (!isValid()) return {}; @@ -396,7 +372,7 @@ SignalDeclarationProperty ModelNode::signalDeclarationProperty(const PropertyNam \return NodeProperty named name */ -NodeProperty ModelNode::nodeProperty(const PropertyName &name) const +NodeProperty ModelNode::nodeProperty(PropertyNameView name) const { if (!isValid()) return {}; @@ -414,7 +390,7 @@ NodeProperty ModelNode::nodeProperty(const PropertyName &name) const \return NodeListProperty named name */ -NodeListProperty ModelNode::nodeListProperty(const PropertyName &name) const +NodeListProperty ModelNode::nodeListProperty(PropertyNameView name) const { if (!isValid()) return {}; @@ -422,7 +398,7 @@ NodeListProperty ModelNode::nodeListProperty(const PropertyName &name) const return NodeListProperty(name, m_internalNode, model(), view()); } -NodeAbstractProperty ModelNode::nodeAbstractProperty(const PropertyName &name) const +NodeAbstractProperty ModelNode::nodeAbstractProperty(PropertyNameView name) const { if (!isValid()) return {}; @@ -455,7 +431,7 @@ NodeProperty ModelNode::defaultNodeProperty() const \return VariantProperty named name */ -VariantProperty ModelNode::variantProperty(const PropertyName &name) const +VariantProperty ModelNode::variantProperty(PropertyNameView name) const { if (!isValid()) return {}; @@ -463,7 +439,7 @@ VariantProperty ModelNode::variantProperty(const PropertyName &name) const return VariantProperty(name, m_internalNode, model(), view()); } -AbstractProperty ModelNode::property(const PropertyName &name) const +AbstractProperty ModelNode::property(PropertyNameView name) const { if (!isValid()) return {}; @@ -596,7 +572,8 @@ static QList descendantNodes(const ModelNode &node) static void removeModelNodeFromSelection(const ModelNode &node) { // remove nodes from the active selection - QList selectedList = node.view()->selectedModelNodes(); + auto model = node.model(); + QList selectedList = model->selectedNodes(node.view()); const QList descendants = descendantNodes(node); for (const ModelNode &descendantNode : descendants) @@ -604,7 +581,7 @@ static void removeModelNodeFromSelection(const ModelNode &node) selectedList.removeAll(node); - node.view()->setSelectedModelNodes(selectedList); + model->setSelectedModelNodes(selectedList); } /*! \brief complete removes this ModelNode from the Model @@ -990,6 +967,8 @@ void ModelNode::setAuxiliaryData(AuxiliaryDataType type, void ModelNode::setAuxiliaryData(AuxiliaryDataKeyView key, const QVariant &data) const { if (isValid()) { + if (key.type == AuxiliaryDataType::Persistent) + ensureIdExists(); Internal::WriteLocker locker(m_model.data()); m_model->d->setAuxiliaryData(internalNode(), key, data); } @@ -997,21 +976,32 @@ void ModelNode::setAuxiliaryData(AuxiliaryDataKeyView key, const QVariant &data) void ModelNode::setAuxiliaryDataWithoutLock(AuxiliaryDataKeyView key, const QVariant &data) const { - if (isValid()) + if (isValid()) { + if (key.type == AuxiliaryDataType::Persistent) + ensureIdExists(); + m_model->d->setAuxiliaryData(internalNode(), key, data); + } } void ModelNode::setAuxiliaryDataWithoutLock(AuxiliaryDataType type, Utils::SmallStringView name, const QVariant &data) const { - if (isValid()) + if (isValid()) { + if (type == AuxiliaryDataType::Persistent) + ensureIdExists(); + m_model->d->setAuxiliaryData(internalNode(), {type, name}, data); + } } void ModelNode::removeAuxiliaryData(AuxiliaryDataKeyView key) const { if (isValid()) { + if (key.type == AuxiliaryDataType::Persistent) + ensureIdExists(); + Internal::WriteLocker locker(m_model.data()); m_model->d->removeAuxiliaryData(internalNode(), key); } @@ -1035,6 +1025,14 @@ bool ModelNode::hasAuxiliaryData(AuxiliaryDataType type, Utils::SmallStringView return hasAuxiliaryData({type, name}); } +bool ModelNode::hasAuxiliaryData(AuxiliaryDataType type) const +{ + if (!isValid()) + return false; + + return m_internalNode->hasAuxiliaryData(type); +} + AuxiliaryDatasForType ModelNode::auxiliaryData(AuxiliaryDataType type) const { if (!isValid()) diff --git a/src/plugins/qmldesigner/designercore/model/modelutils.cpp b/src/plugins/qmldesigner/designercore/model/modelutils.cpp deleted file mode 100644 index 6c3e1ea50f5..00000000000 --- a/src/plugins/qmldesigner/designercore/model/modelutils.cpp +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright (C) 2023 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "modelutils.h" - -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -namespace QmlDesigner::ModelUtils { - -namespace { - -enum class ImportError { EmptyImportName, HasAlreadyImport, NoModule }; - -::Utils::expected findImport(const QString &importName, - const std::function &predicate, - const Imports &imports, - const Imports &modules) -{ - if (importName.isEmpty()) - return ::Utils::make_unexpected(ImportError::EmptyImportName); - - auto hasName = [&](const auto &import) { - return import.url() == importName || import.file() == importName; - }; - - bool hasImport = std::any_of(imports.begin(), imports.end(), hasName); - - if (hasImport) - return ::Utils::make_unexpected(ImportError::HasAlreadyImport); - - auto foundModule = std::find_if(modules.begin(), modules.end(), [&](const Import &import) { - return hasName(import) && predicate(import); - }); - - if (foundModule == modules.end()) - return ::Utils::make_unexpected(ImportError::NoModule); - - return *foundModule; -} - -} // namespace - -bool addImportWithCheck(const QString &importName, - const std::function &predicate, - Model *model) -{ - return addImportsWithCheck({importName}, predicate, model); -} - -bool addImportWithCheck(const QString &importName, Model *model) -{ - return addImportWithCheck( - importName, [](const Import &) { return true; }, model); -} - -bool addImportsWithCheck(const QStringList &importNames, Model *model) -{ - return addImportsWithCheck( - importNames, [](const Import &) { return true; }, model); -} - -bool addImportsWithCheck(const QStringList &importNames, - const std::function &predicate, - Model *model) -{ - const Imports &imports = model->imports(); - const Imports &modules = model->possibleImports(); - - Imports importsToAdd; - importsToAdd.reserve(importNames.size()); - - for (const QString &importName : importNames) { - auto import = findImport(importName, predicate, imports, modules); - - if (import) { - importsToAdd.push_back(*import); - } else { - if (import.error() == ImportError::NoModule) - return false; - else - continue; - } - } - - if (!importsToAdd.isEmpty()) - model->changeImports(std::move(importsToAdd), {}); - - return true; -} - -PropertyMetaInfo metainfo(const AbstractProperty &property) -{ - return metainfo(property.parentModelNode(), property.name()); -} - -PropertyMetaInfo metainfo(const ModelNode &node, const PropertyName &propertyName) -{ - return node.metaInfo().property(propertyName); -} - -QString componentFilePath([[maybe_unused]] const PathCacheType &pathCache, const NodeMetaInfo &metaInfo) -{ -#ifdef QDS_USE_PROJECTSTORAGE - auto typeSourceId = metaInfo.sourceId(); - - if (typeSourceId && metaInfo.isFileComponent()) { - return pathCache.sourcePath(typeSourceId).toQString(); - } - - return {}; -#else - return metaInfo.componentFileName(); -#endif -} - -QString componentFilePath(const ModelNode &node) -{ - if (node) { - const auto &pathCache = node.model()->pathCache(); - return ModelUtils::componentFilePath(pathCache, node.metaInfo()); - } - - return {}; -} - -QList pruneChildren(const QList &nodes) -{ - QList forwardNodes; - QList backNodes; - - auto pushIfIsNotChild = [](QList &container, const ModelNode &node) { - bool hasAncestor = Utils::anyOf(container, [node](const ModelNode &testNode) -> bool { - return testNode.isAncestorOf(node); - }); - if (!hasAncestor) - container.append(node); - }; - - for (const ModelNode &node : nodes | Utils::views::reverse) { - if (node) - pushIfIsNotChild(forwardNodes, node); - } - - for (const ModelNode &node : forwardNodes | Utils::views::reverse) - pushIfIsNotChild(backNodes, node); - - return backNodes; -} - -QList allModelNodesWithId(AbstractView *view) -{ - QTC_ASSERT(view->isAttached(), return {}); - return Utils::filtered(view->allModelNodes(), - [&](const ModelNode &node) { return node.hasId(); }); -} - -bool isThisOrAncestorLocked(const ModelNode &node) -{ - if (!node.isValid()) - return false; - - if (node.locked()) - return true; - - if (node.isRootNode() || !node.hasParentProperty()) - return false; - - return isThisOrAncestorLocked(node.parentProperty().parentModelNode()); -} - -/*! - * \brief The lowest common ancestor node for node1 and node2. If one of the nodes (Node A) is - * the ancestor of the other node, the return value is Node A and not the parent of Node A. - * \param node1 First node - * \param node2 Second node - * \param depthOfLCA Depth of the return value - * \param depthOfNode1 Depth of node1. Use this parameter for optimization - * \param depthOfNode2 Depth of node2. Use this parameter for optimization - */ -namespace { -ModelNode lowestCommonAncestor(const ModelNode &node1, - const ModelNode &node2, - int &depthOfLCA, - const int &depthOfNode1 = -1, - const int &depthOfNode2 = -1) -{ - auto depthOfNode = [](const ModelNode &node) -> int { - int depth = 0; - ModelNode parentNode = node; - while (parentNode && !parentNode.isRootNode()) { - depth++; - parentNode = parentNode.parentProperty().parentModelNode(); - } - - return depth; - }; - - if (node1 == node2) { - depthOfLCA = (depthOfNode1 < 0) ? ((depthOfNode2 < 0) ? depthOfNode(node1) : depthOfNode2) - : depthOfNode1; - return node1; - } - - if (node1.model() != node2.model()) { - depthOfLCA = -1; - return {}; - } - - if (node1.isRootNode()) { - depthOfLCA = 0; - return node1; - } - - if (node2.isRootNode()) { - depthOfLCA = 0; - return node2; - } - - ModelNode nodeLower = node1; - ModelNode nodeHigher = node2; - int depthLower = (depthOfNode1 < 0) ? depthOfNode(nodeLower) : depthOfNode1; - int depthHigher = (depthOfNode2 < 0) ? depthOfNode(nodeHigher) : depthOfNode2; - - if (depthLower > depthHigher) { - std::swap(depthLower, depthHigher); - std::swap(nodeLower, nodeHigher); - } - - int depthDiff = depthHigher - depthLower; - while (depthDiff--) - nodeHigher = nodeHigher.parentProperty().parentModelNode(); - - while (nodeLower != nodeHigher) { - nodeLower = nodeLower.parentProperty().parentModelNode(); - nodeHigher = nodeHigher.parentProperty().parentModelNode(); - --depthLower; - } - - depthOfLCA = depthLower; - return nodeLower; -} -} // namespace - -/*! - * \brief The lowest common node containing all nodes. If one of the nodes (Node A) is - * the ancestor of the other nodes, the return value is Node A and not the parent of Node A. - */ -ModelNode lowestCommonAncestor(Utils::span nodes) -{ - if (nodes.empty()) - return {}; - - ModelNode accumulatedNode = nodes.front(); - int accumulatedNodeDepth = -1; - for (const ModelNode &node : nodes.subspan(1)) { - accumulatedNode = lowestCommonAncestor(accumulatedNode, - node, - accumulatedNodeDepth, - accumulatedNodeDepth); - if (!accumulatedNode) - return {}; - } - - return accumulatedNode; -} - -} // namespace QmlDesigner::ModelUtils diff --git a/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp index f131137ae87..66d9974f217 100644 --- a/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp @@ -13,6 +13,8 @@ #include +#include + namespace QmlDesigner { NodeAbstractProperty::NodeAbstractProperty() = default; @@ -22,11 +24,6 @@ NodeAbstractProperty::NodeAbstractProperty(const NodeAbstractProperty &property, { } -NodeAbstractProperty::NodeAbstractProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model *model, AbstractView *view) - : AbstractProperty(propertyName, internalNode, model, view) -{ -} - NodeAbstractProperty::NodeAbstractProperty(const Internal::InternalNodeAbstractProperty::Pointer &property, Model *model, AbstractView *view) : AbstractProperty(property, model, view) {} @@ -218,12 +215,14 @@ bool operator !=(const NodeAbstractProperty &property1, const NodeAbstractProper QDebug operator<<(QDebug debug, const NodeAbstractProperty &property) { - return debug.nospace() << "NodeAbstractProperty(" << (property.isValid() ? property.name() : PropertyName("invalid")) << ')'; + return debug.nospace() << "NodeAbstractProperty(" + << (property.isValid() ? property.name() : PropertyNameView("invalid")) + << ')'; } QTextStream& operator<<(QTextStream &stream, const NodeAbstractProperty &property) { - stream << "NodeAbstractProperty(" << property.name() << ')'; + stream << "NodeAbstractProperty(" << property.name().toByteArray() << ')'; return stream; } diff --git a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp index 51ca5eb7050..3f9e54bd975 100644 --- a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp @@ -23,14 +23,6 @@ Internal::NodeListPropertyIterator::value_type Internal::NodeListPropertyIterato NodeListProperty::NodeListProperty() = default; -NodeListProperty::NodeListProperty(const PropertyName &propertyName, - const Internal::InternalNodePointer &internalNode, - Model *model, - AbstractView *view) - : NodeAbstractProperty(propertyName, internalNode, model, view) -{ -} - NodeListProperty::NodeListProperty(const Internal::InternalNodeListProperty::Pointer &internalNodeListProperty, Model* model, AbstractView *view) : NodeAbstractProperty(internalNodeListProperty, model, view) { diff --git a/src/plugins/qmldesigner/designercore/model/nodeproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodeproperty.cpp index 330b7e75e93..e8988c7433e 100644 --- a/src/plugins/qmldesigner/designercore/model/nodeproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodeproperty.cpp @@ -10,12 +10,6 @@ namespace QmlDesigner { NodeProperty::NodeProperty() = default; -NodeProperty::NodeProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view) - : NodeAbstractProperty(propertyName, internalNode, model, view) -{ - -} - void NodeProperty::setModelNode(const ModelNode &modelNode) { if (!isValid()) diff --git a/src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp b/src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp index fcae441e529..28bceb42a45 100644 --- a/src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp @@ -15,11 +15,6 @@ SignalHandlerProperty::SignalHandlerProperty(const SignalHandlerProperty &proper { } -SignalHandlerProperty::SignalHandlerProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view) - : AbstractProperty(propertyName, internalNode, model, view) -{ -} - void SignalHandlerProperty::setSource(const QString &source) { Internal::WriteLocker locker(model()); @@ -56,11 +51,11 @@ QString SignalHandlerProperty::source() const return QString(); } -PropertyName SignalHandlerProperty::prefixAdded(const PropertyName &propertyName) +PropertyName SignalHandlerProperty::prefixAdded(PropertyNameView propertyName) { QString nameAsString = QString::fromUtf8(propertyName); - if (nameAsString.startsWith("on")) - return propertyName; + if (propertyName.startsWith("on")) + return propertyName.toByteArray(); QChar firstChar = nameAsString.at(0).toUpper(); nameAsString[0] = firstChar; @@ -69,11 +64,11 @@ PropertyName SignalHandlerProperty::prefixAdded(const PropertyName &propertyName return nameAsString.toLatin1(); } -PropertyName SignalHandlerProperty::prefixRemoved(const PropertyName &propertyName) +PropertyName SignalHandlerProperty::prefixRemoved(PropertyNameView propertyName) { QString nameAsString = QString::fromUtf8(propertyName); if (!nameAsString.startsWith("on")) - return propertyName; + return propertyName.toByteArray(); nameAsString.remove(0, 2); QChar firstChar = nameAsString.at(0).toLower(); @@ -89,15 +84,6 @@ SignalDeclarationProperty::SignalDeclarationProperty(const SignalDeclarationProp : AbstractProperty(property.name(), property.internalNodeSharedPointer(), property.model(), view) {} -SignalDeclarationProperty::SignalDeclarationProperty( - const PropertyName &propertyName, - const Internal::InternalNodePointer &internalNode, - Model *model, - AbstractView *view) - : AbstractProperty(propertyName, internalNode, model, view) -{ -} - void SignalDeclarationProperty::setSignature(const QString &signature) { Internal::WriteLocker locker(model()); diff --git a/src/plugins/qmldesigner/designercore/model/variantproperty.cpp b/src/plugins/qmldesigner/designercore/model/variantproperty.cpp index 37d52ceb19f..a64f372a8ea 100644 --- a/src/plugins/qmldesigner/designercore/model/variantproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/variantproperty.cpp @@ -7,7 +7,7 @@ #include "model.h" #include "model_p.h" - +#include namespace QmlDesigner { @@ -19,11 +19,6 @@ VariantProperty::VariantProperty(const VariantProperty &property, AbstractView * } -VariantProperty::VariantProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view) : - AbstractProperty(propertyName, internalNode, model, view) -{ -} - void VariantProperty::setValue(const QVariant &value) { if (!isValid()) @@ -114,7 +109,9 @@ QDebug operator<<(QDebug debug, const VariantProperty &property) QTextStream& operator<<(QTextStream &stream, const VariantProperty &property) { - stream << "VariantProperty(" << property.name() << ',' << ' ' << property.value().toString() << ' ' << property.value().typeName() << property.parentModelNode() << ')'; + stream << "VariantProperty(" << property.name().toByteArray() << ',' << ' ' + << property.value().toString() << ' ' << property.value().typeName() + << property.parentModelNode() << ')'; return stream; } diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp index 2283b64945a..cd1647c4034 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp @@ -64,8 +64,11 @@ struct ProjectStorage::Statements "ORDER BY minorVersion DESC " "LIMIT 1", database}; - mutable Sqlite::ReadStatement<3, 1> selectPropertyDeclarationResultByPropertyDeclarationIdStatement{ - "SELECT propertyTypeId, propertyDeclarationId, propertyTraits " + mutable Sqlite::ReadStatement<4, 1> selectPropertyDeclarationResultByPropertyDeclarationIdStatement{ + "SELECT propertyImportedTypeNameId, " + " propertyTypeId, " + " propertyDeclarationId, " + " propertyTraits " "FROM propertyDeclarations " "WHERE propertyDeclarationId=?1 " "LIMIT 1", @@ -78,16 +81,14 @@ struct ProjectStorage::Statements "SELECT sourceContextPath, sourceContextId FROM sourceContexts", database}; Sqlite::WriteStatement<1> insertIntoSourceContextsStatement{ "INSERT INTO sourceContexts(sourceContextPath) VALUES (?)", database}; - mutable Sqlite::ReadStatement<1, 2> selectSourceIdFromSourcesBySourceContextIdAndSourceNameStatement{ - "SELECT sourceId FROM sources WHERE sourceContextId = ? AND sourceName = ?", database}; - mutable Sqlite::ReadStatement<2, 1> selectSourceNameAndSourceContextIdFromSourcesBySourceIdStatement{ - "SELECT sourceName, sourceContextId FROM sources WHERE sourceId = ?", database}; - mutable Sqlite::ReadStatement<1, 1> selectSourceContextIdFromSourcesBySourceIdStatement{ - "SELECT sourceContextId FROM sources WHERE sourceId = ?", database}; - Sqlite::WriteStatement<2> insertIntoSourcesStatement{ - "INSERT INTO sources(sourceContextId, sourceName) VALUES (?,?)", database}; - mutable Sqlite::ReadStatement<3> selectAllSourcesStatement{ - "SELECT sourceName, sourceContextId, sourceId FROM sources", database}; + mutable Sqlite::ReadStatement<1, 1> selectSourceNameIdFromSourceNamesBySourceNameStatement{ + "SELECT sourceNameId FROM sourceNames WHERE sourceName = ?", database}; + mutable Sqlite::ReadStatement<1, 1> selectSourceNameFromSourceNamesBySourceNameIdStatement{ + "SELECT sourceName FROM sourceNames WHERE sourceNameId = ?", database}; + Sqlite::WriteStatement<1> insertIntoSourcesStatement{ + "INSERT INTO sourceNames(sourceName) VALUES (?)", database}; + mutable Sqlite::ReadStatement<2> selectAllSourcesStatement{ + "SELECT sourceName, sourceNameId FROM sourceNames", database}; mutable Sqlite::ReadStatement<8, 1> selectTypeByTypeIdStatement{ "SELECT sourceId, t.name, t.typeId, prototypeId, extensionId, traits, annotationTraits, " "pd.name " @@ -141,25 +142,63 @@ struct ProjectStorage::Statements Sqlite::WriteStatement<1> deleteSignalDeclarationByTypeIdStatement{ "DELETE FROM signalDeclarations WHERE typeId=?", database}; Sqlite::WriteStatement<1> deleteTypeStatement{"DELETE FROM types WHERE typeId=?", database}; - mutable Sqlite::ReadStatement<4, 1> selectPropertyDeclarationsByTypeIdStatement{ - "SELECT name, propertyTypeId, propertyTraits, (SELECT name FROM " - "propertyDeclarations WHERE propertyDeclarationId=pd.aliasPropertyDeclarationId) FROM " - "propertyDeclarations AS pd WHERE typeId=?", + mutable Sqlite::ReadStatement<6, 1> selectPropertyDeclarationsByTypeIdStatement{ + "SELECT " + " propertyDeclarationId, " + " name, " + " propertyTypeId, " + " propertyTraits, " + " (SELECT name " + " FROM propertyDeclarations " + " WHERE propertyDeclarationId=pd.aliasPropertyDeclarationId), " + " typeId " + "FROM propertyDeclarations AS pd " + "WHERE typeId=?", database}; Sqlite::ReadStatement<6, 1> selectPropertyDeclarationsForTypeIdStatement{ - "SELECT name, propertyTraits, propertyTypeId, propertyImportedTypeNameId, " - "propertyDeclarationId, aliasPropertyDeclarationId FROM propertyDeclarations " - "WHERE typeId=? ORDER BY name", + "SELECT " + " name, " + " propertyTraits, " + " propertyTypeId, " + " propertyImportedTypeNameId, " + " propertyDeclarationId, " + " aliasPropertyDeclarationId " + "FROM propertyDeclarations " + "WHERE typeId=? " + "ORDER BY name", database}; Sqlite::ReadWriteStatement<1, 5> insertPropertyDeclarationStatement{ - "INSERT INTO propertyDeclarations(typeId, name, propertyTypeId, propertyTraits, " - "propertyImportedTypeNameId, aliasPropertyDeclarationId) VALUES(?1, ?2, ?3, ?4, ?5, NULL) " + "INSERT INTO propertyDeclarations(" + " typeId, " + " name, " + " propertyTypeId, " + " propertyTraits, " + " propertyImportedTypeNameId, " + " aliasPropertyDeclarationId) " + "VALUES(?1, ?2, ?3, ?4, ?5, NULL) " "RETURNING propertyDeclarationId", database}; Sqlite::WriteStatement<4> updatePropertyDeclarationStatement{ - "UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTraits=?3, " - "propertyImportedTypeNameId=?4, aliasPropertyDeclarationId=NULL WHERE " - "propertyDeclarationId=?1", + "UPDATE propertyDeclarations " + "SET " + " propertyTypeId=?2, " + " propertyTraits=?3, " + " propertyImportedTypeNameId=?4, " + " aliasPropertyImportedTypeNameId=NULL, " + " aliasPropertyDeclarationName=NULL, " + " aliasPropertyDeclarationTailName=NULL, " + " aliasPropertyDeclarationId=NULL, " + " aliasPropertyDeclarationTailId=NULL " + "WHERE propertyDeclarationId=?1", + database}; + Sqlite::WriteStatement<2> resetAliasPropertyDeclarationStatement{ + "UPDATE propertyDeclarations " + "SET propertyTypeId=NULL, " + " propertyTraits=?2, " + " propertyImportedTypeNameId=NULL, " + " aliasPropertyDeclarationId=NULL, " + " aliasPropertyDeclarationTailId=NULL " + "WHERE propertyDeclarationId=?1", database}; Sqlite::WriteStatement<3> updatePropertyAliasDeclarationRecursivelyWithTypeAndTraitsStatement{ "WITH RECURSIVE " @@ -193,17 +232,30 @@ struct ProjectStorage::Statements Sqlite::WriteStatement<1> deletePropertyDeclarationStatement{ "DELETE FROM propertyDeclarations WHERE propertyDeclarationId=?", database}; Sqlite::ReadStatement<3, 1> selectPropertyDeclarationsWithAliasForTypeIdStatement{ - "SELECT name, propertyDeclarationId, aliasPropertyDeclarationId FROM propertyDeclarations " - "WHERE typeId=? AND aliasPropertyDeclarationId IS NOT NULL ORDER BY name", + "SELECT name, " + " propertyDeclarationId, " + " aliasPropertyDeclarationId " + "FROM propertyDeclarations " + "WHERE typeId=? AND aliasPropertyDeclarationId IS NOT NULL " + "ORDER BY name", database}; Sqlite::WriteStatement<5> updatePropertyDeclarationWithAliasAndTypeStatement{ - "UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTraits=?3, " - "propertyImportedTypeNameId=?4, aliasPropertyDeclarationId=?5 WHERE " - "propertyDeclarationId=?1", + "UPDATE propertyDeclarations " + "SET propertyTypeId=?2, " + " propertyTraits=?3, " + " propertyImportedTypeNameId=?4, " + " aliasPropertyDeclarationId=?5 " + "WHERE propertyDeclarationId=?1", database}; - Sqlite::ReadWriteStatement<1, 2> insertAliasPropertyDeclarationStatement{ - "INSERT INTO propertyDeclarations(typeId, name) VALUES(?1, ?2) RETURNING " - "propertyDeclarationId", + Sqlite::ReadWriteStatement<1, 5> insertAliasPropertyDeclarationStatement{ + "INSERT INTO propertyDeclarations(" + " typeId, " + " name, " + " aliasPropertyImportedTypeNameId, " + " aliasPropertyDeclarationName, " + " aliasPropertyDeclarationTailName) " + "VALUES(?1, ?2, ?3, ?4, ?5) " + "RETURNING propertyDeclarationId", database}; mutable Sqlite::ReadStatement<4, 1> selectFunctionDeclarationsForTypeIdStatement{ "SELECT name, returnTypeName, signature, functionDeclarationId FROM " @@ -334,26 +386,26 @@ struct ProjectStorage::Statements "NULL OR propertyTypeId IS NOT NULL OR propertyTraits IS NOT NULL)", database}; Sqlite::ReadStatement<5, 1> selectAliasPropertiesDeclarationForPropertiesWithTypeIdStatement{ - "SELECT alias.typeId, alias.propertyDeclarationId, alias.propertyImportedTypeNameId, " + "SELECT alias.typeId, alias.propertyDeclarationId, alias.aliasPropertyImportedTypeNameId, " " alias.aliasPropertyDeclarationId, alias.aliasPropertyDeclarationTailId " "FROM propertyDeclarations AS alias JOIN propertyDeclarations AS target " " ON alias.aliasPropertyDeclarationId=target.propertyDeclarationId OR " " alias.aliasPropertyDeclarationTailId=target.propertyDeclarationId " "WHERE alias.propertyTypeId=?1 " "UNION ALL " - "SELECT alias.typeId, alias.propertyDeclarationId, alias.propertyImportedTypeNameId, " + "SELECT alias.typeId, alias.propertyDeclarationId, alias.aliasPropertyImportedTypeNameId, " " alias.aliasPropertyDeclarationId, alias.aliasPropertyDeclarationTailId " "FROM propertyDeclarations AS alias JOIN propertyDeclarations AS target " " ON alias.aliasPropertyDeclarationId=target.propertyDeclarationId OR " " alias.aliasPropertyDeclarationTailId=target.propertyDeclarationId " "WHERE target.typeId=?1 " "UNION ALL " - "SELECT alias.typeId, alias.propertyDeclarationId, alias.propertyImportedTypeNameId, " + "SELECT alias.typeId, alias.propertyDeclarationId, alias.aliasPropertyImportedTypeNameId, " " alias.aliasPropertyDeclarationId, alias.aliasPropertyDeclarationTailId " "FROM propertyDeclarations AS alias JOIN propertyDeclarations AS target " " ON alias.aliasPropertyDeclarationId=target.propertyDeclarationId OR " " alias.aliasPropertyDeclarationTailId=target.propertyDeclarationId " - "WHERE alias.propertyImportedTypeNameId IN " + "WHERE alias.aliasPropertyImportedTypeNameId IN " " (SELECT importedTypeNameId FROM exportedTypeNames JOIN importedTypeNames USING(name) " " WHERE typeId=?1)", database}; @@ -376,6 +428,30 @@ struct ProjectStorage::Statements "aliasPropertyDeclarationId IS NULL RETURNING typeId, propertyDeclarationId, " "propertyImportedTypeNameId", database}; + Sqlite::ReadWriteStatement<3, 2> selectPropertyDeclarationForPrototypeIdAndTypeNameStatement{ + "SELECT typeId, propertyDeclarationId, propertyImportedTypeNameId " + "FROM propertyDeclarations " + "WHERE propertyTypeId IS ?2 " + " AND propertyImportedTypeNameId IN (SELECT importedTypeNameId " + " FROM " + " importedTypeNames WHERE name=?1)", + database}; + Sqlite::ReadWriteStatement<5, 2> selectAliasPropertyDeclarationForPrototypeIdAndTypeNameStatement{ + "SELECT alias.typeId, " + " alias.propertyDeclarationId, " + " alias.aliasPropertyImportedTypeNameId, " + " alias.aliasPropertyDeclarationId, " + " alias.aliasPropertyDeclarationTailId " + "FROM propertyDeclarations AS alias " + " JOIN propertyDeclarations AS target " + " ON alias.aliasPropertyDeclarationId=target.propertyDeclarationId " + " OR alias.aliasPropertyDeclarationTailId=target.propertyDeclarationId " + "WHERE alias.propertyTypeId IS ?2 " + " AND target.propertyImportedTypeNameId IN " + " (SELECT importedTypeNameId " + " FROM importedTypeNames " + " WHERE name=?1)", + database}; mutable Sqlite::ReadStatement<1, 1> selectPropertyNameStatement{ "SELECT name FROM propertyDeclarations WHERE propertyDeclarationId=?", database}; Sqlite::WriteStatement<2> updatePropertyDeclarationTypeStatement{ @@ -418,7 +494,7 @@ struct ProjectStorage::Statements "RETURNING typeId, prototypeNameId, extensionNameId", database}; Sqlite::ReadStatement<2, 2> selectTypeIdForExtensionIdAndTypeNameStatement{ - "SELECT typeId , prototypeNameId " + "SELECT typeId , extensionNameId " "FROM types " "WHERE extensionNameId IN ( " " SELECT importedTypeNameId " @@ -443,11 +519,12 @@ struct ProjectStorage::Statements "SELECT typeId FROM prototypes WHERE typeId IS NOT NULL", database}; Sqlite::WriteStatement<3> updatePropertyDeclarationAliasIdAndTypeNameIdStatement{ - "UPDATE propertyDeclarations SET aliasPropertyDeclarationId=?2, " - "propertyImportedTypeNameId=?3 WHERE propertyDeclarationId=?1 AND " - "(aliasPropertyDeclarationId IS NOT ?2 OR propertyImportedTypeNameId IS NOT ?3)", + "UPDATE propertyDeclarations " + "SET aliasPropertyDeclarationId=?2, " + " propertyImportedTypeNameId=?3 " + "WHERE propertyDeclarationId=?1", database}; - Sqlite::WriteStatement<1> updatetPropertiesDeclarationValuesOfAliasStatement{ + Sqlite::WriteStatement<1> updatePropertiesDeclarationValuesOfAliasStatement{ "WITH RECURSIVE " " properties(propertyDeclarationId, propertyTypeId, propertyTraits) AS ( " " SELECT aliasPropertyDeclarationId, propertyTypeId, propertyTraits FROM " @@ -542,7 +619,7 @@ struct ProjectStorage::Statements "ORDER BY itn.kind, etn.majorVersion DESC NULLS FIRST, etn.minorVersion DESC NULLS FIRST " "LIMIT 1", database}; - Sqlite::WriteStatement<0> deleteAllSourcesStatement{"DELETE FROM sources", database}; + Sqlite::WriteStatement<0> deleteAllSourceNamesStatement{"DELETE FROM sourceNames", database}; Sqlite::WriteStatement<0> deleteAllSourceContextsStatement{"DELETE FROM sourceContexts", database}; mutable Sqlite::ReadStatement<6, 1> selectExportedTypesForSourceIdsStatement{ "SELECT moduleId, name, ifnull(majorVersion, -1), ifnull(minorVersion, -1), typeId, " @@ -794,6 +871,20 @@ struct ProjectStorage::Statements " WHERE prototypeId=ts.typeId OR extensionId=ts.typeId)" "SELECT typeId FROM typeSelection", database}; + mutable Sqlite::ReadStatement<6, 0> selectBrokenAliasPropertyDeclarationsStatement{ + "SELECT typeId, " + " propertyDeclarationId, " + " aliasPropertyImportedTypeNameId, " + " aliasPropertyDeclarationName, " + " aliasPropertyDeclarationTailName, " + " sourceId " + "FROM propertyDeclarations JOIN types USING(typeId) " + "WHERE " + " aliasPropertyImportedTypeNameId IS NOT NULL " + " AND " + " propertyImportedTypeNameId IS NULL " + "LIMIT 1", + database}; }; class ProjectStorage::Initializer @@ -804,7 +895,7 @@ public: if (!isInitialized) { auto moduleIdColumn = createModulesTable(database); createSourceContextsTable(database); - createSourcesTable(database); + createSourceNamesTable(database); createTypesAndePropertyDeclarationsTables(database, moduleIdColumn); createExportedTypeNamesTable(database, moduleIdColumn); createImportedTypeNamesTable(database); @@ -834,22 +925,14 @@ public: table.initialize(database); } - void createSourcesTable(Database &database) + void createSourceNamesTable(Database &database) { Sqlite::StrictTable table; table.setUseIfNotExists(true); - table.setName("sources"); - table.addColumn("sourceId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}}); - const auto &sourceContextIdColumn = table.addColumn( - "sourceContextId", - Sqlite::StrictColumnType::Integer, - {Sqlite::NotNull{}, - Sqlite::ForeignKey{"sourceContexts", - "sourceContextId", - Sqlite::ForeignKeyAction::NoAction, - Sqlite::ForeignKeyAction::Cascade}}); + table.setName("sourceNames"); + table.addColumn("sourceNameId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}}); const auto &sourceNameColumn = table.addColumn("sourceName", Sqlite::StrictColumnType::Text); - table.addUniqueIndex({sourceContextIdColumn, sourceNameColumn}); + table.addUniqueIndex({sourceNameColumn}); table.initialize(database); } @@ -893,14 +976,17 @@ public: {Sqlite::PrimaryKey{}}); auto &typeIdColumn = propertyDeclarationTable.addColumn("typeId"); auto &nameColumn = propertyDeclarationTable.addColumn("name"); - auto &propertyTypeIdColumn = propertyDeclarationTable.addForeignKeyColumn( - "propertyTypeId", - typesTable, - Sqlite::ForeignKeyAction::NoAction, - Sqlite::ForeignKeyAction::Restrict); + auto &propertyTypeIdColumn = propertyDeclarationTable.addColumn( + "propertyTypeId", Sqlite::StrictColumnType::Integer); propertyDeclarationTable.addColumn("propertyTraits", Sqlite::StrictColumnType::Integer); - propertyDeclarationTable.addColumn("propertyImportedTypeNameId", - Sqlite::StrictColumnType::Integer); + auto &propertyImportedTypeNameIdColumn = propertyDeclarationTable.addColumn( + "propertyImportedTypeNameId", Sqlite::StrictColumnType::Integer); + auto &aliasPropertyImportedTypeNameIdColumn = propertyDeclarationTable.addColumn( + "aliasPropertyImportedTypeNameId", Sqlite::StrictColumnType::Integer); + propertyDeclarationTable.addColumn("aliasPropertyDeclarationName", + Sqlite::StrictColumnType::Text); + propertyDeclarationTable.addColumn("aliasPropertyDeclarationTailName", + Sqlite::StrictColumnType::Text); auto &aliasPropertyDeclarationIdColumn = propertyDeclarationTable.addForeignKeyColumn( "aliasPropertyDeclarationId", propertyDeclarationTable, @@ -913,7 +999,9 @@ public: Sqlite::ForeignKeyAction::Restrict); propertyDeclarationTable.addUniqueIndex({typeIdColumn, nameColumn}); - propertyDeclarationTable.addIndex({propertyTypeIdColumn}); + propertyDeclarationTable.addIndex({propertyTypeIdColumn, propertyImportedTypeNameIdColumn}); + propertyDeclarationTable.addIndex( + {aliasPropertyImportedTypeNameIdColumn, propertyImportedTypeNameIdColumn}); propertyDeclarationTable.addIndex({aliasPropertyDeclarationIdColumn}, "aliasPropertyDeclarationId IS NOT NULL"); propertyDeclarationTable.addIndex({aliasPropertyDeclarationTailIdColumn}, @@ -1119,13 +1207,7 @@ public: Sqlite::StrictTable table; table.setUseIfNotExists(true); table.setName("fileStatuses"); - table.addColumn("sourceId", - Sqlite::StrictColumnType::Integer, - {Sqlite::PrimaryKey{}, - Sqlite::ForeignKey{"sources", - "sourceId", - Sqlite::ForeignKeyAction::NoAction, - Sqlite::ForeignKeyAction::Cascade}}); + table.addColumn("sourceId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}}); table.addColumn("size", Sqlite::StrictColumnType::Integer); table.addColumn("lastModified", Sqlite::StrictColumnType::Integer); @@ -1217,8 +1299,7 @@ void ProjectStorage::synchronize(Storage::Synchronization::SynchronizationPackag TypeIds deletedTypeIds; Sqlite::withImmediateTransaction(database, [&] { - AliasPropertyDeclarations insertedAliasPropertyDeclarations; - AliasPropertyDeclarations updatedAliasPropertyDeclarations; + AliasPropertyDeclarations aliasPropertyDeclarationsToLink; AliasPropertyDeclarations relinkableAliasPropertyDeclarations; PropertyDeclarations relinkablePropertyDeclarations; @@ -1243,8 +1324,7 @@ void ProjectStorage::synchronize(Storage::Synchronization::SynchronizationPackag relinkableExtensions); synchronizeTypes(package.types, updatedTypeIds, - insertedAliasPropertyDeclarations, - updatedAliasPropertyDeclarations, + aliasPropertyDeclarationsToLink, relinkableAliasPropertyDeclarations, relinkablePropertyDeclarations, relinkablePrototypes, @@ -1269,7 +1349,9 @@ void ProjectStorage::synchronize(Storage::Synchronization::SynchronizationPackag relinkableExtensions, deletedTypeIds); - linkAliases(insertedAliasPropertyDeclarations, updatedAliasPropertyDeclarations); + repairBrokenAliasPropertyDeclarations(); + + linkAliases(aliasPropertyDeclarationsToLink, RaiseError::Yes); synchronizeDirectoryInfos(package.directoryInfos, package.updatedDirectoryInfoSourceIds); @@ -2001,6 +2083,7 @@ Storage::Synchronization::Type ProjectStorage::fetchTypeByTypeId(TypeId typeId) type.functionDeclarations = fetchFunctionDeclarations(type.typeId); type.signalDeclarations = fetchSignalDeclarations(type.typeId); type.enumerationDeclarations = fetchEnumerationDeclarations(type.typeId); + type.typeId = typeId; return type; }); @@ -2094,89 +2177,66 @@ Cache::SourceContexts ProjectStorage::fetchAllSourceContexts() const return s->selectAllSourceContextsStatement.valuesWithTransaction(); } -SourceId ProjectStorage::fetchSourceId(SourceContextId sourceContextId, - Utils::SmallStringView sourceName) +SourceNameId ProjectStorage::fetchSourceNameId(Utils::SmallStringView sourceName) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"fetch source id"_t, projectStorageCategory(), - keyValue("source context id", sourceContextId), keyValue("source name", sourceName)}; - auto sourceId = Sqlite::withDeferredTransaction(database, [&] { - return fetchSourceIdUnguarded(sourceContextId, sourceName); + auto sourceNameId = Sqlite::withDeferredTransaction(database, [&] { + return fetchSourceNameIdUnguarded(sourceName); }); - tracer.end(keyValue("source id", sourceId)); + tracer.end(keyValue("source name id", sourceNameId)); - return sourceId; + return sourceNameId; } -Cache::SourceNameAndSourceContextId ProjectStorage::fetchSourceNameAndSourceContextId(SourceId sourceId) const +Utils::SmallString ProjectStorage::fetchSourceName(SourceNameId sourceNameId) const { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"fetch source name and source context id"_t, projectStorageCategory(), - keyValue("source id", sourceId)}; + keyValue("source name id", sourceNameId)}; - auto value = s->selectSourceNameAndSourceContextIdFromSourcesBySourceIdStatement - .valueWithTransaction(sourceId); + auto sourceName = s->selectSourceNameFromSourceNamesBySourceNameIdStatement + .valueWithTransaction(sourceNameId); - if (!value.sourceContextId) - throw SourceIdDoesNotExists(); + if (sourceName.empty()) + throw SourceNameIdDoesNotExists(); - tracer.end(keyValue("source name", value.sourceName), - keyValue("source context id", value.sourceContextId)); + tracer.end(keyValue("source name", sourceName)); - return value; + return sourceName; } void ProjectStorage::clearSources() { Sqlite::withImmediateTransaction(database, [&] { s->deleteAllSourceContextsStatement.execute(); - s->deleteAllSourcesStatement.execute(); + s->deleteAllSourceNamesStatement.execute(); }); } -SourceContextId ProjectStorage::fetchSourceContextId(SourceId sourceId) const -{ - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"fetch source context id"_t, - projectStorageCategory(), - keyValue("source id", sourceId)}; - - auto sourceContextId = s->selectSourceContextIdFromSourcesBySourceIdStatement - .valueWithTransaction(sourceId); - - if (!sourceContextId) - throw SourceIdDoesNotExists(); - - tracer.end(keyValue("source context id", sourceContextId)); - - return sourceContextId; -} - -Cache::Sources ProjectStorage::fetchAllSources() const +Cache::SourceNames ProjectStorage::fetchAllSourceNames() const { NanotraceHR::Tracer tracer{"fetch all sources"_t, projectStorageCategory()}; - return s->selectAllSourcesStatement.valuesWithTransaction(); + return s->selectAllSourcesStatement.valuesWithTransaction(); } -SourceId ProjectStorage::fetchSourceIdUnguarded(SourceContextId sourceContextId, - Utils::SmallStringView sourceName) +SourceNameId ProjectStorage::fetchSourceNameIdUnguarded(Utils::SmallStringView sourceName) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"fetch source id unguarded"_t, projectStorageCategory(), - keyValue("source context id", sourceContextId), keyValue("source name", sourceName)}; - auto sourceId = readSourceId(sourceContextId, sourceName); + auto sourceId = readSourceNameId(sourceName); if (!sourceId) - sourceId = writeSourceId(sourceContextId, sourceName); + sourceId = writeSourceNameId(sourceName); tracer.end(keyValue("source id", sourceId)); @@ -2525,13 +2585,15 @@ void ProjectStorage::synchronizeTypeAnnotations(Storage::Synchronization::TypeAn void ProjectStorage::synchronizeTypeTrait(const Storage::Synchronization::Type &type) { + if (type.changeLevel == Storage::Synchronization::ChangeLevel::Minimal) + return; + s->updateTypeTraitStatement.write(type.typeId, type.traits.type); } void ProjectStorage::synchronizeTypes(Storage::Synchronization::Types &types, TypeIds &updatedTypeIds, - AliasPropertyDeclarations &insertedAliasPropertyDeclarations, - AliasPropertyDeclarations &updatedAliasPropertyDeclarations, + AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, AliasPropertyDeclarations &relinkableAliasPropertyDeclarations, PropertyDeclarations &relinkablePropertyDeclarations, Prototypes &relinkablePrototypes, @@ -2584,10 +2646,7 @@ void ProjectStorage::synchronizeTypes(Storage::Synchronization::Types &types, syncPrototypesAndExtensions(types, relinkablePrototypes, relinkableExtensions); resetDefaultPropertiesIfChanged(types); resetRemovedAliasPropertyDeclarationsToNull(types, relinkableAliasPropertyDeclarations); - syncDeclarations(types, - insertedAliasPropertyDeclarations, - updatedAliasPropertyDeclarations, - relinkablePropertyDeclarations); + syncDeclarations(types, aliasPropertyDeclarationsToLink, relinkablePropertyDeclarations); syncDefaultProperties(types); } @@ -2869,7 +2928,7 @@ void ProjectStorage::handleAliasPropertyDeclarationsWithPropertyType( auto callback = [&](TypeId typeId_, PropertyDeclarationId propertyDeclarationId, - ImportedTypeNameId propertyImportedTypeNameId, + ImportedTypeNameId aliasPropertyImportedTypeNameId, PropertyDeclarationId aliasPropertyDeclarationId, PropertyDeclarationId aliasPropertyDeclarationTailId) { auto aliasPropertyName = s->selectPropertyNameStatement.value( @@ -2880,10 +2939,11 @@ void ProjectStorage::handleAliasPropertyDeclarationsWithPropertyType( aliasPropertyDeclarationTailId); relinkableAliasPropertyDeclarations.emplace_back(TypeId{typeId_}, - PropertyDeclarationId{propertyDeclarationId}, - ImportedTypeNameId{propertyImportedTypeNameId}, + propertyDeclarationId, + aliasPropertyImportedTypeNameId, std::move(aliasPropertyName), - std::move(aliasPropertyNameTail)); + std::move(aliasPropertyNameTail), + fetchTypeSourceId(typeId_)); s->updateAliasPropertyDeclarationToNullStatement.write(propertyDeclarationId); }; @@ -2905,6 +2965,62 @@ void ProjectStorage::handlePropertyDeclarationWithPropertyType( typeId); } +void ProjectStorage::handlePropertyDeclarationsWithExportedTypeNameAndTypeId( + Utils::SmallStringView exportedTypeName, + TypeId typeId, + PropertyDeclarations &relinkablePropertyDeclarations) +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"handle property declarations with exported type name and type id"_t, + projectStorageCategory(), + keyValue("type name", exportedTypeName), + keyValue("type id", typeId), + keyValue("relinkable property declarations", + relinkablePropertyDeclarations)}; + + s->selectPropertyDeclarationForPrototypeIdAndTypeNameStatement.readTo(relinkablePropertyDeclarations, + exportedTypeName, + typeId); +} + +void ProjectStorage::handleAliasPropertyDeclarationsWithExportedTypeNameAndTypeId( + Utils::SmallStringView exportedTypeName, + TypeId typeId, + AliasPropertyDeclarations &relinkableAliasPropertyDeclarations) +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"handle alias property declarations with exported type name and type id"_t, + projectStorageCategory(), + keyValue("type name", exportedTypeName), + keyValue("type id", typeId), + keyValue("relinkable alias property declarations", + relinkableAliasPropertyDeclarations)}; + + auto callback = [&](TypeId typeId_, + PropertyDeclarationId propertyDeclarationId, + ImportedTypeNameId aliasPropertyImportedTypeNameId, + PropertyDeclarationId aliasPropertyDeclarationId, + PropertyDeclarationId aliasPropertyDeclarationTailId) { + auto aliasPropertyName = s->selectPropertyNameStatement.value( + aliasPropertyDeclarationId); + Utils::SmallString aliasPropertyNameTail; + if (aliasPropertyDeclarationTailId) + aliasPropertyNameTail = s->selectPropertyNameStatement.value( + aliasPropertyDeclarationTailId); + + relinkableAliasPropertyDeclarations.emplace_back(TypeId{typeId_}, + propertyDeclarationId, + aliasPropertyImportedTypeNameId, + std::move(aliasPropertyName), + std::move(aliasPropertyNameTail), + fetchTypeSourceId(typeId_)); + }; + + s->selectAliasPropertyDeclarationForPrototypeIdAndTypeNameStatement.readCallback(callback, + exportedTypeName, + typeId); +} + void ProjectStorage::handlePrototypes(TypeId prototypeId, Prototypes &relinkablePrototypes) { using NanotraceHR::keyValue; @@ -3002,6 +3118,7 @@ void ProjectStorage::relinkAliasPropertyDeclarations(AliasPropertyDeclarations & keyValue("deleted type ids", deletedTypeIds)}; std::sort(aliasPropertyDeclarations.begin(), aliasPropertyDeclarations.end()); + // todo remove duplicates Utils::set_greedy_difference( aliasPropertyDeclarations.cbegin(), @@ -3011,17 +3128,26 @@ void ProjectStorage::relinkAliasPropertyDeclarations(AliasPropertyDeclarations & [&](const AliasPropertyDeclaration &alias) { auto typeId = fetchTypeId(alias.aliasImportedTypeNameId); - if (!typeId) - throw TypeNameDoesNotExists{fetchImportedTypeName(alias.aliasImportedTypeNameId)}; + if (typeId) { + auto propertyDeclaration = fetchPropertyDeclarationByTypeIdAndNameUngarded( + typeId, alias.aliasPropertyName); + if (propertyDeclaration) { + auto [propertyImportedTypeNameId, propertyTypeId, aliasId, propertyTraits] = *propertyDeclaration; - auto [propertyTypeId, aliasId, propertyTraits] = fetchPropertyDeclarationByTypeIdAndNameUngarded( - typeId, alias.aliasPropertyName); + s->updatePropertyDeclarationWithAliasAndTypeStatement + .write(alias.propertyDeclarationId, + propertyTypeId, + propertyTraits, + propertyImportedTypeNameId, + aliasId); + return; + } + } - s->updatePropertyDeclarationWithAliasAndTypeStatement.write(alias.propertyDeclarationId, - propertyTypeId, - propertyTraits, - alias.aliasImportedTypeNameId, - aliasId); + errorNotifier->typeNameCannotBeResolved(fetchImportedTypeName(alias.aliasImportedTypeNameId), + fetchTypeSourceId(alias.typeId)); + s->resetAliasPropertyDeclarationStatement.write(alias.propertyDeclarationId, + Storage::PropertyDeclarationTraits{}); }, TypeCompare{}); } @@ -3037,6 +3163,9 @@ void ProjectStorage::relinkPropertyDeclarations(PropertyDeclarations &relinkable keyValue("deleted type ids", deletedTypeIds)}; std::sort(relinkablePropertyDeclaration.begin(), relinkablePropertyDeclaration.end()); + relinkablePropertyDeclaration.erase(std::unique(relinkablePropertyDeclaration.begin(), + relinkablePropertyDeclaration.end()), + relinkablePropertyDeclaration.end()); Utils::set_greedy_difference( relinkablePropertyDeclaration.cbegin(), @@ -3046,8 +3175,12 @@ void ProjectStorage::relinkPropertyDeclarations(PropertyDeclarations &relinkable [&](const PropertyDeclaration &property) { TypeId propertyTypeId = fetchTypeId(property.importedTypeNameId); - if (!propertyTypeId) - throw TypeNameDoesNotExists{fetchImportedTypeName(property.importedTypeNameId)}; + if (!propertyTypeId) { + errorNotifier->typeNameCannotBeResolved(fetchImportedTypeName( + property.importedTypeNameId), + fetchTypeSourceId(property.typeId)); + propertyTypeId = TypeId{}; + } s->updatePropertyDeclarationTypeStatement.write(property.propertyDeclarationId, propertyTypeId); @@ -3156,11 +3289,15 @@ PropertyDeclarationId ProjectStorage::fetchAliasId(TypeId aliasTypeId, auto stemAlias = fetchPropertyDeclarationByTypeIdAndNameUngarded(aliasTypeId, aliasPropertyName); - return fetchPropertyDeclarationIdByTypeIdAndNameUngarded(stemAlias.propertyTypeId, + if (!stemAlias) + return PropertyDeclarationId{}; + + return fetchPropertyDeclarationIdByTypeIdAndNameUngarded(stemAlias->propertyTypeId, aliasPropertyNameTail); } -void ProjectStorage::linkAliasPropertyDeclarationAliasIds(const AliasPropertyDeclarations &aliasDeclarations) +void ProjectStorage::linkAliasPropertyDeclarationAliasIds( + const AliasPropertyDeclarations &aliasDeclarations, RaiseError raiseError) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"link alias property declarations alias ids"_t, @@ -3170,17 +3307,34 @@ void ProjectStorage::linkAliasPropertyDeclarationAliasIds(const AliasPropertyDec for (const auto &aliasDeclaration : aliasDeclarations) { auto aliasTypeId = fetchTypeId(aliasDeclaration.aliasImportedTypeNameId); - if (!aliasTypeId) { - throw TypeNameDoesNotExists{ - fetchImportedTypeName(aliasDeclaration.aliasImportedTypeNameId)}; + if (aliasTypeId) { + auto aliasId = fetchAliasId(aliasTypeId, + aliasDeclaration.aliasPropertyName, + aliasDeclaration.aliasPropertyNameTail); + + if (aliasId) { + s->updatePropertyDeclarationAliasIdAndTypeNameIdStatement + .write(aliasDeclaration.propertyDeclarationId, + aliasId, + aliasDeclaration.aliasImportedTypeNameId); + } else { + s->resetAliasPropertyDeclarationStatement.write(aliasDeclaration.propertyDeclarationId, + Storage::PropertyDeclarationTraits{}); + s->updatePropertyAliasDeclarationRecursivelyWithTypeAndTraitsStatement + .write(aliasDeclaration.propertyDeclarationId, + TypeId{}, + Storage::PropertyDeclarationTraits{}); + + errorNotifier->propertyNameDoesNotExists(aliasDeclaration.composedProperyName(), + aliasDeclaration.sourceId); + } + } else if (raiseError == RaiseError::Yes) { + errorNotifier->typeNameCannotBeResolved(fetchImportedTypeName( + aliasDeclaration.aliasImportedTypeNameId), + aliasDeclaration.sourceId); + s->resetAliasPropertyDeclarationStatement.write(aliasDeclaration.propertyDeclarationId, + Storage::PropertyDeclarationTraits{}); } - - auto aliasId = fetchAliasId(aliasTypeId, - aliasDeclaration.aliasPropertyName, - aliasDeclaration.aliasPropertyNameTail); - - s->updatePropertyDeclarationAliasIdAndTypeNameIdStatement.write( - aliasDeclaration.propertyDeclarationId, aliasId, aliasDeclaration.aliasImportedTypeNameId); } } @@ -3192,7 +3346,7 @@ void ProjectStorage::updateAliasPropertyDeclarationValues(const AliasPropertyDec keyValue("alias property declarations", aliasDeclarations)}; for (const auto &aliasDeclaration : aliasDeclarations) { - s->updatetPropertiesDeclarationValuesOfAliasStatement.write( + s->updatePropertiesDeclarationValuesOfAliasStatement.write( aliasDeclaration.propertyDeclarationId); s->updatePropertyAliasDeclarationRecursivelyStatement.write( aliasDeclaration.propertyDeclarationId); @@ -3209,20 +3363,29 @@ void ProjectStorage::checkAliasPropertyDeclarationCycles(const AliasPropertyDecl checkForAliasChainCycle(aliasDeclaration.propertyDeclarationId); } -void ProjectStorage::linkAliases(const AliasPropertyDeclarations &insertedAliasPropertyDeclarations, - const AliasPropertyDeclarations &updatedAliasPropertyDeclarations) +void ProjectStorage::linkAliases(const AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, + RaiseError raiseError) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"link aliases"_t, projectStorageCategory()}; - linkAliasPropertyDeclarationAliasIds(insertedAliasPropertyDeclarations); - linkAliasPropertyDeclarationAliasIds(updatedAliasPropertyDeclarations); + linkAliasPropertyDeclarationAliasIds(aliasPropertyDeclarationsToLink, raiseError); - checkAliasPropertyDeclarationCycles(insertedAliasPropertyDeclarations); - checkAliasPropertyDeclarationCycles(updatedAliasPropertyDeclarations); + checkAliasPropertyDeclarationCycles(aliasPropertyDeclarationsToLink); - updateAliasPropertyDeclarationValues(insertedAliasPropertyDeclarations); - updateAliasPropertyDeclarationValues(updatedAliasPropertyDeclarations); + updateAliasPropertyDeclarationValues(aliasPropertyDeclarationsToLink); +} + +void ProjectStorage::repairBrokenAliasPropertyDeclarations() +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"repair broken alias property declarations"_t, + projectStorageCategory()}; + + auto brokenAliasPropertyDeclarations = s->selectBrokenAliasPropertyDeclarationsStatement + .values(); + + linkAliases(brokenAliasPropertyDeclarations, RaiseError::No); } void ProjectStorage::synchronizeExportedTypes(const TypeIds &updatedTypeIds, @@ -3303,6 +3466,12 @@ void ProjectStorage::synchronizeExportedTypes(const TypeIds &updatedTypeIds, throw QmlDesigner::ExportedTypeCannotBeInserted{type.name}; } + handlePropertyDeclarationsWithExportedTypeNameAndTypeId(type.name, + TypeId{}, + relinkablePropertyDeclarations); + handleAliasPropertyDeclarationsWithExportedTypeNameAndTypeId(type.name, + TypeId{}, + relinkableAliasPropertyDeclarations); handlePrototypesWithExportedTypeNameAndTypeId(type.name, unresolvedTypeId, relinkablePrototypes); handleExtensionsWithExportedTypeNameAndTypeId(type.name, unresolvedTypeId, relinkableExtensions); }; @@ -3348,7 +3517,7 @@ void ProjectStorage::synchronizeExportedTypes(const TypeIds &updatedTypeIds, } void ProjectStorage::synchronizePropertyDeclarationsInsertAlias( - AliasPropertyDeclarations &insertedAliasPropertyDeclarations, + AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, const Storage::Synchronization::PropertyDeclaration &value, SourceId sourceId, TypeId typeId) @@ -3358,17 +3527,24 @@ void ProjectStorage::synchronizePropertyDeclarationsInsertAlias( projectStorageCategory(), keyValue("property declaration", value)}; + auto propertyImportedTypeNameId = fetchImportedTypeNameId(value.typeName, sourceId); + auto callback = [&](PropertyDeclarationId propertyDeclarationId) { - insertedAliasPropertyDeclarations.emplace_back(typeId, - propertyDeclarationId, - fetchImportedTypeNameId(value.typeName, - sourceId), - value.aliasPropertyName, - value.aliasPropertyNameTail); + aliasPropertyDeclarationsToLink.emplace_back(typeId, + propertyDeclarationId, + propertyImportedTypeNameId, + value.aliasPropertyName, + value.aliasPropertyNameTail, + sourceId); return Sqlite::CallbackControl::Abort; }; - s->insertAliasPropertyDeclarationStatement.readCallback(callback, typeId, value.name); + s->insertAliasPropertyDeclarationStatement.readCallback(callback, + typeId, + value.name, + propertyImportedTypeNameId, + value.aliasPropertyName, + value.aliasPropertyNameTail); } QVarLengthArray ProjectStorage::fetchPropertyDeclarationIds( @@ -3452,8 +3628,12 @@ void ProjectStorage::synchronizePropertyDeclarationsInsertProperty( auto propertyImportedTypeNameId = fetchImportedTypeNameId(value.typeName, sourceId); auto propertyTypeId = fetchTypeId(propertyImportedTypeNameId); - if (!propertyTypeId) - throw TypeNameDoesNotExists{fetchImportedTypeName(propertyImportedTypeNameId), sourceId}; + if (!propertyTypeId) { + auto typeName = std::visit([](auto &&importedTypeName) { return importedTypeName.name; }, + value.typeName); + errorNotifier->typeNameCannotBeResolved(typeName, sourceId); + propertyTypeId = TypeId{}; + } auto propertyDeclarationId = s->insertPropertyDeclarationStatement.value( typeId, value.name, propertyTypeId, value.traits, propertyImportedTypeNameId); @@ -3468,7 +3648,7 @@ void ProjectStorage::synchronizePropertyDeclarationsInsertProperty( } void ProjectStorage::synchronizePropertyDeclarationsUpdateAlias( - AliasPropertyDeclarations &updatedAliasPropertyDeclarations, + AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, const Storage::Synchronization::PropertyDeclarationView &view, const Storage::Synchronization::PropertyDeclaration &value, SourceId sourceId) @@ -3479,12 +3659,13 @@ void ProjectStorage::synchronizePropertyDeclarationsUpdateAlias( keyValue("property declaration", value), keyValue("property declaration view", view)}; - updatedAliasPropertyDeclarations.emplace_back(view.typeId, - view.id, - fetchImportedTypeNameId(value.typeName, sourceId), - value.aliasPropertyName, - value.aliasPropertyNameTail, - view.aliasId); + aliasPropertyDeclarationsToLink.emplace_back(view.propertyTypeId, + view.id, + fetchImportedTypeNameId(value.typeName, sourceId), + value.aliasPropertyName, + value.aliasPropertyNameTail, + sourceId, + view.aliasId); } Sqlite::UpdateChange ProjectStorage::synchronizePropertyDeclarationsUpdateProperty( @@ -3503,10 +3684,15 @@ Sqlite::UpdateChange ProjectStorage::synchronizePropertyDeclarationsUpdateProper auto propertyTypeId = fetchTypeId(propertyImportedTypeNameId); - if (!propertyTypeId) - throw TypeNameDoesNotExists{fetchImportedTypeName(propertyImportedTypeNameId), sourceId}; + if (!propertyTypeId) { + auto typeName = std::visit([](auto &&importedTypeName) { return importedTypeName.name; }, + value.typeName); + errorNotifier->typeNameCannotBeResolved(typeName, sourceId); + propertyTypeId = TypeId{}; + propertyDeclarationIds.push_back(view.id); + } - if (view.traits == value.traits && propertyTypeId == view.typeId + if (view.traits == value.traits && compareId(propertyTypeId, view.propertyTypeId) && propertyImportedTypeNameId == view.typeNameId) return Sqlite::UpdateChange::No; @@ -3528,8 +3714,7 @@ void ProjectStorage::synchronizePropertyDeclarations( TypeId typeId, Storage::Synchronization::PropertyDeclarations &propertyDeclarations, SourceId sourceId, - AliasPropertyDeclarations &insertedAliasPropertyDeclarations, - AliasPropertyDeclarations &updatedAliasPropertyDeclarations, + AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, PropertyDeclarationIds &propertyDeclarationIds) { NanotraceHR::Tracer tracer{"synchronize property declaration"_t, projectStorageCategory()}; @@ -3548,7 +3733,7 @@ void ProjectStorage::synchronizePropertyDeclarations( auto insert = [&](const Storage::Synchronization::PropertyDeclaration &value) { if (value.kind == Storage::Synchronization::PropertyKind::Alias) { - synchronizePropertyDeclarationsInsertAlias(insertedAliasPropertyDeclarations, + synchronizePropertyDeclarationsInsertAlias(aliasPropertyDeclarationsToLink, value, sourceId, typeId); @@ -3560,7 +3745,7 @@ void ProjectStorage::synchronizePropertyDeclarations( auto update = [&](const Storage::Synchronization::PropertyDeclarationView &view, const Storage::Synchronization::PropertyDeclaration &value) { if (value.kind == Storage::Synchronization::PropertyKind::Alias) { - synchronizePropertyDeclarationsUpdateAlias(updatedAliasPropertyDeclarations, + synchronizePropertyDeclarationsUpdateAlias(aliasPropertyDeclarationsToLink, view, value, sourceId); @@ -4254,8 +4439,7 @@ TypeId ProjectStorage::declareType(Storage::Synchronization::Type &type) } void ProjectStorage::syncDeclarations(Storage::Synchronization::Type &type, - AliasPropertyDeclarations &insertedAliasPropertyDeclarations, - AliasPropertyDeclarations &updatedAliasPropertyDeclarations, + AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, PropertyDeclarationIds &propertyDeclarationIds) { NanotraceHR::Tracer tracer{"synchronize declaration per type"_t, projectStorageCategory()}; @@ -4266,8 +4450,7 @@ void ProjectStorage::syncDeclarations(Storage::Synchronization::Type &type, synchronizePropertyDeclarations(type.typeId, type.propertyDeclarations, type.sourceId, - insertedAliasPropertyDeclarations, - updatedAliasPropertyDeclarations, + aliasPropertyDeclarationsToLink, propertyDeclarationIds); synchronizeFunctionDeclarations(type.typeId, type.functionDeclarations); synchronizeSignalDeclarations(type.typeId, type.signalDeclarations); @@ -4275,8 +4458,7 @@ void ProjectStorage::syncDeclarations(Storage::Synchronization::Type &type, } void ProjectStorage::syncDeclarations(Storage::Synchronization::Types &types, - AliasPropertyDeclarations &insertedAliasPropertyDeclarations, - AliasPropertyDeclarations &updatedAliasPropertyDeclarations, + AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, PropertyDeclarations &relinkablePropertyDeclarations) { NanotraceHR::Tracer tracer{"synchronize declaration"_t, projectStorageCategory()}; @@ -4285,10 +4467,7 @@ void ProjectStorage::syncDeclarations(Storage::Synchronization::Types &types, propertyDeclarationIds.reserve(types.size() * 10); for (auto &&type : types) - syncDeclarations(type, - insertedAliasPropertyDeclarations, - updatedAliasPropertyDeclarations, - propertyDeclarationIds); + syncDeclarations(type, aliasPropertyDeclarationsToLink, propertyDeclarationIds); removeRelinkableEntries(relinkablePropertyDeclarations, propertyDeclarationIds, @@ -4320,10 +4499,18 @@ void ProjectStorage::syncDefaultProperties(Storage::Synchronization::Types &type keyValue("view", view)}; PropertyDeclarationId valueDefaultPropertyId; - if (value.defaultPropertyName.size()) - valueDefaultPropertyId = fetchPropertyDeclarationByTypeIdAndNameUngarded(value.typeId, - value.defaultPropertyName) - .propertyDeclarationId; + if (value.defaultPropertyName.size()) { + auto defaultPropertyDeclaration = fetchPropertyDeclarationByTypeIdAndNameUngarded( + value.typeId, value.defaultPropertyName); + + if (defaultPropertyDeclaration) { + valueDefaultPropertyId = defaultPropertyDeclaration->propertyDeclarationId; + } else { + errorNotifier->missingDefaultProperty(value.typeName, + value.defaultPropertyName, + value.sourceId); + } + } if (compareInvalidAreTrue(valueDefaultPropertyId, view.defaultPropertyId)) return Sqlite::UpdateChange::No; @@ -4367,10 +4554,8 @@ void ProjectStorage::resetDefaultPropertiesIfChanged(Storage::Synchronization::T PropertyDeclarationId valueDefaultPropertyId; if (value.defaultPropertyName.size()) { - auto optionalValueDefaultPropertyId = fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded( + valueDefaultPropertyId = fetchPropertyDeclarationIdByTypeIdAndNameUngarded( value.typeId, value.defaultPropertyName); - if (optionalValueDefaultPropertyId) - valueDefaultPropertyId = optionalValueDefaultPropertyId->propertyDeclarationId; } if (compareInvalidAreTrue(valueDefaultPropertyId, view.defaultPropertyId)) @@ -4618,8 +4803,8 @@ TypeId ProjectStorage::fetchTypeId(ImportedTypeNameId typeNameId, } std::optional -ProjectStorage::fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(TypeId typeId, - Utils::SmallStringView name) +ProjectStorage::fetchPropertyDeclarationByTypeIdAndNameUngarded(TypeId typeId, + Utils::SmallStringView name) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"fetch optional property declaration by type id and name ungarded"_t, @@ -4637,24 +4822,6 @@ ProjectStorage::fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(TypeId t return propertyDeclaration; } -ProjectStorage::FetchPropertyDeclarationResult ProjectStorage::fetchPropertyDeclarationByTypeIdAndNameUngarded( - TypeId typeId, Utils::SmallStringView name) -{ - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"fetch property declaration by type id and name ungarded"_t, - projectStorageCategory(), - keyValue("type id", typeId), - keyValue("property name", name)}; - - auto propertyDeclaration = fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(typeId, name); - tracer.end(keyValue("property declaration", propertyDeclaration)); - - if (propertyDeclaration) - return *propertyDeclaration; - - throw PropertyNameDoesNotExists{}; -} - PropertyDeclarationId ProjectStorage::fetchPropertyDeclarationIdByTypeIdAndNameUngarded( TypeId typeId, Utils::SmallStringView name) { @@ -4668,10 +4835,7 @@ PropertyDeclarationId ProjectStorage::fetchPropertyDeclarationIdByTypeIdAndNameU tracer.end(keyValue("property declaration id", propertyDeclarationId)); - if (propertyDeclarationId) - return propertyDeclarationId; - - throw PropertyNameDoesNotExists{}; + return propertyDeclarationId; } SourceContextId ProjectStorage::readSourceContextId(Utils::SmallStringView sourceContextPath) @@ -4705,39 +4869,35 @@ SourceContextId ProjectStorage::writeSourceContextId(Utils::SmallStringView sour return sourceContextId; } -SourceId ProjectStorage::writeSourceId(SourceContextId sourceContextId, - Utils::SmallStringView sourceName) +SourceNameId ProjectStorage::writeSourceNameId(Utils::SmallStringView sourceName) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"write source id"_t, projectStorageCategory(), - keyValue("source context id", sourceContextId), keyValue("source name", sourceName)}; - s->insertIntoSourcesStatement.write(sourceContextId, sourceName); + s->insertIntoSourcesStatement.write(sourceName); - auto sourceId = SourceId::create(static_cast(database.lastInsertedRowId())); + auto sourceNameId = SourceNameId::create(static_cast(database.lastInsertedRowId())); - tracer.end(keyValue("source id", sourceId)); + tracer.end(keyValue("source name id", sourceNameId)); - return sourceId; + return sourceNameId; } -SourceId ProjectStorage::readSourceId(SourceContextId sourceContextId, - Utils::SmallStringView sourceName) +SourceNameId ProjectStorage::readSourceNameId(Utils::SmallStringView sourceName) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"read source id"_t, projectStorageCategory(), - keyValue("source context id", sourceContextId), keyValue("source name", sourceName)}; - auto sourceId = s->selectSourceIdFromSourcesBySourceContextIdAndSourceNameStatement - .value(sourceContextId, sourceName); + auto sourceNameId = s->selectSourceNameIdFromSourceNamesBySourceNameStatement.value( + sourceName); - tracer.end(keyValue("source id", sourceId)); + tracer.end(keyValue("source id", sourceNameId)); - return sourceId; + return sourceNameId; } Storage::Synchronization::ExportedTypes ProjectStorage::fetchExportedTypes(TypeId typeId) diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index 54d91015968..7e3a214f53d 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -40,6 +40,7 @@ class ProjectStorage final : public ProjectStorageInterface friend Storage::Info::CommonTypeCache; enum class Relink { No, Yes }; + enum class RaiseError { No, Yes }; public: ProjectStorage(Database &database, @@ -222,18 +223,15 @@ public: Cache::SourceContexts fetchAllSourceContexts() const; - SourceId fetchSourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName); + SourceNameId fetchSourceNameId(Utils::SmallStringView sourceName); - Cache::SourceNameAndSourceContextId fetchSourceNameAndSourceContextId(SourceId sourceId) const; + Utils::SmallString fetchSourceName(SourceNameId sourceId) const; void clearSources(); - SourceContextId fetchSourceContextId(SourceId sourceId) const; + Cache::SourceNames fetchAllSourceNames() const; - Cache::Sources fetchAllSources() const; - - SourceId fetchSourceIdUnguarded(SourceContextId sourceContextId, - Utils::SmallStringView sourceName); + SourceNameId fetchSourceNameIdUnguarded(Utils::SmallStringView sourceName); FileStatuses fetchAllFileStatuses() const; @@ -352,6 +350,7 @@ private: ImportedTypeNameId aliasImportedTypeNameId, Utils::SmallString aliasPropertyName, Utils::SmallString aliasPropertyNameTail, + SourceId sourceId, PropertyDeclarationId aliasPropertyDeclarationId = PropertyDeclarationId{}) : typeId{typeId} , propertyDeclarationId{propertyDeclarationId} @@ -359,6 +358,21 @@ private: , aliasPropertyName{std::move(aliasPropertyName)} , aliasPropertyNameTail{std::move(aliasPropertyNameTail)} , aliasPropertyDeclarationId{aliasPropertyDeclarationId} + , sourceId{sourceId} + {} + + AliasPropertyDeclaration(TypeId typeId, + PropertyDeclarationId propertyDeclarationId, + ImportedTypeNameId aliasImportedTypeNameId, + Utils::SmallStringView aliasPropertyName, + Utils::SmallStringView aliasPropertyNameTail, + SourceId sourceId) + : typeId{typeId} + , propertyDeclarationId{propertyDeclarationId} + , aliasImportedTypeNameId{aliasImportedTypeNameId} + , aliasPropertyName{aliasPropertyName} + , aliasPropertyNameTail{aliasPropertyNameTail} + , sourceId{sourceId} {} friend bool operator<(const AliasPropertyDeclaration &first, @@ -368,6 +382,13 @@ private: < std::tie(second.typeId, second.propertyDeclarationId); } + friend bool operator==(const AliasPropertyDeclaration &first, + const AliasPropertyDeclaration &second) + { + return std::tie(first.typeId, first.propertyDeclarationId) + == std::tie(second.typeId, second.propertyDeclarationId); + } + template friend void convertToString(String &string, const AliasPropertyDeclaration &aliasPropertyDeclaration) @@ -387,6 +408,14 @@ private: convertToString(string, dict); } + Utils::PathString composedProperyName() const + { + if (aliasPropertyNameTail.empty()) + return aliasPropertyName; + + return Utils::PathString::join({aliasPropertyName, ".", aliasPropertyNameTail}); + } + public: TypeId typeId; PropertyDeclarationId propertyDeclarationId; @@ -394,6 +423,7 @@ private: Utils::SmallString aliasPropertyName; Utils::SmallString aliasPropertyNameTail; PropertyDeclarationId aliasPropertyDeclarationId; + SourceId sourceId; }; using AliasPropertyDeclarations = std::vector; @@ -409,6 +439,12 @@ private: , importedTypeNameId{std::move(importedTypeNameId)} {} + friend bool operator==(const PropertyDeclaration &first, const PropertyDeclaration &second) + { + return std::tie(first.typeId, first.propertyDeclarationId) + == std::tie(second.typeId, second.propertyDeclarationId); + } + friend bool operator<(const PropertyDeclaration &first, const PropertyDeclaration &second) { return std::tie(first.typeId, first.propertyDeclarationId) @@ -569,8 +605,7 @@ private: void synchronizeTypes(Storage::Synchronization::Types &types, TypeIds &updatedTypeIds, - AliasPropertyDeclarations &insertedAliasPropertyDeclarations, - AliasPropertyDeclarations &updatedAliasPropertyDeclarations, + AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, AliasPropertyDeclarations &relinkableAliasPropertyDeclarations, PropertyDeclarations &relinkablePropertyDeclarations, Prototypes &relinkablePrototypes, @@ -605,7 +640,14 @@ private: void handlePropertyDeclarationWithPropertyType(TypeId typeId, PropertyDeclarations &relinkablePropertyDeclarations); - + void handlePropertyDeclarationsWithExportedTypeNameAndTypeId( + Utils::SmallStringView exportedTypeName, + TypeId typeId, + PropertyDeclarations &relinkablePropertyDeclarations); + void handleAliasPropertyDeclarationsWithExportedTypeNameAndTypeId( + Utils::SmallStringView exportedTypeName, + TypeId typeId, + AliasPropertyDeclarations &relinkableAliasPropertyDeclarations); void handlePrototypes(TypeId prototypeId, Prototypes &relinkablePrototypes); void handlePrototypesWithExportedTypeNameAndTypeId(Utils::SmallStringView exportedTypeName, TypeId typeId, @@ -651,14 +693,17 @@ private: Utils::SmallStringView aliasPropertyName, Utils::SmallStringView aliasPropertyNameTail); - void linkAliasPropertyDeclarationAliasIds(const AliasPropertyDeclarations &aliasDeclarations); + void linkAliasPropertyDeclarationAliasIds(const AliasPropertyDeclarations &aliasDeclarations, + RaiseError raiseError); void updateAliasPropertyDeclarationValues(const AliasPropertyDeclarations &aliasDeclarations); void checkAliasPropertyDeclarationCycles(const AliasPropertyDeclarations &aliasDeclarations); - void linkAliases(const AliasPropertyDeclarations &insertedAliasPropertyDeclarations, - const AliasPropertyDeclarations &updatedAliasPropertyDeclarations); + void linkAliases(const AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, + RaiseError raiseError); + + void repairBrokenAliasPropertyDeclarations(); void synchronizeExportedTypes(const TypeIds &updatedTypeIds, Storage::Synchronization::ExportedTypes &exportedTypes, @@ -689,7 +734,7 @@ private: const Storage::Synchronization::PropertyDeclaration &value, SourceId sourceId, TypeId typeId); void synchronizePropertyDeclarationsUpdateAlias( - AliasPropertyDeclarations &updatedAliasPropertyDeclarations, + AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, const Storage::Synchronization::PropertyDeclarationView &view, const Storage::Synchronization::PropertyDeclaration &value, SourceId sourceId); @@ -700,13 +745,11 @@ private: SourceId sourceId, PropertyDeclarationIds &propertyDeclarationIds); - void synchronizePropertyDeclarations( - TypeId typeId, - Storage::Synchronization::PropertyDeclarations &propertyDeclarations, - SourceId sourceId, - AliasPropertyDeclarations &insertedAliasPropertyDeclarations, - AliasPropertyDeclarations &updatedAliasPropertyDeclarations, - PropertyDeclarationIds &propertyDeclarationIds); + void synchronizePropertyDeclarations(TypeId typeId, + Storage::Synchronization::PropertyDeclarations &propertyDeclarations, + SourceId sourceId, + AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, + PropertyDeclarationIds &propertyDeclarationIds); class AliasPropertyDeclarationView { @@ -832,8 +875,7 @@ private: TypeId declareType(Storage::Synchronization::Type &type); void syncDeclarations(Storage::Synchronization::Type &type, - AliasPropertyDeclarations &insertedAliasPropertyDeclarations, - AliasPropertyDeclarations &updatedAliasPropertyDeclarations, + AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, PropertyDeclarationIds &propertyDeclarationIds); template @@ -859,8 +901,7 @@ private: } void syncDeclarations(Storage::Synchronization::Types &types, - AliasPropertyDeclarations &insertedAliasPropertyDeclarations, - AliasPropertyDeclarations &updatedAliasPropertyDeclarations, + AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, PropertyDeclarations &relinkablePropertyDeclarations); class TypeWithDefaultPropertyView @@ -924,10 +965,12 @@ private: class FetchPropertyDeclarationResult { public: - FetchPropertyDeclarationResult(TypeId propertyTypeId, + FetchPropertyDeclarationResult(ImportedTypeNameId propertyImportedTypeNameId, + TypeId propertyTypeId, PropertyDeclarationId propertyDeclarationId, Storage::PropertyDeclarationTraits propertyTraits) - : propertyTypeId{propertyTypeId} + : propertyImportedTypeNameId{propertyImportedTypeNameId} + , propertyTypeId{propertyTypeId} , propertyDeclarationId{propertyDeclarationId} , propertyTraits{propertyTraits} {} @@ -937,7 +980,9 @@ private: { using NanotraceHR::dictonary; using NanotraceHR::keyValue; - auto dict = dictonary(keyValue("property type id", result.propertyTypeId), + auto dict = dictonary(keyValue("property imported type name id", + result.propertyImportedTypeNameId), + keyValue("property type id", result.propertyTypeId), keyValue("property declaration id", result.propertyDeclarationId), keyValue("property traits", result.propertyTraits)); @@ -945,15 +990,13 @@ private: } public: + ImportedTypeNameId propertyImportedTypeNameId; TypeId propertyTypeId; PropertyDeclarationId propertyDeclarationId; Storage::PropertyDeclarationTraits propertyTraits; }; - std::optional fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded( - TypeId typeId, Utils::SmallStringView name); - - FetchPropertyDeclarationResult fetchPropertyDeclarationByTypeIdAndNameUngarded( + std::optional fetchPropertyDeclarationByTypeIdAndNameUngarded( TypeId typeId, Utils::SmallStringView name); PropertyDeclarationId fetchPropertyDeclarationIdByTypeIdAndNameUngarded(TypeId typeId, @@ -963,9 +1006,9 @@ private: SourceContextId writeSourceContextId(Utils::SmallStringView sourceContextPath); - SourceId writeSourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName); + SourceNameId writeSourceNameId(Utils::SmallStringView sourceName); - SourceId readSourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName); + SourceNameId readSourceNameId(Utils::SmallStringView sourceName); Storage::Synchronization::ExportedTypes fetchExportedTypes(TypeId typeId); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.cpp index a4705f5eecb..6d59ebb3884 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.cpp @@ -8,10 +8,26 @@ namespace QmlDesigner { void ProjectStorageErrorNotifier::typeNameCannotBeResolved(Utils::SmallStringView typeName, - SourceId sourceId) + SourceId sourceId) { qDebug() << "Missing type name: " << typeName << " in file: " << m_pathCache.sourcePath(sourceId).toStringView(); } +void ProjectStorageErrorNotifier::missingDefaultProperty(Utils::SmallStringView typeName, + Utils::SmallStringView propertyName, + SourceId sourceId) + +{ + qDebug() << "Missing default property: " << propertyName << " in type: " << typeName + << " in file: " << m_pathCache.sourcePath(sourceId).toStringView(); +} + +void ProjectStorageErrorNotifier::propertyNameDoesNotExists(Utils::SmallStringView propertyName, + SourceId sourceId) +{ + qDebug() << "Missing property: " << propertyName + << " in file: " << m_pathCache.sourcePath(sourceId).toStringView(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.h index 2695e930193..ab1bdd51366 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.h @@ -16,7 +16,11 @@ public: : m_pathCache{pathCache} {} - void typeNameCannotBeResolved(Utils::SmallStringView typeName, SourceId souceId) override; + void typeNameCannotBeResolved(Utils::SmallStringView typeName, SourceId sourceId) override; + void missingDefaultProperty(Utils::SmallStringView typeName, + Utils::SmallStringView propertyName, + SourceId sourceId) override; + void propertyNameDoesNotExists(Utils::SmallStringView propertyName, SourceId sourceId) override; private: PathCacheType &m_pathCache; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifierinterface.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifierinterface.h index 8136c9d599c..5d370519037 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifierinterface.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifierinterface.h @@ -18,7 +18,12 @@ public: ProjectStorageErrorNotifierInterface(const ProjectStorageErrorNotifierInterface &) = delete; ProjectStorageErrorNotifierInterface &operator=(const ProjectStorageErrorNotifierInterface &) = delete; - virtual void typeNameCannotBeResolved(Utils::SmallStringView typeName, SourceId souceId) = 0; + virtual void typeNameCannotBeResolved(Utils::SmallStringView typeName, SourceId sourceId) = 0; + virtual void missingDefaultProperty(Utils::SmallStringView typeName, + Utils::SmallStringView propertyName, + SourceId sourceId) + = 0; + virtual void propertyNameDoesNotExists(Utils::SmallStringView propertyName, SourceId sourceId) = 0; protected: ~ProjectStorageErrorNotifierInterface() = default; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.cpp index a86b78a785f..938a9fac4d4 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.cpp @@ -47,12 +47,12 @@ const char *SourceContextIdDoesNotExists::what() const noexcept return "The source context id does not exist in the database!"; } -SourceIdDoesNotExists::SourceIdDoesNotExists() +SourceNameIdDoesNotExists::SourceNameIdDoesNotExists() { - category().threadEvent("SourceIdDoesNotExists"_t); + category().threadEvent("SourceNameIdDoesNotExists"_t); } -const char *SourceIdDoesNotExists::what() const noexcept +const char *SourceNameIdDoesNotExists::what() const noexcept { return "The source id does not exist in the database!"; } @@ -98,16 +98,6 @@ TypeNameDoesNotExists::TypeNameDoesNotExists(std::string_view typeName, SourceId keyValue("source id", sourceId)); } -PropertyNameDoesNotExists::PropertyNameDoesNotExists() -{ - category().threadEvent("PropertyNameDoesNotExists"_t); -} - -const char *PropertyNameDoesNotExists::what() const noexcept -{ - return "The property name does not exist!"; -} - PrototypeChainCycle::PrototypeChainCycle() { category().threadEvent("PrototypeChainCycle"_t); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h index f4f78f714bb..5ab71b3c247 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h @@ -55,10 +55,10 @@ public: const char *what() const noexcept override; }; -class QMLDESIGNERCORE_EXPORT SourceIdDoesNotExists : public ProjectStorageError +class QMLDESIGNERCORE_EXPORT SourceNameIdDoesNotExists : public ProjectStorageError { public: - SourceIdDoesNotExists(); + SourceNameIdDoesNotExists(); const char *what() const noexcept override; }; @@ -95,13 +95,6 @@ public: TypeNameDoesNotExists(std::string_view typeName, SourceId sourceId = SourceId{}); }; -class QMLDESIGNERCORE_EXPORT PropertyNameDoesNotExists : public ProjectStorageError -{ -public: - PropertyNameDoesNotExists(); - const char *what() const noexcept override; -}; - class QMLDESIGNERCORE_EXPORT PrototypeChainCycle : public ProjectStorageError { public: diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h index 1d630344aec..010c9a7e1cc 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h @@ -131,8 +131,6 @@ struct TypeTraits : kind{TypeTraitsKind::None} , isEnum{false} , isFileComponent{false} - , isProjectComponent{false} - , isInProjectModule{false} , usesCustomParser{false} , dummy{0U} , canBeContainer{FlagIs::False} @@ -181,8 +179,6 @@ struct TypeTraits keyValue("kind", typeTraits.kind), keyValue("is enum", typeTraits.isEnum), keyValue("is file component", typeTraits.isFileComponent), - keyValue("is project component", typeTraits.isProjectComponent), - keyValue("is in project module", typeTraits.isInProjectModule), keyValue("uses custom parser", typeTraits.usesCustomParser), keyValue("can be container", typeTraits.canBeContainer), keyValue("force clip", typeTraits.forceClip), @@ -207,10 +203,8 @@ struct TypeTraits TypeTraitsKind kind : 4; unsigned int isEnum : 1; unsigned int isFileComponent : 1; - unsigned int isProjectComponent : 1; - unsigned int isInProjectModule : 1; unsigned int usesCustomParser : 1; - unsigned int dummy : 23; + unsigned int dummy : 25; }; unsigned int type; @@ -242,7 +236,7 @@ struct TypeTraits static_assert(sizeof(TypeTraits) == sizeof(unsigned int) * 2, "TypeTraits must be of size unsigned long long!"); -using TypeNameString = ::Utils::BasicSmallString<63>; +using TypeNameString = ::Utils::BasicSmallString<64>; class VersionNumber { @@ -374,7 +368,7 @@ struct ItemLibraryProperty using ItemLibraryProperties = QVarLengthArray; -using ToolTipString = Utils::BasicSmallString<94>; +using ToolTipString = Utils::BasicSmallString<96>; struct ItemLibraryEntry { diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatcher.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatcher.h index d79b87807f8..63816b5cb55 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatcher.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatcher.h @@ -127,13 +127,16 @@ public: ids.push_back(id); - outputIterator = std::transform( - idPath.sourceIds.begin(), idPath.sourceIds.end(), outputIterator, [&](SourceId sourceId) { - return WatcherEntry{id, - m_pathCache.sourceContextId(sourceId), - sourceId, - m_fileStatusCache.lastModifiedTime(sourceId)}; - }); + outputIterator = std::transform(idPath.sourceIds.begin(), + idPath.sourceIds.end(), + outputIterator, + [&](SourceId sourceId) { + return WatcherEntry{id, + sourceId.contextId(), + sourceId, + m_fileStatusCache.lastModifiedTime( + sourceId)}; + }); } std::sort(entries.begin(), entries.end()); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h index 1592628af53..8608f3ad805 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h @@ -870,6 +870,21 @@ public: , kind{PropertyKind::Property} {} + explicit PropertyDeclaration(PropertyDeclarationId propertyDeclarationId, + ::Utils::SmallStringView name, + TypeId propertyTypeId, + PropertyDeclarationTraits traits, + ::Utils::SmallStringView aliasPropertyName, + TypeId typeId) + : name{name} + , aliasPropertyName{aliasPropertyName} + , traits{traits} + , propertyTypeId{propertyTypeId} + , typeId{typeId} + , propertyDeclarationId{propertyDeclarationId} + , kind{PropertyKind::Property} + {} + explicit PropertyDeclaration(::Utils::SmallStringView name, ImportedTypeName aliasTypeName, ::Utils::SmallStringView aliasPropertyName, @@ -916,6 +931,7 @@ public: PropertyDeclarationTraits traits = {}; TypeId propertyTypeId; TypeId typeId; + PropertyDeclarationId propertyDeclarationId; PropertyKind kind = PropertyKind::Property; }; @@ -926,13 +942,13 @@ class PropertyDeclarationView public: explicit PropertyDeclarationView(::Utils::SmallStringView name, PropertyDeclarationTraits traits, - TypeId typeId, + TypeId propertyTypeId, ImportedTypeNameId typeNameId, PropertyDeclarationId id, PropertyDeclarationId aliasId) : name{name} , traits{traits} - , typeId{typeId} + , propertyTypeId{propertyTypeId} , typeNameId{typeNameId} , id{id} , aliasId{aliasId} @@ -945,7 +961,7 @@ public: using NanotraceHR::keyValue; auto dict = dictonary(keyValue("name", propertyDeclaration.name), keyValue("traits", propertyDeclaration.traits), - keyValue("type id", propertyDeclaration.typeId), + keyValue("type id", propertyDeclaration.propertyTypeId), keyValue("type name id", propertyDeclaration.typeNameId), keyValue("id", propertyDeclaration.id), keyValue("alias id", propertyDeclaration.aliasId)); @@ -956,7 +972,7 @@ public: public: ::Utils::SmallStringView name; PropertyDeclarationTraits traits = {}; - TypeId typeId; + TypeId propertyTypeId; ImportedTypeNameId typeNameId; PropertyDeclarationId id; PropertyDeclarationId aliasId; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp index a0e7bba3c52..88110223755 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp @@ -260,11 +260,13 @@ std::vector createIdPaths(ProjectStorageUpdater::WatchedSourceIdsIds wa } // namespace -void ProjectStorageUpdater::update(QStringList directories, - QStringList qmlTypesPaths, - const QString &propertyEditorResourcesPath, - const QStringList &typeAnnotationPaths) +void ProjectStorageUpdater::update(Update update) { + QStringList directories = std::move(update.directories); + QStringList qmlTypesPaths = std::move(update.qmlTypesPaths); + const QString &propertyEditorResourcesPath = update.propertyEditorResourcesPath; + const QStringList &typeAnnotationPaths = update.typeAnnotationPaths; + NanotraceHR::Tracer tracer{"update"_t, category(), keyValue("directories", directories), @@ -437,24 +439,22 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct { struct Directory { - Directory(Utils::SmallStringView path, SourceContextId sourceContextId, SourceId sourceId) + Directory(Utils::SmallStringView path, SourceId sourceId) : path{path} - , sourceContextId{sourceContextId} , sourceId{sourceId} {} bool operator<(const Directory &other) const { - return sourceContextId < other.sourceContextId; + return sourceId.contextId() < other.sourceId.contextId(); } bool operator==(const Directory &other) const { - return sourceContextId == other.sourceContextId; + return sourceId.contextId() == other.sourceId.contextId(); } Utils::PathString path; - SourceContextId sourceContextId; SourceId sourceId; }; @@ -462,17 +462,17 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct { bool operator()(const Directory &first, const Directory &second) const { - return first.sourceContextId < second.sourceContextId; + return first.sourceId.contextId() < second.sourceId.contextId(); } bool operator()(const Directory &first, SourceContextId second) const { - return first.sourceContextId < second; + return first.sourceId.contextId() < second; } bool operator()(SourceContextId first, const Directory &second) const { - return first < second.sourceContextId; + return first < second.sourceId.contextId(); } }; @@ -481,9 +481,9 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct auto subdirectorySourceIds = m_projectStorage.fetchSubdirectorySourceIds(directorySourceId); auto subdirectories = Utils::transform( subdirectorySourceIds, [&](SourceId sourceId) -> Directory { - auto sourceContextId = m_pathCache.sourceContextId(sourceId); + auto sourceContextId = sourceId.contextId(); auto subdirectoryPath = m_pathCache.sourceContextPath(sourceContextId); - return {subdirectoryPath, sourceContextId, sourceId}; + return {subdirectoryPath, sourceId}; }); auto exisitingSubdirectoryPaths = m_fileSystem.subdirectories(directoryPath.toQString()); @@ -493,10 +493,9 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct || subdirectory.endsWith("/QtQuick/Scene3D")) continue; Utils::PathString subdirectoryPath = subdirectory; - auto [sourceContextId, sourceId] = m_pathCache.sourceContextAndSourceId( - SourcePath{subdirectoryPath + "/."}); - subdirectories.emplace_back(subdirectoryPath, sourceContextId, sourceId); - existingSubdirecories.emplace_back(subdirectoryPath, sourceContextId, sourceId); + SourceId sourceId = m_pathCache.sourceId(SourcePath{subdirectoryPath + "/."}); + subdirectories.emplace_back(subdirectoryPath, sourceId); + existingSubdirecories.emplace_back(subdirectoryPath, sourceId); } std::sort(subdirectories.begin(), subdirectories.end()); @@ -517,8 +516,7 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct Compare{}); if (directoryState == FileState::Changed) { - for (const auto &[subdirectoryPath, sourceContextId, subdirectorySourceId] : - existingSubdirecories) { + for (const auto &[subdirectoryPath, subdirectorySourceId] : existingSubdirecories) { package.directoryInfos.emplace_back(directorySourceId, subdirectorySourceId, ModuleId{}, @@ -826,12 +824,10 @@ void ProjectStorageUpdater::updatePropertyEditorFilePath( } namespace { -SourceContextIds filterUniqueSourceContextIds(const SourceIds &sourceIds, - ProjectStorageUpdater::PathCache &pathCache) +SourceContextIds filterUniqueSourceContextIds(const SourceIds &sourceIds) { - auto sourceContextIds = Utils::transform(sourceIds, [&](SourceId sourceId) { - return pathCache.sourceContextId(sourceId); - }); + auto sourceContextIds = Utils::transform(sourceIds, + [](SourceId sourceId) { return sourceId.contextId(); }); std::sort(sourceContextIds.begin(), sourceContextIds.end()); auto newEnd = std::unique(sourceContextIds.begin(), sourceContextIds.end()); @@ -897,7 +893,7 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector &chan } } - auto directorySourceContextIds = filterUniqueSourceContextIds(directorySourceIds, m_pathCache); + auto directorySourceContextIds = filterUniqueSourceContextIds(directorySourceIds); for (auto sourceContextId : directorySourceContextIds) { Utils::PathString directory = m_pathCache.sourceContextPath(sourceContextId); @@ -909,13 +905,13 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector &chan } for (SourceId sourceId : filterUniqueSourceIds(qmlDocumentSourceIds)) { - if (!contains(directorySourceContextIds, m_pathCache.sourceContextId(sourceId))) + if (!contains(directorySourceContextIds, sourceId.contextId())) parseQmlComponent(sourceId, package, notUpdatedSourceIds); } try { for (SourceId sourceId : filterUniqueSourceIds(std::move(qmltypesSourceIds))) { - if (!contains(directorySourceContextIds, m_pathCache.sourceContextId(sourceId))) { + if (!contains(directorySourceContextIds, sourceId.contextId())) { auto qmltypesPath = m_pathCache.sourcePath(sourceId); auto directoryInfo = m_projectStorage.fetchDirectoryInfo(sourceId); if (directoryInfo) @@ -1113,7 +1109,6 @@ void ProjectStorageUpdater::parseQmlComponent(Utils::SmallStringView relativeFil package.updatedSourceIds.push_back(sourceId); type.typeName = SourcePath{qmlFilePath}.name(); - type.traits = Storage::TypeTraitsKind::Reference; type.sourceId = sourceId; type.exportedTypes = std::move(exportedTypes); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h index baecbd6b11b..3995c97800b 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h @@ -59,10 +59,15 @@ public: , m_projectPartId{projectPartId} {} - void update(QStringList directories, - QStringList qmlTypesPaths, - const QString &propertyEditorResourcesPath, - const QStringList &typeAnnotationPaths); + struct Update + { + QStringList directories = {}; + QStringList qmlTypesPaths = {}; + const QString propertyEditorResourcesPath = {}; + const QStringList typeAnnotationPaths = {}; + }; + + void update(Update update); void pathsWithIdsChanged(const std::vector &idPaths) override; void pathsChanged(const SourceIds &filePathIds) override; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp index 4338da62ce9..0469809ac17 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp @@ -297,6 +297,15 @@ void addEnumeraton(Storage::Synchronization::Type &type, const QmlDom::Component } } +Storage::TypeTraits createTypeTraits() +{ + Storage::TypeTraits traits = Storage::TypeTraitsKind::Reference; + + traits.isFileComponent = true; + + return traits; +} + } // namespace Storage::Synchronization::Type QmlDocumentParser::parse(const QString &sourceContent, @@ -363,6 +372,7 @@ Storage::Synchronization::Type QmlDocumentParser::parse(const QString &sourceCon directoryPath, m_storage); + type.traits = createTypeTraits(); type.prototype = createImportedTypeName(qmlObject.name(), qualifiedImports); type.defaultPropertyName = qmlObject.localDefaultPropertyName(); addImports(imports, qmlFile->imports(), sourceId, directoryPath, m_storage); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp index b3ec4f00242..228609a9ce8 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp @@ -288,7 +288,7 @@ createFunctionAndSignals(const QMultiHash &qmlMethods if (qmlMethod.isJavaScriptFunction()) continue; - if (qmlMethod.methodType() != QQmlJSMetaMethod::Type::Signal) { + if (qmlMethod.methodType() != QQmlJSMetaMethodType::Signal) { functionsDeclarations.emplace_back(Utils::SmallString{qmlMethod.methodName()}, fullyQualifiedTypeName(qmlMethod.returnTypeName(), componentNameWithoutNamespace), diff --git a/src/plugins/qmldesigner/designercore/projectstorage/sourcepath.h b/src/plugins/qmldesigner/designercore/projectstorage/sourcepath.h index fa550a4d52e..be197bc91f2 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/sourcepath.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/sourcepath.h @@ -47,7 +47,7 @@ public: } explicit SourcePath(const Utils::PathString &sourcePath) - : SourcePath(sourcePath.clone()) + : SourcePath(Utils::PathString{sourcePath}) { } diff --git a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcache.h b/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcache.h index 424638a64d9..4ce7ae43b59 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcache.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcache.h @@ -32,7 +32,7 @@ class SourcePathCache final : public SourcePathCacheInterface public: SourcePathCache(ProjectStorage &projectStorage) : m_sourceContextStorageAdapter{projectStorage} - , m_sourceStorageAdapter{projectStorage} + , m_sourceNameStorageAdapter{projectStorage} { populateIfEmpty(); @@ -58,9 +58,9 @@ public: Utils::SmallStringView sourceName = sourcePath.name(); - auto sourceId = m_sourcePathCache.id({sourceName, sourceContextId}); + auto sourceId = m_sourcePathCache.id(sourceName); - return {sourceContextId, sourceId}; + return {sourceContextId, SourceId::create(sourceId, sourceContextId)}; } SourceId sourceId(SourcePathView sourcePath) const override @@ -71,7 +71,9 @@ public: SourceId sourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName) const override { - return m_sourcePathCache.id({sourceName, sourceContextId}); + SourceNameId sourceNameId = m_sourcePathCache.id(sourceName); + + return SourceId::create(sourceNameId, sourceContextId); } SourceContextId sourceContextId(Utils::SmallStringView sourceContextPath) const override @@ -88,11 +90,11 @@ public: if (Q_UNLIKELY(!sourceId.isValid())) throw NoSourcePathForInvalidSourceId(); - auto entry = m_sourcePathCache.value(sourceId); + auto sourceName = m_sourcePathCache.value(sourceId.mainId()); - Utils::PathString sourceContextPath = m_sourceContextPathCache.value(entry.sourceContextId); + Utils::PathString sourceContextPath = m_sourceContextPathCache.value(sourceId.contextId()); - return SourcePath{sourceContextPath, entry.sourceName}; + return SourcePath{sourceContextPath, sourceName}; } Utils::PathString sourceContextPath(SourceContextId sourceContextId) const override @@ -103,19 +105,11 @@ public: return m_sourceContextPathCache.value(sourceContextId); } - SourceContextId sourceContextId(SourceId sourceId) const override - { - if (Q_UNLIKELY(!sourceId.isValid())) - throw NoSourcePathForInvalidSourceId(); - - return m_sourcePathCache.value(sourceId).sourceContextId; - } - private: class SourceContextStorageAdapter { public: - auto fetchId(const Utils::SmallStringView sourceContextPath) + auto fetchId(Utils::SmallStringView sourceContextPath) { return storage.fetchSourceContextId(sourceContextPath); } @@ -127,27 +121,22 @@ private: ProjectStorage &storage; }; - class SourceStorageAdapter + class SourceNameStorageAdapter { public: - auto fetchId(Cache::SourceNameView sourceNameView) + auto fetchId(Utils::SmallStringView sourceNameView) { - return storage.fetchSourceId(sourceNameView.sourceContextId, sourceNameView.sourceName); + return storage.fetchSourceNameId(sourceNameView); } - auto fetchValue(SourceId id) - { - auto entry = storage.fetchSourceNameAndSourceContextId(id); + auto fetchValue(SourceNameId id) { return storage.fetchSourceName(id); } - return Cache::SourceNameEntry{std::move(entry.sourceName), entry.sourceContextId}; - } - - auto fetchAll() { return storage.fetchAllSources(); } + auto fetchAll() { return storage.fetchAllSourceNames(); } ProjectStorage &storage; }; - static bool sourceContextLess(Utils::SmallStringView first, Utils::SmallStringView second) noexcept + static bool sourceLess(Utils::SmallStringView first, Utils::SmallStringView second) noexcept { return std::lexicographical_compare(first.rbegin(), first.rend(), @@ -155,31 +144,26 @@ private: second.rend()); } - static bool sourceLess(Cache::SourceNameView first, Cache::SourceNameView second) noexcept - { - return first < second; - } - using SourceContextPathCache = StorageCache; - using SourceNameCache = StorageCache; + Cache::SourceName>; private: SourceContextStorageAdapter m_sourceContextStorageAdapter; - SourceStorageAdapter m_sourceStorageAdapter; + SourceNameStorageAdapter m_sourceNameStorageAdapter; mutable SourceContextPathCache m_sourceContextPathCache{m_sourceContextStorageAdapter}; - mutable SourceNameCache m_sourcePathCache{m_sourceStorageAdapter}; + mutable SourceNameCache m_sourcePathCache{m_sourceNameStorageAdapter}; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcacheinterface.h b/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcacheinterface.h index 3eaa5634130..8ad961ee80c 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcacheinterface.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcacheinterface.h @@ -36,7 +36,6 @@ public: virtual SourcePath sourcePath(SourceId sourceId) const = 0; virtual Utils::PathString sourceContextPath(SourceContextId sourceContextId) const = 0; - virtual SourceContextId sourceContextId(SourceId sourceId) const = 0; protected: ~SourcePathCacheInterface() = default; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcachetypes.h b/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcachetypes.h index 1ef8ba7f216..0f6a40c626c 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcachetypes.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcachetypes.h @@ -12,70 +12,6 @@ namespace QmlDesigner::Cache { -class SourceNameView -{ -public: - friend bool operator==(const SourceNameView &first, const SourceNameView &second) noexcept - { - return first.sourceContextId == second.sourceContextId - && first.sourceName == second.sourceName; - } - - friend bool operator<(SourceNameView first, SourceNameView second) noexcept - { - return std::tie(first.sourceContextId, first.sourceName) - < std::tie(second.sourceContextId, second.sourceName); - } - -public: - Utils::SmallStringView sourceName; - SourceContextId sourceContextId; -}; - -class SourceNameEntry -{ -public: - SourceNameEntry() = default; - SourceNameEntry(Utils::SmallStringView sourceName, SourceContextId sourceContextId) - : sourceName(sourceName) - , sourceContextId(sourceContextId) - {} - - SourceNameEntry(SourceNameView view) - : sourceName(view.sourceName) - , sourceContextId(view.sourceContextId) - {} - - friend bool operator==(const SourceNameEntry &first, const SourceNameEntry &second) noexcept - { - return first.sourceContextId == second.sourceContextId - && first.sourceName == second.sourceName; - } - - friend bool operator!=(const SourceNameEntry &first, const SourceNameEntry &second) noexcept - { - return !(first == second); - } - - friend bool operator==(const SourceNameEntry &first, const SourceNameView &second) noexcept - { - return first.sourceContextId == second.sourceContextId - && first.sourceName == second.sourceName; - } - - friend bool operator!=(const SourceNameEntry &first, const SourceNameView &second) noexcept - { - return !(first == second); - } - - operator SourceNameView() const noexcept { return {sourceName, sourceContextId}; } - - operator Utils::SmallString() &&noexcept { return std::move(sourceName); } - -public: - Utils::SmallString sourceName; - SourceContextId sourceContextId; -}; class SourceContext : public StorageCacheEntry @@ -93,38 +29,19 @@ public: using SourceContexts = std::vector; -class Source : public StorageCacheEntry +class SourceName : public StorageCacheEntry { - using Base = StorageCacheEntry; + using Base = StorageCacheEntry; public: using Base::Base; - Source(Utils::SmallStringView sourceName, SourceContextId sourceContextId, SourceId sourceId) - : Base{{sourceName, sourceContextId}, sourceId} - {} - friend bool operator==(const Source &first, const Source &second) + friend bool operator==(const SourceName &first, const SourceName &second) { return first.id == second.id && first.value == second.value; } }; -using Sources = std::vector; - -class SourceNameAndSourceContextId -{ -public: - constexpr SourceNameAndSourceContextId() = default; - - SourceNameAndSourceContextId(Utils::SmallStringView sourceName, SourceContextId sourceContextId) - : sourceName{sourceName} - , sourceContextId{sourceContextId} - {} - - Utils::SmallString sourceName; - SourceContextId sourceContextId; -}; - -using SourceNameAndSourceContextIds = std::vector; +using SourceNames = std::vector; } // namespace QmlDesigner::Cache diff --git a/src/plugins/qmldesigner/designercore/model/qml3dnode.cpp b/src/plugins/qmldesigner/designercore/qmltools/qml3dnode.cpp similarity index 96% rename from src/plugins/qmldesigner/designercore/model/qml3dnode.cpp rename to src/plugins/qmldesigner/designercore/qmltools/qml3dnode.cpp index 12befa942f1..05e4bbf2aef 100644 --- a/src/plugins/qmldesigner/designercore/model/qml3dnode.cpp +++ b/src/plugins/qmldesigner/designercore/qmltools/qml3dnode.cpp @@ -39,7 +39,7 @@ bool Qml3DNode::isValidVisualRoot(const ModelNode &modelNode) && (modelNode.metaInfo().isQtQuick3DNode() || modelNode.metaInfo().isQtQuick3DMaterial()); } -bool Qml3DNode::handleEulerRotation(const PropertyName &name) +bool Qml3DNode::handleEulerRotation(PropertyNameView name) { if (isBlocked(name)) return false; @@ -50,7 +50,7 @@ bool Qml3DNode::handleEulerRotation(const PropertyName &name) return true; } -bool Qml3DNode::isBlocked(const PropertyName &propName) const +bool Qml3DNode::isBlocked(PropertyNameView propName) const { if (modelNode().isValid() && propName.startsWith("eulerRotation")) return modelNode().auxiliaryDataWithDefault(rotBlockProperty).toBool(); diff --git a/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp b/src/plugins/qmldesigner/designercore/qmltools/qmlanchors.cpp similarity index 88% rename from src/plugins/qmldesigner/designercore/model/qmlanchors.cpp rename to src/plugins/qmldesigner/designercore/qmltools/qmlanchors.cpp index c717a698174..e43ceeb49bc 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp +++ b/src/plugins/qmldesigner/designercore/qmltools/qmlanchors.cpp @@ -12,20 +12,30 @@ namespace QmlDesigner { static PropertyName lineTypeToString(AnchorLineType lineType) { switch (lineType) { - case AnchorLineLeft: return PropertyName("left"); - case AnchorLineTop: return PropertyName("top"); - case AnchorLineRight: return PropertyName("right"); - case AnchorLineBottom: return PropertyName("bottom"); - case AnchorLineHorizontalCenter: return PropertyName("horizontalCenter"); - case AnchorLineVerticalCenter: return PropertyName("verticalCenter"); - case AnchorLineBaseline: return PropertyName("baseline"); - case AnchorLineFill: return PropertyName("fill"); - case AnchorLineCenter: return PropertyName("centerIn"); - default: return PropertyName(); + case AnchorLineLeft: + return QByteArrayLiteral("left"); + case AnchorLineTop: + return QByteArrayLiteral("top"); + case AnchorLineRight: + return QByteArrayLiteral("right"); + case AnchorLineBottom: + return QByteArrayLiteral("bottom"); + case AnchorLineHorizontalCenter: + return QByteArrayLiteral("horizontalCenter"); + case AnchorLineVerticalCenter: + return QByteArrayLiteral("verticalCenter"); + case AnchorLineBaseline: + return QByteArrayLiteral("baseline"); + case AnchorLineFill: + return QByteArrayLiteral("fill"); + case AnchorLineCenter: + return QByteArrayLiteral("centerIn"); + default: + return {}; } } -static AnchorLineType propertyNameToLineType(const PropertyName & name) +static AnchorLineType propertyNameToLineType(PropertyNameView name) { if (name == "left") return AnchorLineLeft; @@ -49,30 +59,52 @@ static AnchorLineType propertyNameToLineType(const PropertyName & name) return AnchorLineInvalid; } -static PropertyName marginPropertyName(AnchorLineType lineType) +static PropertyNameView marginPropertyName(AnchorLineType lineType) { switch (lineType) { - case AnchorLineLeft: return PropertyName("anchors.leftMargin"); - case AnchorLineTop: return PropertyName("anchors.topMargin"); - case AnchorLineRight: return PropertyName("anchors.rightMargin"); - case AnchorLineBottom: return PropertyName("anchors.bottomMargin"); - case AnchorLineHorizontalCenter: return PropertyName("anchors.horizontalCenterOffset"); - case AnchorLineVerticalCenter: return PropertyName("anchors.verticalCenterOffset"); - default: return PropertyName(); + case AnchorLineLeft: + return {"anchors.leftMargin"}; + case AnchorLineTop: + return {"anchors.topMargin"}; + case AnchorLineRight: + return {"anchors.rightMargin"}; + case AnchorLineBottom: + return {"anchors.bottomMargin"}; + case AnchorLineHorizontalCenter: + return {"anchors.horizontalCenterOffset"}; + case AnchorLineVerticalCenter: + return {"anchors.verticalCenterOffset"}; + default: + return {}; } } -static PropertyName anchorPropertyName(AnchorLineType lineType) +static PropertyNameView anchorPropertyName(AnchorLineType lineType) { - const PropertyName typeString = lineTypeToString(lineType); - - if (typeString.isEmpty()) - return PropertyName(); - else - return PropertyName("anchors.") + typeString; + switch (lineType) { + case AnchorLineLeft: + return {"anchors.left"}; + case AnchorLineTop: + return {"anchors.top"}; + case AnchorLineRight: + return {"anchors.right"}; + case AnchorLineBottom: + return {"anchors.bottom"}; + case AnchorLineHorizontalCenter: + return {"anchors.horizontalCenter"}; + case AnchorLineVerticalCenter: + return {"anchors.verticalCenter"}; + case AnchorLineBaseline: + return {"anchors.baseline"}; + case AnchorLineFill: + return {"anchors.fill"}; + case AnchorLineCenter: + return {"anchors.centerIn"}; + default: + return {}; + } } - QmlAnchors::QmlAnchors(const QmlItemNode &fxItemNode) : m_qmlItemNode(fxItemNode) { } @@ -95,7 +127,7 @@ bool QmlAnchors::modelHasAnchors() const bool QmlAnchors::modelHasAnchor(AnchorLineType sourceAnchorLineType) const { - const PropertyName propertyName = anchorPropertyName(sourceAnchorLineType); + const PropertyNameView propertyName = anchorPropertyName(sourceAnchorLineType); if (sourceAnchorLineType & AnchorLineFill) return qmlItemNode().modelNode().hasBindingProperty(propertyName) || qmlItemNode().modelNode().hasBindingProperty("anchors.fill"); @@ -117,7 +149,7 @@ AnchorLine QmlAnchors::modelAnchor(AnchorLineType sourceAnchorLineType) const targetAnchorLinePair.first = lineTypeToString(sourceAnchorLineType); } else { AbstractProperty binding = qmlItemNode().modelNode().bindingProperty(anchorPropertyName(sourceAnchorLineType)).resolveToProperty(); - targetAnchorLinePair.first = binding.name(); + targetAnchorLinePair.first = binding.name().toByteArray(); targetAnchorLinePair.second = binding.parentModelNode(); } @@ -146,7 +178,7 @@ void QmlAnchors::setAnchor(AnchorLineType sourceAnchorLine, removeAnchor(sourceAnchorLine); } - const PropertyName propertyName = anchorPropertyName(sourceAnchorLine); + const PropertyNameView propertyName = anchorPropertyName(sourceAnchorLine); ModelNode targetModelNode = targetQmlItemNode.modelNode(); QString targetExpression = targetModelNode.validId(); if (targetQmlItemNode.modelNode() == qmlItemNode().modelNode().parentProperty().parentModelNode()) @@ -296,7 +328,7 @@ void QmlAnchors::removeAnchor(AnchorLineType sourceAnchorLine) { qmlItemNode().view()->executeInTransaction("QmlAnchors::removeAnchor", [this, sourceAnchorLine](){ if (qmlItemNode().isInBaseState()) { - const PropertyName propertyName = anchorPropertyName(sourceAnchorLine); + const PropertyNameView propertyName = anchorPropertyName(sourceAnchorLine); if (qmlItemNode().nodeInstance().hasAnchor("anchors.fill") && (sourceAnchorLine & AnchorLineFill)) { qmlItemNode().modelNode().removeProperty("anchors.fill"); qmlItemNode().modelNode().bindingProperty("anchors.top").setExpression(QLatin1String("parent.top")); @@ -344,7 +376,7 @@ bool QmlAnchors::instanceHasAnchor(AnchorLineType sourceAnchorLine) const if (!qmlItemNode().isValid()) return false; - const PropertyName propertyName = anchorPropertyName(sourceAnchorLine); + const PropertyNameView propertyName = anchorPropertyName(sourceAnchorLine); if (sourceAnchorLine & AnchorLineFill) return qmlItemNode().nodeInstance().hasAnchor(propertyName) || qmlItemNode().nodeInstance().hasAnchor("anchors.fill"); @@ -418,7 +450,7 @@ double QmlAnchors::instanceAnchorLine(AnchorLineType anchorLine) const void QmlAnchors::setMargin(AnchorLineType sourceAnchorLineType, double margin) const { - PropertyName propertyName = marginPropertyName(sourceAnchorLineType); + PropertyNameView propertyName = marginPropertyName(sourceAnchorLineType); qmlItemNode().setVariantProperty(propertyName, qRound(margin)); } @@ -506,7 +538,7 @@ double QmlAnchors::instanceMargin(AnchorLineType sourceAnchorLineType) const void QmlAnchors::removeMargin(AnchorLineType sourceAnchorLineType) { if (qmlItemNode().isInBaseState()) { - PropertyName propertyName = marginPropertyName(sourceAnchorLineType); + PropertyNameView propertyName = marginPropertyName(sourceAnchorLineType); qmlItemNode().modelNode().removeProperty(propertyName); } } diff --git a/src/plugins/qmldesigner/designercore/model/qmlchangeset.cpp b/src/plugins/qmldesigner/designercore/qmltools/qmlchangeset.cpp similarity index 97% rename from src/plugins/qmldesigner/designercore/model/qmlchangeset.cpp rename to src/plugins/qmldesigner/designercore/qmltools/qmlchangeset.cpp index 134a9a91375..e77656b9672 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlchangeset.cpp +++ b/src/plugins/qmldesigner/designercore/qmltools/qmlchangeset.cpp @@ -78,7 +78,7 @@ bool QmlModelStateOperation::isValidQmlModelStateOperation(const ModelNode &mode return isValidQmlModelNodeFacade(modelNode) && modelNode.metaInfo().isQtQuickStateOperation(); } -void QmlPropertyChanges::removeProperty(const PropertyName &name) +void QmlPropertyChanges::removeProperty(PropertyNameView name) { RewriterTransaction transaction(view()->beginRewriterTransaction(QByteArrayLiteral("QmlPropertyChanges::removeProperty"))); if (name == "name") diff --git a/src/plugins/qmldesigner/designercore/model/qmlconnections.cpp b/src/plugins/qmldesigner/designercore/qmltools/qmlconnections.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/qmlconnections.cpp rename to src/plugins/qmldesigner/designercore/qmltools/qmlconnections.cpp diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/qmltools/qmlitemnode.cpp similarity index 99% rename from src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp rename to src/plugins/qmldesigner/designercore/qmltools/qmlitemnode.cpp index 6e3b739096f..eb1b2329af3 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp +++ b/src/plugins/qmldesigner/designercore/qmltools/qmlitemnode.cpp @@ -1009,7 +1009,7 @@ ModelNode QmlFlowViewNode::createTransition() return transition; } -QList QmlFlowViewNode::transitionsForProperty(const PropertyName &propertyName, +QList QmlFlowViewNode::transitionsForProperty(PropertyNameView propertyName, const ModelNode &modelNode) { QList list; diff --git a/src/plugins/qmldesigner/designercore/model/qmlmodelnodefacade.cpp b/src/plugins/qmldesigner/designercore/qmltools/qmlmodelnodefacade.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/qmlmodelnodefacade.cpp rename to src/plugins/qmldesigner/designercore/qmltools/qmlmodelnodefacade.cpp diff --git a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp b/src/plugins/qmldesigner/designercore/qmltools/qmlobjectnode.cpp similarity index 92% rename from src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp rename to src/plugins/qmldesigner/designercore/qmltools/qmlobjectnode.cpp index 8e1d130295d..a4153fc4464 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp +++ b/src/plugins/qmldesigner/designercore/qmltools/qmlobjectnode.cpp @@ -30,7 +30,7 @@ namespace QmlDesigner { -void QmlObjectNode::setVariantProperty(const PropertyName &name, const QVariant &value) +void QmlObjectNode::setVariantProperty(PropertyNameView name, const QVariant &value) { if (!isValid()) return; @@ -39,7 +39,7 @@ void QmlObjectNode::setVariantProperty(const PropertyName &name, const QVariant return; if (timelineIsActive() && currentTimeline().isRecording()) { - modelNode().validId(); + modelNode().ensureIdExists(); QmlTimelineKeyframeGroup timelineFrames(currentTimeline().keyframeGroup(modelNode(), name)); @@ -69,7 +69,7 @@ void QmlObjectNode::setVariantProperty(const PropertyName &name, const QVariant if (isInBaseState()) { modelNode().variantProperty(name).setValue(value); //basestate } else { - modelNode().validId(); + modelNode().ensureIdExists(); QmlPropertyChanges changeSet(currentState().propertyChanges(modelNode())); Q_ASSERT(changeSet.isValid()); @@ -77,7 +77,7 @@ void QmlObjectNode::setVariantProperty(const PropertyName &name, const QVariant } } -void QmlObjectNode::setBindingProperty(const PropertyName &name, const QString &expression) +void QmlObjectNode::setBindingProperty(PropertyNameView name, const QString &expression) { if (!isValid()) return; @@ -88,7 +88,7 @@ void QmlObjectNode::setBindingProperty(const PropertyName &name, const QString & if (isInBaseState()) { modelNode().bindingProperty(name).setExpression(expression); //basestate } else { - modelNode().validId(); + modelNode().ensureIdExists(); QmlPropertyChanges changeSet(currentState().propertyChanges(modelNode())); Q_ASSERT(changeSet.isValid()); @@ -123,13 +123,12 @@ bool QmlObjectNode::isRootModelNode() const actual instance. The return value is not the value in the model, but the value of a real instantiated instance of this object. */ -QVariant QmlObjectNode::instanceValue(const PropertyName &name) const +QVariant QmlObjectNode::instanceValue(PropertyNameView name) const { return nodeInstance().property(name); } - -bool QmlObjectNode::hasProperty(const PropertyName &name) const +bool QmlObjectNode::hasProperty(PropertyNameView name) const { if (!isValid()) return false; @@ -143,7 +142,7 @@ bool QmlObjectNode::hasProperty(const PropertyName &name) const return modelNode().hasProperty(name); } -bool QmlObjectNode::hasBindingProperty(const PropertyName &name) const +bool QmlObjectNode::hasBindingProperty(PropertyNameView name) const { if (!isValid()) return false; @@ -157,7 +156,7 @@ bool QmlObjectNode::hasBindingProperty(const PropertyName &name) const return modelNode().hasBindingProperty(name); } -NodeAbstractProperty QmlObjectNode::nodeAbstractProperty(const PropertyName &name) const +NodeAbstractProperty QmlObjectNode::nodeAbstractProperty(PropertyNameView name) const { return modelNode().nodeAbstractProperty(name); } @@ -167,22 +166,22 @@ NodeAbstractProperty QmlObjectNode::defaultNodeAbstractProperty() const return modelNode().defaultNodeAbstractProperty(); } -NodeProperty QmlObjectNode::nodeProperty(const PropertyName &name) const +NodeProperty QmlObjectNode::nodeProperty(PropertyNameView name) const { return modelNode().nodeProperty(name); } -NodeListProperty QmlObjectNode::nodeListProperty(const PropertyName &name) const +NodeListProperty QmlObjectNode::nodeListProperty(PropertyNameView name) const { return modelNode().nodeListProperty(name); } -bool QmlObjectNode::instanceHasValue(const PropertyName &name) const +bool QmlObjectNode::instanceHasValue(PropertyNameView name) const { return nodeInstance().hasProperty(name); } -bool QmlObjectNode::propertyAffectedByCurrentState(const PropertyName &name) const +bool QmlObjectNode::propertyAffectedByCurrentState(PropertyNameView name) const { if (!isValid()) return false; @@ -199,7 +198,7 @@ bool QmlObjectNode::propertyAffectedByCurrentState(const PropertyName &name) con return currentState().propertyChanges(modelNode()).modelNode().hasProperty(name); } -QVariant QmlObjectNode::modelValue(const PropertyName &name) const +QVariant QmlObjectNode::modelValue(PropertyNameView name) const { if (!isValid()) return false; @@ -233,7 +232,7 @@ QVariant QmlObjectNode::modelValue(const PropertyName &name) const return propertyChanges.modelNode().variantProperty(name).value(); } -bool QmlObjectNode::isTranslatableText(const PropertyName &name) const +bool QmlObjectNode::isTranslatableText(PropertyNameView name) const { if (modelNode().metaInfo().isValid() && modelNode().metaInfo().hasProperty(name) && modelNode().metaInfo().property(name).propertyType().isString()) { @@ -249,7 +248,7 @@ bool QmlObjectNode::isTranslatableText(const PropertyName &name) const return false; } -QString QmlObjectNode::stripedTranslatableText(const PropertyName &name) const +QString QmlObjectNode::stripedTranslatableText(PropertyNameView name) const { if (modelNode().hasBindingProperty(name)) { static QRegularExpression regularExpressionPattern( @@ -263,7 +262,7 @@ QString QmlObjectNode::stripedTranslatableText(const PropertyName &name) const return instanceValue(name).toString(); } -BindingProperty QmlObjectNode::bindingProperty(const PropertyName &name) const +BindingProperty QmlObjectNode::bindingProperty(PropertyNameView name) const { if (!isValid()) return {}; @@ -282,7 +281,7 @@ BindingProperty QmlObjectNode::bindingProperty(const PropertyName &name) const return propertyChanges.modelNode().bindingProperty(name); } -QString QmlObjectNode::expression(const PropertyName &name) const +QString QmlObjectNode::expression(PropertyNameView name) const { return bindingProperty(name).expression(); } @@ -338,7 +337,7 @@ void QmlObjectNode::ensureAliasExport() return; if (!isAliasExported()) { - modelNode().validId(); + modelNode().ensureIdExists(); ModelNode rootModelNode = view()->rootModelNode(); rootModelNode.bindingProperty(modelNode().id().toUtf8()). setDynamicTypeNameAndExpression("alias", modelNode().id()); @@ -487,7 +486,7 @@ QList QmlObjectNode::getAllConnections() const model. */ -void QmlObjectNode::removeProperty(const PropertyName &name) +void QmlObjectNode::removeProperty(PropertyNameView name) { if (!isValid()) return; @@ -528,7 +527,7 @@ bool QmlObjectNode::isAncestorOf(const QmlObjectNode &objectNode) const return modelNode().isAncestorOf(objectNode.modelNode()); } -QVariant QmlObjectNode::instanceValue(const ModelNode &modelNode, const PropertyName &name) +QVariant QmlObjectNode::instanceValue(const ModelNode &modelNode, PropertyNameView name) { Q_ASSERT(modelNode.view()->nodeInstanceView()->hasInstanceForModelNode(modelNode)); return modelNode.view()->nodeInstanceView()->instanceForModelNode(modelNode).property(name); @@ -569,12 +568,12 @@ QString QmlObjectNode::convertToCorrectTranslatableFunction(const QString &text, return generateTranslatableText(stripedTranslatableTextFunction(text), designerSettings); } -TypeName QmlObjectNode::instanceType(const PropertyName &name) const +TypeName QmlObjectNode::instanceType(PropertyNameView name) const { return nodeInstance().instanceType(name); } -bool QmlObjectNode::instanceHasBinding(const PropertyName &name) const +bool QmlObjectNode::instanceHasBinding(PropertyNameView name) const { return nodeInstance().hasBindingForProperty(name); } diff --git a/src/plugins/qmldesigner/designercore/model/qmlstate.cpp b/src/plugins/qmldesigner/designercore/qmltools/qmlstate.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/qmlstate.cpp rename to src/plugins/qmldesigner/designercore/qmltools/qmlstate.cpp diff --git a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp b/src/plugins/qmldesigner/designercore/qmltools/qmltextgenerator.cpp similarity index 99% rename from src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp rename to src/plugins/qmldesigner/designercore/qmltools/qmltextgenerator.cpp index 921f838ff90..e332feba19a 100644 --- a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp +++ b/src/plugins/qmldesigner/designercore/qmltools/qmltextgenerator.cpp @@ -38,7 +38,7 @@ static bool isLowPrecisionProperties(PropertyNameView property) return std::find(std::begin(properties), std::end(properties), property) != std::end(properties); } -static QString doubleToString(const PropertyName &propertyName, double d) +static QString doubleToString(PropertyNameView propertyName, double d) { int precision = 5; if (propertyName.contains("anchors") || propertyName.contains("font") diff --git a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.h b/src/plugins/qmldesigner/designercore/qmltools/qmltextgenerator.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/qmltextgenerator.h rename to src/plugins/qmldesigner/designercore/qmltools/qmltextgenerator.h diff --git a/src/plugins/qmldesigner/designercore/model/qmltimeline.cpp b/src/plugins/qmldesigner/designercore/qmltools/qmltimeline.cpp similarity index 94% rename from src/plugins/qmldesigner/designercore/model/qmltimeline.cpp rename to src/plugins/qmldesigner/designercore/qmltools/qmltimeline.cpp index ae0f675d793..85c4db30c5f 100644 --- a/src/plugins/qmldesigner/designercore/model/qmltimeline.cpp +++ b/src/plugins/qmldesigner/designercore/qmltools/qmltimeline.cpp @@ -41,7 +41,8 @@ void QmlTimeline::destroy() modelNode().destroy(); } -QmlTimelineKeyframeGroup QmlTimeline::keyframeGroup(const ModelNode &node, const PropertyName &propertyName) +QmlTimelineKeyframeGroup QmlTimeline::keyframeGroup(const ModelNode &node, + PropertyNameView propertyName) { if (isValid()) { addKeyframeGroupIfNotExists(node, propertyName); @@ -60,7 +61,7 @@ QmlTimelineKeyframeGroup QmlTimeline::keyframeGroup(const ModelNode &node, const return QmlTimelineKeyframeGroup(); //not found } -bool QmlTimeline::hasTimeline(const ModelNode &node, const PropertyName &propertyName) +bool QmlTimeline::hasTimeline(const ModelNode &node, PropertyNameView propertyName) { if (isValid()) { for (const ModelNode &childNode : modelNode().defaultNodeListProperty().toModelNodeList()) { @@ -185,7 +186,7 @@ void QmlTimeline::destroyKeyframesForTarget(const ModelNode &target) } void QmlTimeline::removeKeyframesForTargetAndProperty(const ModelNode &target, - const PropertyName &propertyName) + PropertyNameView propertyName) { for (QmlTimelineKeyframeGroup frames : keyframeGroupsForTarget(target)) { if (frames.propertyName() == propertyName) @@ -236,7 +237,7 @@ void QmlTimeline::resetGroupRecording() const } } -void QmlTimeline::addKeyframeGroupIfNotExists(const ModelNode &node, const PropertyName &propertyName) +void QmlTimeline::addKeyframeGroupIfNotExists(const ModelNode &node, PropertyNameView propertyName) { if (!isValid()) return; @@ -253,8 +254,7 @@ void QmlTimeline::addKeyframeGroupIfNotExists(const ModelNode &node, const Prope } } - -bool QmlTimeline::hasKeyframeGroup(const ModelNode &node, const PropertyName &propertyName) const +bool QmlTimeline::hasKeyframeGroup(const ModelNode &node, PropertyNameView propertyName) const { for (const QmlTimelineKeyframeGroup &frames : allKeyframeGroups()) { if (frames.target().isValid() @@ -279,7 +279,7 @@ bool QmlTimeline::hasKeyframeGroupForTarget(const ModelNode &node) const return false; } -void QmlTimeline::insertKeyframe(const ModelNode &target, const PropertyName &propertyName) +void QmlTimeline::insertKeyframe(const ModelNode &target, PropertyNameView propertyName) { ModelNode targetNode = target; QmlTimelineKeyframeGroup timelineFrames(keyframeGroup(targetNode, propertyName)); diff --git a/src/plugins/qmldesigner/designercore/model/qmltimelinekeyframegroup.cpp b/src/plugins/qmldesigner/designercore/qmltools/qmltimelinekeyframegroup.cpp similarity index 99% rename from src/plugins/qmldesigner/designercore/model/qmltimelinekeyframegroup.cpp rename to src/plugins/qmldesigner/designercore/qmltools/qmltimelinekeyframegroup.cpp index 7cee6095bb4..c692ccaed04 100644 --- a/src/plugins/qmldesigner/designercore/model/qmltimelinekeyframegroup.cpp +++ b/src/plugins/qmldesigner/designercore/qmltools/qmltimelinekeyframegroup.cpp @@ -57,7 +57,7 @@ PropertyName QmlTimelineKeyframeGroup::propertyName() const return modelNode().variantProperty("property").value().toString().toUtf8(); } -void QmlTimelineKeyframeGroup::setPropertyName(const PropertyName &propertyName) +void QmlTimelineKeyframeGroup::setPropertyName(PropertyNameView propertyName) { modelNode().variantProperty("property").setValue(QString::fromUtf8(propertyName)); } diff --git a/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp b/src/plugins/qmldesigner/designercore/qmltools/qmlvisualnode.cpp similarity index 98% rename from src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp rename to src/plugins/qmldesigner/designercore/qmltools/qmlvisualnode.cpp index 726d3d52af4..5e919a40c9b 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp +++ b/src/plugins/qmldesigner/designercore/qmltools/qmlvisualnode.cpp @@ -200,10 +200,13 @@ void QmlVisualNode::scatter(const ModelNode &targetNode, const std::optional +#include +#include + +namespace QmlDesigner { + +using namespace QmlDesigner::Internal; + + +// Creates invalid PropertyContainer +PropertyContainer::PropertyContainer() = default; + +PropertyContainer::PropertyContainer(const PropertyName &name, const QString &type, const QVariant &value) + : m_name(name), m_type(type), m_value(value) +{ + Q_ASSERT_X(!name.isEmpty(), Q_FUNC_INFO, "Name of property cannot be empty"); + Q_ASSERT_X(!type.isEmpty(), Q_FUNC_INFO, "Type of property cannot be empty"); +} + +void PropertyContainer::set(const PropertyName &name, const QString &type, const QVariant &value) +{ + m_name = name; + m_type = type; + m_value = value; +} + +bool PropertyContainer::isValid() const +{ + return !m_name.isEmpty() && m_value.isValid(); +} + +PropertyName PropertyContainer::name() const +{ + return m_name; +} + +QVariant PropertyContainer::value() const +{ + if (m_value.typeId() == QVariant::String) + m_value = PropertyParser::read(m_type, m_value.toString()); + return m_value; +} + + +void PropertyContainer::setValue(const QVariant &value) +{ + m_value = value; +} + +QString PropertyContainer::type() const +{ + return m_type; +} + +QDataStream &operator<<(QDataStream &stream, const PropertyContainer &propertyContainer) +{ + Q_ASSERT(!propertyContainer.name().isEmpty()); + Q_ASSERT(!propertyContainer.type().isEmpty()); + Q_ASSERT(propertyContainer.value().isValid()); + stream << propertyContainer.name(); + stream << propertyContainer.type(); + stream << propertyContainer.value(); + + + return stream; +} + +QDataStream &operator>>(QDataStream &stream, PropertyContainer &propertyContainer) +{ + + stream >> propertyContainer.m_name; + stream >> propertyContainer.m_type; + stream >> propertyContainer.m_value; + + Q_ASSERT(!propertyContainer.name().isEmpty()); + + return stream; +} + +QDebug operator<<(QDebug debug, const PropertyContainer &propertyContainer) +{ + debug << propertyContainer.m_name; + debug << propertyContainer.m_type; + debug << propertyContainer.m_value; + + return debug.space(); +} + +} //namespace QmlDesigner + diff --git a/src/plugins/qmldesigner/designercore/model/propertynode.cpp b/src/plugins/qmldesigner/designercore/rewriter/propertynode.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/propertynode.cpp rename to src/plugins/qmldesigner/designercore/rewriter/propertynode.cpp diff --git a/src/plugins/qmldesigner/designercore/model/propertyparser.cpp b/src/plugins/qmldesigner/designercore/rewriter/propertyparser.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/propertyparser.cpp rename to src/plugins/qmldesigner/designercore/rewriter/propertyparser.cpp diff --git a/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp b/src/plugins/qmldesigner/designercore/rewriter/rewriteaction.cpp similarity index 99% rename from src/plugins/qmldesigner/designercore/model/rewriteaction.cpp rename to src/plugins/qmldesigner/designercore/rewriter/rewriteaction.cpp index 3d301488612..94d5e905aa2 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp +++ b/src/plugins/qmldesigner/designercore/rewriter/rewriteaction.cpp @@ -8,6 +8,8 @@ #include "nodelistproperty.h" #include "nodemetainfo.h" +#include + using namespace QmlDesigner; using namespace QmlDesigner::Internal; using namespace QmlDesigner; @@ -287,7 +289,7 @@ bool ReparentNodeRewriteAction::execute(QmlRefactoring &refactoring, ModelNodePo const bool isArrayBinding = m_targetProperty.isNodeListProperty(); bool result = false; - PropertyName targetPropertyName; + PropertyNameView targetPropertyName; if (!m_targetProperty.isDefaultProperty()) targetPropertyName = m_targetProperty.name(); diff --git a/src/plugins/qmldesigner/designercore/model/rewriteaction.h b/src/plugins/qmldesigner/designercore/rewriter/rewriteaction.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/rewriteaction.h rename to src/plugins/qmldesigner/designercore/rewriter/rewriteaction.h diff --git a/src/plugins/qmldesigner/designercore/model/rewriteactioncompressor.cpp b/src/plugins/qmldesigner/designercore/rewriter/rewriteactioncompressor.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/rewriteactioncompressor.cpp rename to src/plugins/qmldesigner/designercore/rewriter/rewriteactioncompressor.cpp diff --git a/src/plugins/qmldesigner/designercore/model/rewriteactioncompressor.h b/src/plugins/qmldesigner/designercore/rewriter/rewriteactioncompressor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/rewriteactioncompressor.h rename to src/plugins/qmldesigner/designercore/rewriter/rewriteactioncompressor.h diff --git a/src/plugins/qmldesigner/designercore/rewritertransaction.cpp b/src/plugins/qmldesigner/designercore/rewriter/rewritertransaction.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/rewritertransaction.cpp rename to src/plugins/qmldesigner/designercore/rewriter/rewritertransaction.cpp diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp similarity index 83% rename from src/plugins/qmldesigner/designercore/model/rewriterview.cpp rename to src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp index 3c481573d2e..6565208385c 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp @@ -3,9 +3,9 @@ #include "rewriterview.h" -#include "texttomodelmerger.h" -#include "modeltotextmerger.h" #include "model_p.h" +#include "modeltotextmerger.h" +#include "texttomodelmerger.h" #include #include @@ -36,9 +36,9 @@ #include #include +#include #include #include -#include using namespace QmlDesigner::Internal; using namespace Qt::StringLiterals; @@ -68,12 +68,21 @@ RewriterView::RewriterView(ExternalDependenciesInterface &externalDependencies, connect(&m_amendTimer, &QTimer::timeout, this, &RewriterView::amendQmlText); QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); - connect(modelManager, &QmlJS::ModelManagerInterface::libraryInfoUpdated, - this, &RewriterView::handleLibraryInfoUpdate, Qt::QueuedConnection); - connect(modelManager, &QmlJS::ModelManagerInterface::projectInfoUpdated, - this, &RewriterView::handleProjectUpdate, Qt::DirectConnection); - connect(this, &RewriterView::modelInterfaceProjectUpdated, - this, &RewriterView::handleLibraryInfoUpdate, Qt::QueuedConnection); + connect(modelManager, + &QmlJS::ModelManagerInterface::libraryInfoUpdated, + this, + &RewriterView::handleLibraryInfoUpdate, + Qt::QueuedConnection); + connect(modelManager, + &QmlJS::ModelManagerInterface::projectInfoUpdated, + this, + &RewriterView::handleProjectUpdate, + Qt::DirectConnection); + connect(this, + &RewriterView::modelInterfaceProjectUpdated, + this, + &RewriterView::handleLibraryInfoUpdate, + Qt::QueuedConnection); } RewriterView::~RewriterView() = default; @@ -90,6 +99,7 @@ Internal::TextToModelMerger *RewriterView::textToModelMerger() const void RewriterView::modelAttached(Model *model) { + QTC_ASSERT(m_textModifier, return); m_modelAttachPending = false; AbstractView::modelAttached(model); @@ -104,7 +114,7 @@ void RewriterView::modelAttached(Model *model) if (hasIncompleteTypeInformation()) { m_modelAttachPending = true; - QTimer::singleShot(1000, this, [this, model](){ + QTimer::singleShot(1000, this, [this, model]() { modelAttached(model); restoreAuxiliaryData(); }); @@ -129,7 +139,9 @@ void RewriterView::nodeCreated(const ModelNode &createdNode) applyChanges(); } -void RewriterView::nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange) +void RewriterView::nodeRemoved(const ModelNode &removedNode, + const NodeAbstractProperty &parentProperty, + PropertyChangeFlags propertyChange) { Q_ASSERT(textModifier()); if (textToModelMerger()->isActive()) @@ -153,13 +165,14 @@ void RewriterView::propertiesAboutToBeRemoved(const QList &pro if (!m_removeDefaultPropertyTransaction.isValid()) { m_removeDefaultPropertyTransaction = beginRewriterTransaction( - QByteArrayLiteral("RewriterView::propertiesAboutToBeRemoved")); + QByteArrayLiteral("RewriterView::propertiesAboutToBeRemoved")); } if (property.isNodeListProperty()) { const auto nodeList = property.toNodeListProperty().toModelNodeList(); for (const ModelNode &node : nodeList) { - modelToTextMerger()->nodeRemoved(node, property.toNodeAbstractProperty(), + modelToTextMerger()->nodeRemoved(node, + property.toNodeAbstractProperty(), AbstractView::NoAdditionalChanges); } } else if (property.isBindingProperty() || property.isVariantProperty() @@ -172,7 +185,7 @@ void RewriterView::propertiesAboutToBeRemoved(const QList &pro } } -void RewriterView::propertiesRemoved(const QList& propertyList) +void RewriterView::propertiesRemoved(const QList &propertyList) { Q_ASSERT(textModifier()); if (textToModelMerger()->isActive()) @@ -187,7 +200,8 @@ void RewriterView::propertiesRemoved(const QList& propertyList applyChanges(); } -void RewriterView::variantPropertiesChanged(const QList& propertyList, PropertyChangeFlags propertyChange) +void RewriterView::variantPropertiesChanged(const QList &propertyList, + PropertyChangeFlags propertyChange) { Q_ASSERT(textModifier()); if (textToModelMerger()->isActive()) @@ -203,7 +217,8 @@ void RewriterView::variantPropertiesChanged(const QList& proper applyChanges(); } -void RewriterView::bindingPropertiesChanged(const QList& propertyList, PropertyChangeFlags propertyChange) +void RewriterView::bindingPropertiesChanged(const QList &propertyList, + PropertyChangeFlags propertyChange) { Q_ASSERT(textModifier()); if (textToModelMerger()->isActive()) @@ -219,7 +234,8 @@ void RewriterView::bindingPropertiesChanged(const QList& proper applyChanges(); } -void RewriterView::signalHandlerPropertiesChanged(const QVector &propertyList, AbstractView::PropertyChangeFlags propertyChange) +void RewriterView::signalHandlerPropertiesChanged(const QVector &propertyList, + AbstractView::PropertyChangeFlags propertyChange) { Q_ASSERT(textModifier()); if (textToModelMerger()->isActive()) @@ -235,7 +251,8 @@ void RewriterView::signalHandlerPropertiesChanged(const QVector &propertyList, PropertyChangeFlags propertyChange) +void RewriterView::signalDeclarationPropertiesChanged( + const QVector &propertyList, PropertyChangeFlags propertyChange) { Q_ASSERT(textModifier()); if (textToModelMerger()->isActive()) @@ -251,7 +268,10 @@ void RewriterView::signalDeclarationPropertiesChanged(const QVectorisActive()) @@ -293,7 +313,7 @@ void RewriterView::importsRemoved(const Imports &imports) applyChanges(); } -void RewriterView::nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) +void RewriterView::nodeIdChanged(const ModelNode &node, const QString &newId, const QString &oldId) { Q_ASSERT(textModifier()); if (textToModelMerger()->isActive()) @@ -340,7 +360,7 @@ void RewriterView::nodeOrderChanged(const NodeListProperty &listProperty) void RewriterView::rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion) { - Q_ASSERT(textModifier()); + Q_ASSERT(textModifier()); if (textToModelMerger()->isActive()) return; @@ -350,7 +370,10 @@ void RewriterView::rootNodeTypeChanged(const QString &type, int majorVersion, in applyChanges(); } -void RewriterView::nodeTypeChanged(const ModelNode &node, const TypeName &type, int majorVersion, int minorVersion) +void RewriterView::nodeTypeChanged(const ModelNode &node, + const TypeName &type, + int majorVersion, + int minorVersion) { Q_ASSERT(textModifier()); if (textToModelMerger()->isActive()) @@ -362,7 +385,10 @@ void RewriterView::nodeTypeChanged(const ModelNode &node, const TypeName &type, applyChanges(); } -void RewriterView::customNotification(const AbstractView * /*view*/, const QString &identifier, const QList & /* nodeList */, const QList & /*data */) +void RewriterView::customNotification(const AbstractView * /*view*/, + const QString &identifier, + const QList & /* nodeList */, + const QList & /*data */) { if (identifier == StartRewriterAmend || identifier == EndRewriterAmend) return; // we emitted this ourselves, so just ignore these notifications. @@ -378,8 +404,7 @@ void RewriterView::rewriterEndTransaction() { transactionLevel--; Q_ASSERT(transactionLevel >= 0); - if (transactionLevel == 0) - { + if (transactionLevel == 0) { setModificationGroupActive(false); applyModificationGroupChanges(); } @@ -419,13 +444,13 @@ QString RewriterView::textModifierContent() const return QString(); } -void RewriterView::reactivateTextMofifierChangeSignals() +void RewriterView::reactivateTextModifierChangeSignals() { if (textModifier()) textModifier()->reactivateChangeSignals(); } -void RewriterView::deactivateTextMofifierChangeSignals() +void RewriterView::deactivateTextModifierChangeSignals() { if (textModifier()) textModifier()->deactivateChangeSignals(); @@ -433,7 +458,7 @@ void RewriterView::deactivateTextMofifierChangeSignals() void RewriterView::auxiliaryDataChanged(const ModelNode &, AuxiliaryDataKeyView key, const QVariant &) { - if (m_restoringAuxData) + if (m_restoringAuxData || !m_textModifier) return; if (key.type == AuxiliaryDataType::Document) @@ -455,9 +480,14 @@ void RewriterView::applyChanges() if (inErrorState()) { const QString content = textModifierContent(); - qDebug().noquote() << "RewriterView::applyChanges() got called while in error state. Will do a quick-exit now."; + qDebug().noquote() << "RewriterView::applyChanges() got called while in error state. Will " + "do a quick-exit now."; qDebug().noquote() << "Content: " << content; - throw RewritingException(__LINE__, __FUNCTION__, __FILE__, "RewriterView::applyChanges() already in error state", content); + throw RewritingException(__LINE__, + __FUNCTION__, + __FILE__, + "RewriterView::applyChanges() already in error state", + content); } m_differenceHandling = Validate; @@ -481,18 +511,21 @@ void RewriterView::applyChanges() qDebug().noquote() << "Content: " << content; if (!errors().isEmpty()) qDebug().noquote() << "Error:" << errors().constFirst().description(); - throw RewritingException(__LINE__, __FUNCTION__, __FILE__, qPrintable(m_rewritingErrorMessage), content); + throw RewritingException(__LINE__, + __FUNCTION__, + __FILE__, + qPrintable(m_rewritingErrorMessage), + content); } } void RewriterView::amendQmlText() { - if (!model()->rewriterView()) return; + QTC_ASSERT(m_textModifier, return); emitCustomNotification(StartRewriterAmend); - const QString newQmlText = m_textModifier->text(); ModelAmender differenceHandler(m_textToModelMerger.get()); @@ -518,40 +551,15 @@ static QString replaceIllegalPropertyNameChars(const QString &str) return ret; } -static bool idIsQmlKeyWord(const QString& id) +static bool idIsQmlKeyWord(QStringView id) { - static const QSet keywords = { - "as", - "break", - "case", - "catch", - "continue", - "debugger", - "default", - "delete", - "do", - "else", - "finally", - "for", - "function", - "if", - "import", - "in", - "instanceof", - "new", - "return", - "switch", - "this", - "throw", - "try", - "typeof", - "var", - "void", - "while", - "with" - }; + static constexpr std::u16string_view keywords[] = { + u"as", u"break", u"case", u"catch", u"continue", u"debugger", u"default", + u"delete", u"do", u"else", u"finally", u"for", u"function", u"if", + u"import", u"in", u"instanceof", u"new", u"return", u"switch", u"this", + u"throw", u"try", u"typeof", u"var", u"void", u"while", u"with"}; - return keywords.contains(id); + return Utils::contains(keywords, std::u16string_view{id.utf16(), Utils::usize(id)}); } QString RewriterView::auxiliaryDataAsQML() const @@ -566,7 +574,7 @@ QString RewriterView::auxiliaryDataAsQML() const int columnCount = 0; - const QRegularExpression safeName("^[a-z][a-zA-Z0-9]*$"); + static const QRegularExpression safeName(R"(^[a-z][a-zA-Z0-9]*$)"); for (const auto &node : allModelNodes()) { auto data = node.auxiliaryData(AuxiliaryDataType::Document); @@ -598,8 +606,7 @@ QString RewriterView::auxiliaryDataAsQML() const const int metaType = value.typeId(); - if (metaType == QMetaType::QString - || metaType == QMetaType::QColor) { + if (metaType == QMetaType::QString || metaType == QMetaType::QColor) { strValue.replace("\\"_L1, "\\\\"_L1); strValue.replace("\""_L1, "\\\""_L1); strValue.replace("\t"_L1, "\\t"_L1); @@ -650,7 +657,8 @@ void RewriterView::sanitizeModel() QList danglingNodes; const auto danglingStates = root.allInvalidStateOperations(); - const auto danglingKeyframeGroups = QmlTimelineKeyframeGroup::allInvalidTimelineKeyframeGroups(this); + const auto danglingKeyframeGroups = QmlTimelineKeyframeGroup::allInvalidTimelineKeyframeGroups( + this); std::transform(danglingStates.begin(), danglingStates.end(), @@ -756,6 +764,7 @@ void RewriterView::enterErrorState(const QString &errorMessage) void RewriterView::resetToLastCorrectQml() { + QTC_ASSERT(m_textModifier, return); m_textModifier->textDocument()->undo(); m_textModifier->textDocument()->clearUndoRedoStacks(QTextDocument::RedoStack); ModelAmender differenceHandler(m_textToModelMerger.get()); @@ -768,6 +777,7 @@ void RewriterView::resetToLastCorrectQml() QMap RewriterView::extractText(const QList &nodes) const { + QTC_ASSERT(m_textModifier, return {}); QmlDesigner::ASTObjectTextExtractor extract(m_textModifier->text()); QMap result; @@ -794,6 +804,7 @@ int RewriterView::nodeOffset(const ModelNode &node) const */ int RewriterView::nodeLength(const ModelNode &node) const { + QTC_ASSERT(m_textModifier, return -1); ObjectLengthCalculator objectLengthCalculator; unsigned length; if (objectLengthCalculator(m_textModifier->text(), nodeOffset(node), length)) @@ -804,14 +815,16 @@ int RewriterView::nodeLength(const ModelNode &node) const int RewriterView::firstDefinitionInsideOffset(const ModelNode &node) const { + QTC_ASSERT(m_textModifier, return -1); FirstDefinitionFinder firstDefinitionFinder(m_textModifier->text()); return firstDefinitionFinder(nodeOffset(node)); } int RewriterView::firstDefinitionInsideLength(const ModelNode &node) const { + QTC_ASSERT(m_textModifier, return -1); FirstDefinitionFinder firstDefinitionFinder(m_textModifier->text()); - const int offset = firstDefinitionFinder(nodeOffset(node)); + const int offset = firstDefinitionFinder(nodeOffset(node)); ObjectLengthCalculator objectLengthCalculator; unsigned length; @@ -831,9 +844,31 @@ static bool isInNodeDefinition(int nodeTextOffset, int nodeTextLength, int curso return (nodeTextOffset <= cursorPosition) && (nodeTextOffset + nodeTextLength > cursorPosition); } +int findEvenClosingBrace(const QStringView &string) +{ + int count = 0; + int index = 0; + + for (auto currentChar : string) { + if (currentChar == '{') + count++; + + if (currentChar == '}') { + if (count == 1) + return index; + else + count--; + } + index++; + } + return index; +} + ModelNode RewriterView::nodeAtTextCursorPositionHelper(const ModelNode &root, int cursorPosition) const { - using myPair = std::pair; + QTC_ASSERT(m_textModifier, return {}); + + using myPair = std::pair; std::vector data; for (const ModelNode &node : allModelNodes()) { @@ -842,9 +877,7 @@ ModelNode RewriterView::nodeAtTextCursorPositionHelper(const ModelNode &root, in data.emplace_back(std::make_pair(node, offset)); } - std::sort(data.begin(), data.end(), [](myPair a, myPair b) { - return a.second < b.second; - }); + std::sort(data.begin(), data.end(), [](myPair a, myPair b) { return a.second < b.second; }); ModelNode lastNode = root; @@ -852,7 +885,9 @@ ModelNode RewriterView::nodeAtTextCursorPositionHelper(const ModelNode &root, in ModelNode node = pair.first; const int nodeTextOffset = nodeOffset(node); - const int nodeTextLength = m_textModifier->text().indexOf("}", nodeTextOffset) - nodeTextOffset - 1; + + const int nodeTextLength = findEvenClosingBrace(m_textModifier->text().sliced(nodeTextOffset)) + - 1; if (isInNodeDefinition(nodeTextOffset, nodeTextLength, cursorPosition)) lastNode = node; @@ -868,7 +903,7 @@ void RewriterView::setupCanonicalHashes() const m_canonicalIntModelNode.clear(); m_canonicalModelNodeInt.clear(); - using myPair = std::pair; + using myPair = std::pair; std::vector data; for (const ModelNode &node : allModelNodes()) { @@ -877,9 +912,7 @@ void RewriterView::setupCanonicalHashes() const data.emplace_back(std::make_pair(node, offset)); } - std::sort(data.begin(), data.end(), [](myPair a, myPair b) { - return a.second < b.second; - }); + std::sort(data.begin(), data.end(), [](myPair a, myPair b) { return a.second < b.second; }); int i = 0; for (const myPair &pair : data) { @@ -909,26 +942,28 @@ ModelNode RewriterView::nodeAtTextCursorPosition(int cursorPosition) const return nodeAtTextCursorPositionHelper(rootModelNode(), cursorPosition); } -bool RewriterView::renameId(const QString& oldId, const QString& newId) +bool RewriterView::renameId(const QString &oldId, const QString &newId) { if (textModifier()) { PropertyName propertyName = oldId.toUtf8(); bool hasAliasExport = rootModelNode().isValid() - && rootModelNode().hasBindingProperty(propertyName) - && rootModelNode().bindingProperty(propertyName).isAliasExport(); + && rootModelNode().hasBindingProperty(propertyName) + && rootModelNode().bindingProperty(propertyName).isAliasExport(); bool instant = m_instantQmlTextUpdate; m_instantQmlTextUpdate = true; - bool refactoring = textModifier()->renameId(oldId, newId); + bool refactoring = textModifier()->renameId(oldId, newId); m_instantQmlTextUpdate = instant; if (refactoring && hasAliasExport) { //Keep export alias properties rootModelNode().removeProperty(propertyName); PropertyName newPropertyName = newId.toUtf8(); - rootModelNode().bindingProperty(newPropertyName).setDynamicTypeNameAndExpression("alias", QString::fromUtf8(newPropertyName)); + rootModelNode() + .bindingProperty(newPropertyName) + .setDynamicTypeNameAndExpression("alias", QString::fromUtf8(newPropertyName)); } return refactoring; } @@ -1002,7 +1037,7 @@ QStringList RewriterView::importDirectories() const return Utils::transform(list, [](const Utils::FilePath &p) { return p.toString(); }); } -QSet > RewriterView::qrcMapping() const +QSet> RewriterView::qrcMapping() const { return m_textToModelMerger->qrcMapping(); } @@ -1116,8 +1151,7 @@ QList RewriterView::getQMLTypes() const for (const QmlJS::ModelManagerInterface::CppData &cppData : QmlJS::ModelManagerInterface::instance()->cppData()) for (const LanguageUtils::FakeMetaObject::ConstPtr &fakeMetaObject : cppData.exportedTypes) { - for (const LanguageUtils::FakeMetaObject::Export &exportItem : - fakeMetaObject->exports()) { + for (const LanguageUtils::FakeMetaObject::Export &exportItem : fakeMetaObject->exports()) { QmlTypeData qmlData; qmlData.cppClassName = fakeMetaObject->className(); qmlData.typeName = exportItem.type; @@ -1134,7 +1168,7 @@ QList RewriterView::getQMLTypes() const return qmlDataList; } -void RewriterView::setWidgetStatusCallback(std::function setWidgetStatusCallback) +void RewriterView::setWidgetStatusCallback(std::function setWidgetStatusCallback) { m_setWidgetStatusCallback = setWidgetStatusCallback; } @@ -1143,36 +1177,35 @@ void RewriterView::qmlTextChanged() { if (inErrorState()) return; + QTC_ASSERT(m_textModifier, return); - if (m_textToModelMerger && m_textModifier) { - const QString newQmlText = m_textModifier->text(); + const QString newQmlText = m_textModifier->text(); #if 0 - qDebug() << Q_FUNC_INFO; - qDebug() << "old:" << lastCorrectQmlSource; - qDebug() << "new:" << newQmlText; + qDebug() << Q_FUNC_INFO; + qDebug() << "old:" << lastCorrectQmlSource; + qDebug() << "new:" << newQmlText; #endif - switch (m_differenceHandling) { - case Validate: { - ModelValidator differenceHandler(m_textToModelMerger.get()); - if (m_textToModelMerger->load(newQmlText, differenceHandler)) - m_lastCorrectQmlSource = newQmlText; - break; - } + switch (m_differenceHandling) { + case Validate: { + ModelValidator differenceHandler(m_textToModelMerger.get()); + if (m_textToModelMerger->load(newQmlText, differenceHandler)) + m_lastCorrectQmlSource = newQmlText; + break; + } - case Amend: { - if (m_instantQmlTextUpdate || externalDependencies().instantQmlTextUpdate()) { - amendQmlText(); - } else { - if (externalDependencies().viewManagerUsesRewriterView(this)) { - externalDependencies().viewManagerDiableWidgets(); - m_amendTimer.start(); - } + case Amend: { + if (m_instantQmlTextUpdate || externalDependencies().instantQmlTextUpdate()) { + amendQmlText(); + } else { + if (externalDependencies().viewManagerUsesRewriterView(this)) { + externalDependencies().viewManagerDiableWidgets(); + m_amendTimer.start(); } - break; - } } + break; + } } } @@ -1303,4 +1336,4 @@ void RewriterView::restoreAuxiliaryData() m_restoringAuxData = false; } -} //QmlDesigner +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/textmodifier.cpp b/src/plugins/qmldesigner/designercore/rewriter/textmodifier.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/textmodifier.cpp rename to src/plugins/qmldesigner/designercore/rewriter/textmodifier.cpp diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/rewriter/texttomodelmerger.cpp similarity index 98% rename from src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp rename to src/plugins/qmldesigner/designercore/rewriter/texttomodelmerger.cpp index eda3fd1bf7b..cde2df725bc 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/rewriter/texttomodelmerger.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include @@ -408,7 +408,10 @@ bool equals(const QVariant &a, const QVariant &b) bool usesCustomParserButIsNotPropertyChange(const QmlDesigner::NodeMetaInfo &nodeMetaInfo) { - return nodeMetaInfo.usesCustomParser() && !nodeMetaInfo.isQtQuickPropertyChanges(); + bool usesCustomParser = nodeMetaInfo.usesCustomParser(); + bool isQtQuickPropertyChanges = nodeMetaInfo.isQtQuickPropertyChanges(); + + return usesCustomParser && !isQtQuickPropertyChanges; } } // anonymous namespace @@ -778,12 +781,14 @@ bool skipModule(QStringView moduleName) } void collectPossibleFileImports(const QString &checkPath, + const QDir &docDir, QSet usedImportsSet, QList &possibleImports) { const QStringList qmlList("*.qml"); const QStringList qmldirList("qmldir"); const QChar delimeter('/'); + const QString upDir("../"); if (QFileInfo(checkPath).isRoot()) return; @@ -796,30 +801,20 @@ void collectPossibleFileImports(const QString &checkPath, if (!dir.entryInfoList(qmlList, QDir::Files).isEmpty() && dir.entryInfoList(qmldirList, QDir::Files).isEmpty() && !usedImportsSet.contains(dirPath)) { - const QString importName = dir.path().mid(checkPath.size() + 1); - QmlDesigner::Import import = QmlDesigner::Import::createFileImport(importName); - possibleImports.append(import); + const QString importName = docDir.relativeFilePath(dirPath); + + // Omit all imports that would be just "../", "../../" etc. without additional subfolder, + // as we don't want to encourage bad design. "../MySharedComps" is a legitimate + // use, though. + if (!importName.startsWith(upDir) || importName.lastIndexOf(upDir) != importName.size() - 3) { + QmlDesigner::Import import = QmlDesigner::Import::createFileImport(importName); + possibleImports.append(import); + } } - collectPossibleFileImports(dirPath, usedImportsSet, possibleImports); + collectPossibleFileImports(dirPath, docDir, usedImportsSet, possibleImports); } } -QList generatePossibleFileImports(const QString &path, - const QList &usedImports) -{ - QSet usedImportsSet; - for (const QmlJS::Import &i : usedImports) - usedImportsSet.insert(i.info.path()); - - QList possibleImports; - - QStringList fileImportPaths; - - collectPossibleFileImports(path, usedImportsSet, possibleImports); - - return possibleImports; -} - QmlDesigner::Imports createQt5Modules() { return {QmlDesigner::Import::createLibraryImport("QtQuick", "2.15"), @@ -829,7 +824,7 @@ QmlDesigner::Imports createQt5Modules() QmlDesigner::Import::createLibraryImport("QtQuick.Timeline", "1.0"), QmlDesigner::Import::createLibraryImport("QtCharts", "2.15"), QmlDesigner::Import::createLibraryImport("QtDataVisulaization", "2.15"), - QmlDesigner::Import::createLibraryImport("QtQuick.Studio.Controls", "1.0"), + QmlDesigner::Import::createLibraryImport("QtQuick.Studio.Components", "1.0"), QmlDesigner::Import::createLibraryImport("QtQuick.Studio.Effects", "1.0"), QmlDesigner::Import::createLibraryImport("FlowView", "1.0"), QmlDesigner::Import::createLibraryImport("QtQuick.Studio.LogicHelper", "1.0"), @@ -882,6 +877,25 @@ void TextToModelMerger::setupPossibleImports() if (m_rewriterView->isAttached()) m_rewriterView->model()->setPossibleImports(modules); } + +QList TextToModelMerger::generatePossibleFileImports( + const QString &path, const QList &usedImports) const +{ + if (!m_rewriterView) + return {}; + + QSet usedImportsSet; + for (const QmlJS::Import &i : usedImports) + usedImportsSet.insert(i.info.path()); + + QList possibleImports; + + collectPossibleFileImports(m_rewriterView->externalDependencies().currentResourcePath().toLocalFile(), + QDir(path), usedImportsSet, possibleImports); + + return possibleImports; +} + #endif #ifndef QDS_USE_PROJECTSTORAGE @@ -1147,7 +1161,7 @@ void TextToModelMerger::syncNode(ModelNode &modelNode, if (info.isQmlComponent() || isImplicitComponent) setupComponentDelayed(modelNode, differenceHandler.isAmender()); - else if (info.usesCustomParser()) + else if (usesCustomParserButIsNotPropertyChange(info)) setupCustomParserNodeDelayed(modelNode, differenceHandler.isAmender()); else if (!modelNode.nodeSource().isEmpty() || modelNode.nodeSourceType() != ModelNode::NodeWithoutSource) clearImplicitComponentDelayed(modelNode, differenceHandler.isAmender()); diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.h b/src/plugins/qmldesigner/designercore/rewriter/texttomodelmerger.h similarity index 98% rename from src/plugins/qmldesigner/designercore/model/texttomodelmerger.h rename to src/plugins/qmldesigner/designercore/rewriter/texttomodelmerger.h index e22f747718a..8abb7bcad9f 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.h +++ b/src/plugins/qmldesigner/designercore/rewriter/texttomodelmerger.h @@ -141,7 +141,10 @@ private: static QString textAt(const QmlJS::Document::Ptr &doc, const QmlJS::SourceLocation &from, const QmlJS::SourceLocation &to); - +#ifndef QDS_USE_PROJECTSTORAGE + QList generatePossibleFileImports( + const QString &path, const QList &usedImports) const; +#endif private: RewriterView *m_rewriterView; bool m_isActive; diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index c22b84dd61e..264a515cd5c 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -207,14 +207,20 @@ void DesignModeWidget::setup() ADS::DockManager::setConfigFlag(ADS::DockManager::OpaqueSplitterResize, true); ADS::DockManager::setConfigFlag(ADS::DockManager::AllTabsHaveCloseButton, false); ADS::DockManager::setConfigFlag(ADS::DockManager::RetainTabSizeWhenCloseButtonHidden, true); - //ADS::DockManager::setAutoHideConfigFlags(ADS::DockManager::DefaultAutoHideConfig); + if (QmlDesignerBasePlugin::isLiteModeEnabled()) { + ADS::DockManager::setConfigFlag(ADS::DockManager::ActiveTabHasCloseButton, false); + ADS::DockManager::setConfigFlag(ADS::DockManager::MiddleMouseButtonClosesTab, false); + ADS::DockManager::setConfigFlag(ADS::DockManager::HideContextMenuDockWidgetTab, true); + } + auto designerSettings = DesignerSettings(settings); if (designerSettings.value(DesignerSettingsKey::ENABLE_DOCKWIDGET_CONTENT_MIN_SIZE).toBool()) m_minimumSizeHintMode = ADS::DockWidget::MinimumSizeHintFromContentMinimumSize; m_dockManager = new ADS::DockManager(this); + m_dockManager->setLiteMode(QmlDesignerBasePlugin::isLiteModeEnabled()); m_dockManager->setSettings(settings); m_dockManager->setWorkspacePresetsPath( Core::ICore::resourcePath("qmldesigner/workspacePresets/").toString()); @@ -279,35 +285,6 @@ void DesignModeWidget::setup() ADS::DockManager::iconProvider().registerCustomIcon(ADS::FloatingWidgetNormalIcon, floatingWidgetNormalIcon); - // Setup Actions and Menus - Core::ActionContainer *mview = Core::ActionManager::actionContainer(Core::Constants::M_VIEW); - // View > Views - Core::ActionContainer *mviews = Core::ActionManager::createMenu(Core::Constants::M_VIEW_VIEWS); - connect(mviews->menu(), &QMenu::aboutToShow, this, &DesignModeWidget::aboutToShowViews); - mviews->menu()->addSeparator(); - // View > Workspaces - Core::ActionContainer *mworkspaces = Core::ActionManager::createMenu(QmlDesigner::Constants::M_VIEW_WORKSPACES); - mview->addMenu(mworkspaces, Core::Constants::G_VIEW_VIEWS); - mworkspaces->menu()->setTitle(tr("&Workspaces")); - mworkspaces->setOnAllDisabledBehavior(Core::ActionContainer::Show); - // Connect opening of the 'workspaces' menu with creation of the workspaces menu - connect(mworkspaces->menu(), &QMenu::aboutToShow, this, &DesignModeWidget::aboutToShowWorkspaces); - - // Initially disable menus - mworkspaces->menu()->setEnabled(false); - - // Enable/disable menus when mode is different to MODE_DESIGN - connect(Core::ModeManager::instance(), - &Core::ModeManager::currentModeChanged, - this, - [mworkspaces](Utils::Id mode, Utils::Id) { - if (mode == Core::Constants::MODE_DESIGN) { - mworkspaces->menu()->setEnabled(true); - } else { - mworkspaces->menu()->setEnabled(false); - } - }); - // Create a DockWidget for each QWidget and add them to the DockManager const Core::Context designContext(Core::Constants::C_DESIGN_MODE); static const Utils::Id actionToggle("QmlDesigner.Toggle"); @@ -329,7 +306,7 @@ void DesignModeWidget::setup() continue; hideToolButtons(navigationView.dockToolBarWidgets); - navigationView.widget->setWindowTitle(tr(factory->id().name())); + navigationView.widget->setWindowTitle(factory->displayName()); QString idString = factory->id().toSetting().toString(); const QString title = idString; @@ -404,8 +381,40 @@ void DesignModeWidget::setup() return first->description() < second->description(); }); - for (Core::Command *command : viewCommands) - mviews->addAction(command); + if (!QmlDesignerBasePlugin::isLiteModeEnabled()) { + // Setup Actions and Menus + Core::ActionContainer *mview = Core::ActionManager::actionContainer(Core::Constants::M_VIEW); + // View > Views + Core::ActionContainer *mviews = Core::ActionManager::createMenu(Core::Constants::M_VIEW_VIEWS); + connect(mviews->menu(), &QMenu::aboutToShow, this, &DesignModeWidget::aboutToShowViews); + mviews->menu()->addSeparator(); + // View > Workspaces + Core::ActionContainer *mworkspaces = Core::ActionManager::createMenu( + QmlDesigner::Constants::M_VIEW_WORKSPACES); + mview->addMenu(mworkspaces, Core::Constants::G_VIEW_VIEWS); + mworkspaces->menu()->setTitle(tr("&Workspaces")); + mworkspaces->setOnAllDisabledBehavior(Core::ActionContainer::Show); + // Connect opening of the 'workspaces' menu with creation of the workspaces menu + connect(mworkspaces->menu(), &QMenu::aboutToShow, this, &DesignModeWidget::aboutToShowWorkspaces); + + // Initially disable menus + mworkspaces->menu()->setEnabled(false); + + // Enable/disable menus when mode is different to MODE_DESIGN + connect(Core::ModeManager::instance(), + &Core::ModeManager::currentModeChanged, + this, + [mworkspaces](Utils::Id mode, Utils::Id) { + if (mode == Core::Constants::MODE_DESIGN) { + mworkspaces->menu()->setEnabled(true); + } else { + mworkspaces->menu()->setEnabled(false); + } + }); + + for (Core::Command *command : viewCommands) + mviews->addAction(command); + } // Create toolbars if (!ToolBar::isVisible()) { diff --git a/src/plugins/qmldesigner/documentmanager.cpp b/src/plugins/qmldesigner/documentmanager.cpp index 92d80680a94..8530743d5fb 100644 --- a/src/plugins/qmldesigner/documentmanager.cpp +++ b/src/plugins/qmldesigner/documentmanager.cpp @@ -4,8 +4,9 @@ #include "documentmanager.h" #include "qmldesignerplugin.h" +#include #include -#include +#include #include #include #include @@ -40,12 +41,13 @@ namespace QmlDesigner { Q_LOGGING_CATEGORY(documentManagerLog, "qtc.qtquickdesigner.documentmanager", QtWarningMsg) -inline static QmlDesigner::DesignDocument *designDocument() +namespace { +QmlDesigner::DesignDocument *designDocument() { return QmlDesigner::QmlDesignerPlugin::instance()->documentManager().currentDesignDocument(); } -inline static QHash getProperties(const ModelNode &node) +QHash getProperties(const ModelNode &node) { QHash propertyHash; if (QmlObjectNode::isValidQmlObjectNode(node)) { @@ -54,7 +56,8 @@ inline static QHash getProperties(const ModelNode &node) if (abstractProperty.isVariantProperty() || (abstractProperty.isBindingProperty() && !abstractProperty.name().contains("anchors."))) - propertyHash.insert(abstractProperty.name(), QmlObjectNode(node).instanceValue(abstractProperty.name())); + propertyHash.insert(abstractProperty.name().toByteArray(), + QmlObjectNode(node).instanceValue(abstractProperty.name())); } if (QmlItemNode::isValidQmlItemNode(node)) { @@ -72,7 +75,7 @@ inline static QHash getProperties(const ModelNode &node) return propertyHash; } -inline static void applyProperties(ModelNode &node, const QHash &propertyHash) +void applyProperties(ModelNode &node, const QHash &propertyHash) { const auto auxiliaryData = node.auxiliaryData(AuxiliaryDataType::NodeInstancePropertyOverwrite); for (const auto &element : auxiliaryData) @@ -93,7 +96,7 @@ inline static void applyProperties(ModelNode &node, const QHashviewManager().nextFileIsCalledInternally(); Core::EditorManager::openEditor(FilePath::fromString(fileName), @@ -101,17 +104,17 @@ static void openFileComponentForFile(const QString &fileName) Core::EditorManager::DoNotMakeVisible); } -static void openFileComponent(const ModelNode &modelNode) +void openFileComponent(const ModelNode &modelNode) { openFileComponentForFile(ModelUtils::componentFilePath(modelNode)); } -static void openFileComponentForDelegate(const ModelNode &modelNode) +void openFileComponentForDelegate(const ModelNode &modelNode) { openFileComponent(modelNode.nodeProperty("delegate").modelNode()); } -static void openComponentSourcePropertyOfLoader(const ModelNode &modelNode) +void openComponentSourcePropertyOfLoader(const ModelNode &modelNode) { QmlDesignerPlugin::instance()->viewManager().nextFileIsCalledInternally(); @@ -135,7 +138,7 @@ static void openComponentSourcePropertyOfLoader(const ModelNode &modelNode) Core::EditorManager::DoNotMakeVisible); } -static void openSourcePropertyOfLoader(const ModelNode &modelNode) +void openSourcePropertyOfLoader(const ModelNode &modelNode) { QmlDesignerPlugin::instance()->viewManager().nextFileIsCalledInternally(); @@ -148,14 +151,13 @@ static void openSourcePropertyOfLoader(const ModelNode &modelNode) Core::EditorManager::DoNotMakeVisible); } - -static void handleComponent(const ModelNode &modelNode) +void handleComponent(const ModelNode &modelNode) { if (modelNode.nodeSourceType() == ModelNode::NodeWithComponentSource) designDocument()->changeToSubComponent(modelNode); } -static void handleDelegate(const ModelNode &modelNode) +void handleDelegate(const ModelNode &modelNode) { if (modelNode.metaInfo().isView() && modelNode.hasNodeProperty("delegate") @@ -163,7 +165,7 @@ static void handleDelegate(const ModelNode &modelNode) designDocument()->changeToSubComponent(modelNode.nodeProperty("delegate").modelNode()); } -static void handleTabComponent(const ModelNode &modelNode) +void handleTabComponent(const ModelNode &modelNode) { if (modelNode.hasNodeProperty("component") && modelNode.nodeProperty("component").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource) { @@ -171,7 +173,7 @@ static void handleTabComponent(const ModelNode &modelNode) } } -inline static void openInlineComponent(const ModelNode &modelNode) +void openInlineComponent(const ModelNode &modelNode) { if (!modelNode.metaInfo().isValid()) return; @@ -181,7 +183,7 @@ inline static void openInlineComponent(const ModelNode &modelNode) handleTabComponent(modelNode); } -static bool isFileComponent(const ModelNode &node) +bool isFileComponent(const ModelNode &node) { if (node.isValid() && node.metaInfo().isValid() @@ -191,7 +193,7 @@ static bool isFileComponent(const ModelNode &node) return false; } -static bool hasDelegateWithFileComponent(const ModelNode &node) +bool hasDelegateWithFileComponent(const ModelNode &node) { if (node.isValid() && node.metaInfo().isValid() @@ -203,7 +205,7 @@ static bool hasDelegateWithFileComponent(const ModelNode &node) return false; } -static bool isLoaderWithSourceComponent(const ModelNode &modelNode) +bool isLoaderWithSourceComponent(const ModelNode &modelNode) { if (modelNode.isValid() && modelNode.metaInfo().isQtQuickLoader()) { if (modelNode.hasNodeProperty("sourceComponent")) @@ -215,7 +217,7 @@ static bool isLoaderWithSourceComponent(const ModelNode &modelNode) return false; } -static bool hasSourceWithFileComponent(const ModelNode &modelNode) +bool hasSourceWithFileComponent(const ModelNode &modelNode) { if (modelNode.isValid() && modelNode.metaInfo().isQtQuickLoader() && modelNode.hasVariantProperty("source")) @@ -224,6 +226,8 @@ static bool hasSourceWithFileComponent(const ModelNode &modelNode) return false; } +} // namespace + void DocumentManager::setCurrentDesignDocument(Core::IEditor *editor) { if (editor) { @@ -295,7 +299,7 @@ bool DocumentManager::goIntoComponent(const ModelNode &modelNode) ModelNode rootModelNode = designDocument()->rewriterView()->rootModelNode(); applyProperties(rootModelNode, oldProperties); - rootModelNode.setAuxiliaryData(AuxiliaryDataType::Temporary, "contextImage", image); + rootModelNode.setAuxiliaryData(contextImageProperty, image); return true; } diff --git a/src/plugins/qmldesigner/documentmanager.h b/src/plugins/qmldesigner/documentmanager.h index 64476943391..59ec00b7979 100644 --- a/src/plugins/qmldesigner/documentmanager.h +++ b/src/plugins/qmldesigner/documentmanager.h @@ -5,7 +5,7 @@ #include "qmldesigner_global.h" -#include +#include #include #include diff --git a/src/plugins/qmldesigner/puppetenvironmentbuilder.cpp b/src/plugins/qmldesigner/puppetenvironmentbuilder.cpp index 7819c6b49d6..41f9fd80067 100644 --- a/src/plugins/qmldesigner/puppetenvironmentbuilder.cpp +++ b/src/plugins/qmldesigner/puppetenvironmentbuilder.cpp @@ -198,12 +198,11 @@ void PuppetEnvironmentBuilder::addForceQApplication() const void PuppetEnvironmentBuilder::addMultiLanguageDatatbase() const { - if (m_target) { - if (auto multiLanguageAspect = QmlProjectManager::QmlMultiLanguageAspect::current(m_target)) { - if (!multiLanguageAspect->databaseFilePath().isEmpty()) - m_environment.set("QT_MULTILANGUAGE_DATABASE", - multiLanguageAspect->databaseFilePath().toString()); - } + if (auto multiLanguageAspect = QmlProjectManager::QmlMultiLanguageAspect::current()) { + const auto databaseFilePath = multiLanguageAspect->databaseFilePath(); + if (!databaseFilePath.isEmpty() && databaseFilePath.exists()) + m_environment.set("QT_MULTILANGUAGE_DATABASE", + multiLanguageAspect->databaseFilePath().toString()); } } diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 28f3ed6097b..04b2320e838 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -79,6 +79,7 @@ inline constexpr char EDIT3D_CAMERA_SPEED_CONFIG[] = "QmlDesigner.Editor3D.Camer inline constexpr char QML_DESIGNER_SUBFOLDER[] = "/designer/"; inline constexpr char BUNDLE_JSON_FILENAME[] = "bundle.json"; +inline constexpr char BUNDLE_SUFFIX[] = "qdsbundle"; inline constexpr char COMPONENT_BUNDLES_TYPE[] = "Bundles"; inline constexpr char COMPONENT_BUNDLES_MATERIAL_BUNDLE_TYPE[] = "Materials"; inline constexpr char COMPONENT_BUNDLES_EFFECT_BUNDLE_TYPE[] = "Effects"; diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 573af01a57f..1845b0908ef 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -96,6 +96,19 @@ namespace QmlDesigner { namespace Internal { +class FullQDSFeatureProvider : public Core::IFeatureProvider +{ +public: + QSet availableFeatures(Utils::Id) const override + { + return {"QmlDesigner.Wizards.FullQDS"}; + } + + QSet availablePlatforms() const override { return {}; } + + QString displayNameForPlatform(Utils::Id) const override { return {}; } +}; + class EnterpriseFeatureProvider : public Core::IFeatureProvider { public: @@ -300,8 +313,6 @@ bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *e StudioQuickWidget::registerDeclarativeType(); QmlDesignerBase::WindowManager::registerDeclarativeType(); - if (checkEnterpriseLicense()) - Core::IWizardFactory::registerFeatureProvider(new EnterpriseFeatureProvider); Exception::setWarnAboutException(!QmlDesignerPlugin::instance() ->settings() .value(DesignerSettingsKey::ENABLE_MODEL_EXCEPTION_OUTPUT) @@ -343,6 +354,12 @@ void QmlDesignerPlugin::extensionsInitialized() registerCombinedTracedPoints(Constants::EVENT_STATE_ADDED, Constants::EVENT_STATE_CLONED, Constants::EVENT_STATE_ADDED_AND_CLONED); + + if (checkEnterpriseLicense()) + Core::IWizardFactory::registerFeatureProvider(new EnterpriseFeatureProvider); + + if (!QmlDesignerBasePlugin::isLiteModeEnabled()) + Core::IWizardFactory::registerFeatureProvider(new FullQDSFeatureProvider); } ExtensionSystem::IPlugin::ShutdownFlag QmlDesignerPlugin::aboutToShutdown() @@ -662,12 +679,11 @@ void QmlDesignerPlugin::enforceDelayedInitialize() FoundLicense license = checkLicense(); if (license == FoundLicense::enterprise) - Core::ICore::appendAboutInformation(tr("License: Enterprise")); + Core::ICore::setPrependAboutInformation("License: Enterprise"); else if (license == FoundLicense::professional) - Core::ICore::appendAboutInformation(tr("License: Professional")); - - if (!licensee().isEmpty()) - Core::ICore::appendAboutInformation(tr("Licensee: %1").arg(licensee())); + Core::ICore::setPrependAboutInformation("License: Professional"); + else if (license == FoundLicense::community) + Core::ICore::setPrependAboutInformation("License: Community"); } m_delayedInitialized = true; diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp index 730a557d120..f4d94af5234 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp @@ -586,15 +586,15 @@ void QmlDesignerProjectManager::update() return; if constexpr (isUsingQmlDesignerLite()) { - m_projectData->projectStorageData->updater.update(directoriesForLiteDesigner(), - qmlTypesForLiteDesigner(), - propertyEditorResourcesPath(), - {qtCreatorItemLibraryPath()}); + m_projectData->projectStorageData->updater.update({directoriesForLiteDesigner(), + qmlTypesForLiteDesigner(), + propertyEditorResourcesPath(), + {qtCreatorItemLibraryPath()}}); } else { - m_projectData->projectStorageData->updater.update(directories(m_projectData->activeTarget), - qmlTypes(m_projectData->activeTarget), - propertyEditorResourcesPath(), - {qtCreatorItemLibraryPath()}); + m_projectData->projectStorageData->updater.update({directories(m_projectData->activeTarget), + qmlTypes(m_projectData->activeTarget), + propertyEditorResourcesPath(), + {qtCreatorItemLibraryPath()}}); } } diff --git a/src/plugins/qmldesigner/utils/version.cpp b/src/plugins/qmldesigner/utils/version.cpp new file mode 100644 index 00000000000..ec18ce133d1 --- /dev/null +++ b/src/plugins/qmldesigner/utils/version.cpp @@ -0,0 +1,47 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#include "version.h" + +#include +#include + +namespace QmlDesigner { + +Version Version::fromString(QStringView string) +{ + Version result; + // Split version into parts (major, minor, patch) + QList versionParts = string.split('.'); + + auto readDigit = [](QStringView string, int defaultValue = 0) -> int { + bool canConvert = false; + int digit = string.toInt(&canConvert); + return (canConvert && digit > -1) ? digit : defaultValue; + }; + + if (versionParts.size() > 0) + result.major = readDigit(versionParts[0], std::numeric_limits::max()); + + if (versionParts.size() > 1) + result.minor = readDigit(versionParts[1]); + + if (versionParts.size() > 2) + result.patch = readDigit(versionParts[2]); + + return result; +} + +QString Version::toString() const +{ + if (isEmpty()) + return {}; + + return QString("%1.%2.%3").arg(major).arg(minor).arg(patch); +} + +QDebug operator<<(QDebug debug, Version version) +{ + return debug.noquote() << QStringView(u"Version(%1)").arg(version.toString()); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/utils/version.h b/src/plugins/qmldesigner/utils/version.h new file mode 100644 index 00000000000..a9082ee2a9e --- /dev/null +++ b/src/plugins/qmldesigner/utils/version.h @@ -0,0 +1,52 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "qmldesignerutils_global.h" + +#include +#include + +QT_BEGIN_NAMESPACE +class QDebug; +QT_END_NAMESPACE + +namespace QmlDesigner { + +class Version +{ +public: + static Version QMLDESIGNERUTILS_EXPORT fromString(QStringView string); + + QString QMLDESIGNERUTILS_EXPORT toString() const; + + bool isEmpty() const { return major == std::numeric_limits::max(); } + + friend bool operator==(Version first, Version second) + { + return std::tie(first.major, first.minor, first.patch) + == std::tie(second.major, second.minor, second.patch); + } + + friend bool operator<(Version first, Version second) + { + return std::tie(first.major, first.minor, first.patch) + < std::tie(second.major, second.minor, second.patch); + } + + friend bool operator>(Version first, Version second) { return second < first; } + + friend bool operator<=(Version first, Version second) { return !(second < first); } + + friend bool operator>=(Version first, Version second) { return !(first < second); } + + friend QMLDESIGNERUTILS_EXPORT QDebug operator<<(QDebug debug, Version version); + +public: + int major = std::numeric_limits::max(); + int minor = 0; + int patch = 0; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesignerbase/QmlDesignerBase.json.in b/src/plugins/qmldesignerbase/QmlDesignerBase.json.in index a02264b63f5..c41ed6bc7ba 100644 --- a/src/plugins/qmldesignerbase/QmlDesignerBase.json.in +++ b/src/plugins/qmldesignerbase/QmlDesignerBase.json.in @@ -15,5 +15,11 @@ "Category" : "Qt Quick", "Description" : "Provides support code for the qml designer and co..", "Url" : "https://www.qt.io", + "Arguments" : [ + { + "Name" : "-qml-lite-designer", + "Description" : "Enable QML Lite Designer" + } + ], ${IDE_PLUGIN_DEPENDENCIES} } diff --git a/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp b/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp index b71fb63bd89..e024de6761c 100644 --- a/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp +++ b/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp @@ -83,8 +83,11 @@ bool QmlDesignerBasePlugin::isLiteModeEnabled() return global->m_enableLiteMode; } -bool QmlDesignerBasePlugin::initialize(const QStringList &, QString *) +bool QmlDesignerBasePlugin::initialize(const QStringList &arguments, QString *) { + if (arguments.contains("-qml-lite-designer")) + enbableLiteMode(); + d = std::make_unique(); if (Core::ICore::settings()->value("QML/Designer/StandAloneMode", false).toBool()) d->studioConfigSettingsPage = std::make_unique(); diff --git a/src/plugins/qmldesignerbase/utils/designersettings.cpp b/src/plugins/qmldesignerbase/utils/designersettings.cpp index af5bd36fc56..d330d1905bd 100644 --- a/src/plugins/qmldesignerbase/utils/designersettings.cpp +++ b/src/plugins/qmldesignerbase/utils/designersettings.cpp @@ -94,7 +94,7 @@ void DesignerSettings::fromSettings(QtcSettings *settings) restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION_INTERVAL, 5.); restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE, true); restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE_INTERVAL, 10.); - restoreValue(settings, DesignerSettingsKey::SMOOTH_RENDERING, false); + restoreValue(settings, DesignerSettingsKey::SMOOTH_RENDERING, true); restoreValue(settings, DesignerSettingsKey::SHOW_DEBUG_SETTINGS, false); restoreValue(settings, DesignerSettingsKey::EDITOR_ZOOM_FACTOR, 1.0); restoreValue(settings, DesignerSettingsKey::ACTIONS_MERGE_TEMPLATE_ENABLED, false); diff --git a/src/plugins/qmlprojectmanager/CMakeLists.txt b/src/plugins/qmlprojectmanager/CMakeLists.txt index 68bb545011e..2cbf409e041 100644 --- a/src/plugins/qmlprojectmanager/CMakeLists.txt +++ b/src/plugins/qmlprojectmanager/CMakeLists.txt @@ -46,18 +46,21 @@ extend_qtc_plugin(QmlProjectManager cmakewriter.cpp cmakewriter.h cmakewriterv0.cpp cmakewriterv0.h cmakewriterv1.cpp cmakewriterv1.h + filetypes.cpp filetypes.h boilerplate.qrc ) add_qtc_library(QmlProjectManagerLib OBJECT + CONDITION WITH_TESTS AND Qt6_VERSION VERSION_GREATER_EQUAL 6.4.3 EXCLUDE_FROM_INSTALL + DEFINES QMLPROJECTMANAGER_STATIC_LIBRARY DEPENDS QmlJS Utils ProjectExplorer INCLUDES ${CMAKE_CURRENT_LIST_DIR} - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/buildsystem SOURCES - projectitem/filefilteritems.cpp projectitem/filefilteritems.h - projectitem/qmlprojectitem.cpp projectitem/qmlprojectitem.h - projectitem/converters.cpp projectitem/converters.h + buildsystem/projectitem/filefilteritems.cpp buildsystem/projectitem/filefilteritems.h + buildsystem/projectitem/qmlprojectitem.cpp buildsystem/projectitem/qmlprojectitem.h + buildsystem/projectitem/converters.cpp buildsystem/projectitem/converters.h + cmakegen/filetypes.cpp cmakegen/filetypes.h ) diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp b/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp index 82ba1fc2e41..e98a8446091 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp @@ -2,6 +2,8 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "converters.h" +#include "utils/algorithm.h" +#include "cmakegen/filetypes.h" #include @@ -9,17 +11,10 @@ namespace QmlProjectManager::Converters { const static QStringList qmlFilesFilter{QStringLiteral("*.qml")}; const static QStringList javaScriptFilesFilter{QStringLiteral("*.js"), QStringLiteral("*.ts")}; -const static QStringList imageFilesFilter{QStringLiteral("*.jpeg"), - QStringLiteral("*.jpg"), - QStringLiteral("*.png"), - QStringLiteral("*.svg"), - QStringLiteral("*.hdr"), - QStringLiteral("*.ktx"), - QStringLiteral("*.bmp"), - QStringLiteral("*.ttf"), - QStringLiteral("*.tiff"), - QStringLiteral("*.webp"), - QStringLiteral("*.gif")}; + +const QStringList imageFilesFilter() { + return imageFiles([](const QString& suffix) { return "*." + suffix; }); +} QString jsonValueToString(const QJsonValue &val, int indentationLevel, bool indented); @@ -122,7 +117,7 @@ QString jsonToQmlProject(const QJsonObject &rootObject) if (nodeName.toLower() == "qmlfiles") { filter = qmlFilesFilter; } else if (nodeName.toLower() == "imagefiles") { - filter = imageFilesFilter; + filter = imageFilesFilter(); } else if (nodeName.toLower() == "javascriptfiles") { filter = javaScriptFilesFilter; } @@ -224,6 +219,103 @@ QString jsonToQmlProject(const QJsonObject &rootObject) return qmlProjectString; } +QStringList qmlprojectsFromFilesNodes(const QJsonArray &fileGroups, + const Utils::FilePath &projectRootPath) +{ + QStringList qmlProjectFiles; + for (const QJsonValue &fileGroup : fileGroups) { + if (fileGroup["type"].toString() != "Module") { + continue; + } + // In Qul, paths are relative to the project root directory, not the "directory" entry + qmlProjectFiles.append(fileGroup["files"].toVariant().toStringList()); + + // If the "directory" property is set, all qmlproject files in the directory are also added + // as relative paths from the project root directory, in addition to explicitly added files + const QString directoryProp = fileGroup["directory"].toString(""); + if (directoryProp.isEmpty()) { + continue; + } + const Utils::FilePath dir = projectRootPath / directoryProp; + qmlProjectFiles.append(Utils::transform( + dir.dirEntries(Utils::FileFilter({"*.qmlproject"}, QDir::Files)), + [&projectRootPath](Utils::FilePath file) { + return file.absoluteFilePath().relativePathFrom(projectRootPath).toFSPathString(); + })); + } + + return qmlProjectFiles; +} + +QString moduleUriFromQmlProject(const QString &qmlProjectFilePath) +{ + QmlJS::SimpleReader simpleReader; + const auto rootNode = simpleReader.readFile(qmlProjectFilePath); + // Since the file wasn't explicitly added, skip qmlproject files with errors + if (!rootNode || !simpleReader.errors().isEmpty()) { + return QString(); + } + + for (const auto &child : rootNode->children()) { + if (child->name() == "MCU.Module") { + const auto prop = child->property("uri").isValid() ? child->property("uri") + : child->property("MCU.uri"); + if (prop.isValid()) { + return prop.value.toString(); + } + break; + } + } + + return QString(); +} + +// Returns a list of qmlproject files in currentSearchPath which are valid modules, +// with URIs matching the relative path from importPathBase. +QStringList getModuleQmlProjectFiles(const Utils::FilePath &importPath, + const Utils::FilePath &projectRootPath) +{ + QStringList qmlProjectFiles; + + QDirIterator it(importPath.toFSPathString(), + QDir::NoDotAndDotDot | QDir::Files, + QDirIterator::Subdirectories); + while (it.hasNext()) { + const QString file = it.next(); + if (!file.endsWith(".qmlproject")) { + continue; + } + + // Add if matching + QString uri = moduleUriFromQmlProject(file); + if (uri.isEmpty()) { + // If the qmlproject file is not a valid module, skip it + continue; + } + + const auto filePath = Utils::FilePath::fromUserInput(file); + const bool isBaseImportPath = filePath.parentDir() == importPath; + + // Check the URI against the original import path before adding + // If we look directly in the search path, the URI doesn't matter + const QString relativePath = filePath.parentDir().relativePathFrom(importPath).path(); + if (isBaseImportPath || uri.replace(".", "/") == relativePath) { + // If the URI matches the path or the file is directly in the import path, add it + qmlProjectFiles.emplace_back(filePath.relativePathFrom(projectRootPath).toFSPathString()); + } + } + return qmlProjectFiles; +} + +QStringList qmlprojectsFromImportPaths(const QStringList &importPaths, + const Utils::FilePath &projectRootPath) +{ + return Utils::transform(importPaths, [&projectRootPath](const QString &importPath) { + const auto importDir = projectRootPath / importPath; + return getModuleQmlProjectFiles(importDir, projectRootPath); + }); +} + QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile) { QmlJS::SimpleReader simpleQmlJSReader; @@ -265,6 +357,9 @@ QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile) bool qtForMCUs = false; + QStringList importPaths; + Utils::FilePath projectRootPath = projectFile.parentDir(); + // convert the non-object props for (const QString &propName : rootNode->propertyNames()) { QJsonObject *currentObj = &rootObject; @@ -300,6 +395,7 @@ QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile) value = rootNode->property(propName).value.toBool() ? "6" : "5"; } else if (propName.contains("importpaths", Qt::CaseInsensitive)) { objKey = "importPaths"; + importPaths = value.toVariant().toStringList(); } else { currentObj = &otherProperties; objKey = propName; // With prefix @@ -357,7 +453,7 @@ QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile) } else if (childNodeName == "javascriptfiles") { inserter(javaScriptFilesFilter); } else if (childNodeName == "imagefiles") { - inserter(imageFilesFilter); + inserter(imageFilesFilter()); } } @@ -413,6 +509,12 @@ QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile) } } + QStringList qmlProjectDependencies; + qmlProjectDependencies.append(qmlprojectsFromImportPaths(importPaths, projectRootPath)); + qmlProjectDependencies.append(qmlprojectsFromFilesNodes(fileGroupsObject, projectRootPath)); + qmlProjectDependencies.sort(); + rootObject.insert("qmlprojectDependencies", QJsonArray::fromStringList(qmlProjectDependencies)); + mcuObject.insert("config", mcuConfigObject); mcuObject.insert("module", mcuModuleObject); qtForMCUs |= !(mcuModuleObject.isEmpty() && mcuConfigObject.isEmpty()); diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp index 5229d486ce3..067ada48f03 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp @@ -209,6 +209,11 @@ void QmlProjectItem::addImportPath(const QString &importPath) insertAndUpdateProjectFile("importPaths", importPaths); } +QStringList QmlProjectItem::qmlProjectModules() const +{ + return m_project["qmlprojectDependencies"].toVariant().toStringList(); +} + QStringList QmlProjectItem::fileSelectors() const { return m_project["runConfig"].toObject()["fileSelectors"].toVariant().toStringList(); diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.h b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.h index 5d0b520f144..bcbc3ddadc5 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.h +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.h @@ -46,6 +46,8 @@ public: void setImportPaths(const QStringList &paths); void addImportPath(const QString &importPath); + QStringList qmlProjectModules() const; + QStringList fileSelectors() const; void setFileSelectors(const QStringList &selectors); void addFileSelector(const QString &selector); diff --git a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp index f3a6d8fed3e..0d188bebd60 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp @@ -236,38 +236,28 @@ void QmlBuildSystem::initMcuProjectItems() m_mcuProjectItems.clear(); m_mcuProjectFilesWatcher.clear(); - Utils::FilePath projectDir = projectFilePath().parentDir(); - // traverse the project dir and find all other mcu projects (.qmlproject files) in the project tree - // and add them to the m_mcuProjectItems vector - QDirIterator it(projectDir.toFSPathString(), QDir::Files, QDirIterator::Subdirectories); - while (it.hasNext()) { - it.next(); - if (it.fileInfo().suffix() == "qmlproject" && it.filePath() != projectFilePath().toString()) { - auto qmlProjectItem = QSharedPointer( - new QmlProjectItem{Utils::FilePath::fromString(it.filePath())}); + const QStringList mcuProjectFiles = m_projectItem->qmlProjectModules(); + for (const QString &mcuProjectFile : mcuProjectFiles) { + auto qmlProjectItem = QSharedPointer( + new QmlProjectItem{Utils::FilePath::fromString(mcuProjectFile)}); - m_mcuProjectItems.append(qmlProjectItem); - connect(qmlProjectItem.data(), - &QmlProjectItem::filesChanged, - this, - &QmlBuildSystem::refreshFiles); - connect(qmlProjectItem.data(), - &QmlProjectItem::filesChanged, - m_cmakeGen, - &GenerateCmake::CMakeGenerator::update); + m_mcuProjectItems.append(qmlProjectItem); + connect(qmlProjectItem.data(), &QmlProjectItem::filesChanged, this, &QmlBuildSystem::refreshFiles); + connect(qmlProjectItem.data(), + &QmlProjectItem::filesChanged, + m_cmakeGen, + &GenerateCmake::CMakeGenerator::update); - m_mcuProjectFilesWatcher.addFile(it.filePath(), - Utils::FileSystemWatcher::WatchModifiedDate); + m_mcuProjectFilesWatcher.addFile(mcuProjectFile, Utils::FileSystemWatcher::WatchModifiedDate); - connect(&m_mcuProjectFilesWatcher, - &Utils::FileSystemWatcher::fileChanged, - this, - [this](const QString &file) { - Q_UNUSED(file) - initMcuProjectItems(); - refresh(RefreshOptions::Files); - }); - } + connect(&m_mcuProjectFilesWatcher, + &Utils::FileSystemWatcher::fileChanged, + this, + [this](const QString &file) { + Q_UNUSED(file) + initMcuProjectItems(); + refresh(RefreshOptions::Files); + }); } } diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.cpp b/src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.cpp index 9ae576ec35a..4f81763f39b 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.cpp +++ b/src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "cmakegenerator.h" +#include "filetypes.h" #include "qmlprojectmanager/qmlproject.h" #include "qmlprojectmanager/qmlprojectconstants.h" @@ -197,21 +198,6 @@ void CMakeGenerator::update(const QSet &added, const QSet &rem createSourceFiles(); } -bool CMakeGenerator::isQml(const Utils::FilePath &path) const -{ - const QString suffix = path.suffix(); - return suffix == "qml" || suffix == "ui.qml"; -} - -bool CMakeGenerator::isResource(const Utils::FilePath &path) const -{ - static const QStringList suffixes = { - "json", "mesh", "dae", "qad", "hints", "png", "hdr", "ttf", "jpg", - "jpeg", "js", "qsb", "frag", "frag.qsb", "vert", "vert.qsb", "svg", - "ktx", "bmp", "gif", "webp", "tiff"}; - return suffixes.contains(path.suffix(), Qt::CaseInsensitive); -} - bool CMakeGenerator::ignore(const Utils::FilePath &path) const { if (path.isFile()) { @@ -236,6 +222,32 @@ bool CMakeGenerator::ignore(const Utils::FilePath &path) const return false; } +bool CMakeGenerator::checkUri(const QString& uri, const Utils::FilePath &path) const +{ + QTC_ASSERT(buildSystem(), return false); + + Utils::FilePath relative = path.relativeChildPath(m_root->dir); + QList pathComponents = relative.pathView().split('/', Qt::SkipEmptyParts); + + for (const auto& import : buildSystem()->importPaths()) { + Utils::FilePath importPath = Utils::FilePath::fromUserInput(import); + for (const auto& component : importPath.pathView().split('/', Qt::SkipEmptyParts)) { + if (component == pathComponents.first()) + pathComponents.pop_front(); + } + } + + const QStringList uriComponents = uri.split('.', Qt::SkipEmptyParts); + if (pathComponents.size() == uriComponents.size()) { + for (qsizetype i=0; iuri, node->dir)) { + QString text("Unexpected uri %1"); + logIssue(ProjectExplorer::Task::Warning, text.arg(node->uri), node->dir); + } } NodePtr CMakeGenerator::findModuleFor(const NodePtr &node) const @@ -365,9 +382,9 @@ bool findFileWithGetter(const Utils::FilePath &file, const NodePtr &node, const bool CMakeGenerator::findFile(const NodePtr &node, const Utils::FilePath &file) const { - if (isResource(file)) { - return findFileWithGetter(file, node, [](const NodePtr &n) { return n->resources; }); - } else if (isQml(file)) { + if (isAssetFile(file)) { + return findFileWithGetter(file, node, [](const NodePtr &n) { return n->assets; }); + } else if (isQmlFile(file)) { if (findFileWithGetter(file, node, [](const NodePtr &n) { return n->files; })) return true; else if (findFileWithGetter(file, node, [](const NodePtr &n) { return n->singletons; })) @@ -386,10 +403,10 @@ void CMakeGenerator::insertFile(NodePtr &node, const Utils::FilePath &path) cons readQmlDir(path, node); } else if (path.suffix() == "cpp") { node->sources.push_back(path); - } else if (isQml(path)) { + } else if (isQmlFile(path)) { node->files.push_back(path); - } else if (isResource(path)) { - node->resources.push_back(path); + } else if (isAssetFile(path)) { + node->assets.push_back(path); } } @@ -400,15 +417,14 @@ void CMakeGenerator::removeFile(NodePtr &node, const Utils::FilePath &path) cons node->singletons.clear(); node->uri = ""; node->name = path.parentDir().fileName(); - - } else if (isQml(path)) { + } else if (isQmlFile(path)) { auto iter = std::find(node->files.begin(), node->files.end(), path); if (iter != node->files.end()) node->files.erase(iter); - } else if (isResource(path)) { - auto iter = std::find(node->resources.begin(), node->resources.end(), path); - if (iter != node->resources.end()) - node->resources.erase(iter); + } else if (isAssetFile(path)) { + auto iter = std::find(node->assets.begin(), node->assets.end(), path); + if (iter != node->assets.end()) + node->assets.erase(iter); } } @@ -454,7 +470,7 @@ void CMakeGenerator::printNodeTree(const NodePtr &generatorNode, size_t indent) qDebug() << addIndent(indent) << "directory: " << generatorNode->dir; qDebug() << addIndent(indent) << "files: " << generatorNode->files; qDebug() << addIndent(indent) << "singletons: " << generatorNode->singletons; - qDebug() << addIndent(indent) << "resources: " << generatorNode->resources; + qDebug() << addIndent(indent) << "assets: " << generatorNode->assets; qDebug() << addIndent(indent) << "sources: " << generatorNode->sources; for (const auto &child : generatorNode->subdirs) @@ -526,7 +542,7 @@ void CMakeGenerator::compareWithFileSystem(const NodePtr &node) const if (ignore(next.parentDir())) continue; - if (isResource(next) && !findFile(next) && !ignore(next)) + if (isAssetFile(next) && !findFile(next) && !ignore(next)) files.push_back(next); } diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.h b/src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.h index 3af3405879f..e552f154203 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.h +++ b/src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.h @@ -45,9 +45,8 @@ public: void updateMenuAction(); private: - bool isQml(const Utils::FilePath &path) const; - bool isResource(const Utils::FilePath &path) const; bool ignore(const Utils::FilePath &path) const; + bool checkUri(const QString& uri, const Utils::FilePath &path) const; void createCMakeFiles(const NodePtr &node) const; void createSourceFiles() const; diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakewriter.cpp b/src/plugins/qmlprojectmanager/cmakegen/cmakewriter.cpp index 0b1d0c4c60e..81701cd4bc0 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakewriter.cpp +++ b/src/plugins/qmlprojectmanager/cmakegen/cmakewriter.cpp @@ -98,9 +98,9 @@ std::vector CMakeWriter::singletons(const NodePtr &node) const return files(node, [](const NodePtr &n) { return n->singletons; }); } -std::vector CMakeWriter::resources(const NodePtr &node) const +std::vector CMakeWriter::assets(const NodePtr &node) const { - return files(node, [](const NodePtr &n) { return n->resources; }); + return files(node, [](const NodePtr &n) { return n->assets; }); } std::vector CMakeWriter::sources(const NodePtr &node) const @@ -133,6 +133,31 @@ QString CMakeWriter::getEnvironmentVariable(const QString &key) const return value; } +QString CMakeWriter::makeFindPackageBlock(const QmlBuildSystem* buildSystem) const +{ + QString head = "find_package(Qt" + buildSystem->versionQt(); + const QString tail = " REQUIRED COMPONENTS Core Gui Qml Quick)\n"; + + const QStringList versions = buildSystem->versionQtQuick().split('.', Qt::SkipEmptyParts); + if (versions.size() < 2) + return head + tail; + + bool majorOk = false; + bool minorOk = false; + int major = versions[0].toInt(&majorOk); + int minor = versions[1].toInt(&minorOk); + if (!majorOk || !minorOk) + return head + tail; + + const QString from = versions[0] + "." + versions[1]; + QString out = head + " " + from + tail; + + if (major >= 6 && minor >= 3) + out += "qt_standard_project_setup()\n"; + + return out; +} + QString CMakeWriter::makeRelative(const NodePtr &node, const Utils::FilePath &path) const { const QString dir = node->dir.toString(); @@ -204,7 +229,7 @@ std::tuple CMakeWriter::makeResourcesBlocks(const NodePtr &nod QString resourceFiles; std::vector bigResources; - for (const Utils::FilePath &path : resources(node)) { + for (const Utils::FilePath &path : assets(node)) { if (path.fileSize() > 5000000) { bigResources.push_back(makeRelative(node, path)); continue; diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakewriter.h b/src/plugins/qmlprojectmanager/cmakegen/cmakewriter.h index 8766df0dcda..14eb512f9c4 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakewriter.h +++ b/src/plugins/qmlprojectmanager/cmakegen/cmakewriter.h @@ -32,7 +32,7 @@ struct Node std::vector> subdirs; std::vector files; std::vector singletons; - std::vector resources; + std::vector assets; std::vector sources; }; @@ -76,12 +76,13 @@ protected: std::vector files(const NodePtr &node, const FileGetter &getter) const; std::vector qmlFiles(const NodePtr &node) const; std::vector singletons(const NodePtr &node) const; - std::vector resources(const NodePtr &node) const; + std::vector assets(const NodePtr &node) const; std::vector sources(const NodePtr &node) const; std::vector plugins(const NodePtr &node) const; QString getEnvironmentVariable(const QString &key) const; + QString makeFindPackageBlock(const QmlBuildSystem* buildSystem) const; QString makeRelative(const NodePtr &node, const Utils::FilePath &path) const; QString makeQmlFilesBlock(const NodePtr &node) const; QString makeSingletonBlock(const NodePtr &node) const; diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv0.cpp b/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv0.cpp index 5cb17d1e1bf..b6861a4493d 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv0.cpp +++ b/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv0.cpp @@ -21,7 +21,7 @@ CMakeWriterV0::CMakeWriterV0(CMakeGenerator *parent) bool CMakeWriterV0::isPlugin(const NodePtr &node) const { if (node->type == Node::Type::App) - return !node->files.empty() || !node->singletons.empty() || !node->resources.empty(); + return !node->files.empty() || !node->singletons.empty() || !node->assets.empty(); return CMakeWriter::isPlugin(node); } diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv1.cpp b/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv1.cpp index 6d2d93a76b9..0ff2f23da4e 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv1.cpp +++ b/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv1.cpp @@ -40,6 +40,7 @@ void CMakeWriterV1::transformNode(NodePtr &node) const void CMakeWriterV1::writeRootCMakeFile(const NodePtr &node) const { QTC_ASSERT(parent(), return); + QTC_ASSERT(parent()->buildSystem(), return); const Utils::FilePath cmakeFolderPath = node->dir.pathAppended("cmake"); if (!cmakeFolderPath.exists()) @@ -66,6 +67,7 @@ void CMakeWriterV1::writeRootCMakeFile(const NodePtr &node) const const Utils::FilePath file = node->dir.pathAppended("CMakeLists.txt"); if (!file.exists()) { const QString appName = parent()->projectName() + "App"; + const QString findPackage = makeFindPackageBlock(parent()->buildSystem()); QString fileSection = ""; const QString configFile = getEnvironmentVariable(ENV_VARIABLE_CONTROLCONF); @@ -73,7 +75,7 @@ void CMakeWriterV1::writeRootCMakeFile(const NodePtr &node) const fileSection = QString("\t\t%1").arg(configFile); const QString fileTemplate = readTemplate(":/templates/cmakeroot_v1"); - const QString fileContent = fileTemplate.arg(appName, fileSection); + const QString fileContent = fileTemplate.arg(appName, findPackage, fileSection); writeFile(file, fileContent); } } diff --git a/src/plugins/qmlprojectmanager/cmakegen/filetypes.cpp b/src/plugins/qmlprojectmanager/cmakegen/filetypes.cpp new file mode 100644 index 00000000000..a6ee4cd15f6 --- /dev/null +++ b/src/plugins/qmlprojectmanager/cmakegen/filetypes.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "filetypes.h" + +namespace QmlProjectManager { + +QStringList imageFiles(const std::function &transformer) +{ + static const QStringList suffixes = { + "bmp", "dae", "gif", "hdr", "ico", + "jpeg", "jpg", "ktx", "pbm", "pgm", + "png", "ppm", "svg", "svgz", "tif", + "tiff", "ttf", "webp", "xbm", "xpm" + }; + + if (transformer) { + QStringList result; + for (const QString& suffix : suffixes) + result << transformer(suffix); + return result; + } + return suffixes; +} + +bool isQmlFile(const Utils::FilePath &path) +{ + const QString suffix = path.suffix(); + return suffix == "qml" || suffix == "ui.qml"; +} + +bool isAssetFile(const Utils::FilePath &path) +{ + static const QStringList suffixes = { + "js", "ts", "json", "hints", "mesh", "qad", "qsb", "frag", + "frag.qsb", "vert", "vert.qsb", "mng" + }; + return + suffixes.contains(path.suffix(), Qt::CaseInsensitive) || + imageFiles().contains(path.suffix(), Qt::CaseInsensitive); +} + +bool isResource(const Utils::FilePath &path) +{ + auto isOtherFile = [](const Utils::FilePath &p) -> bool { + static QStringList suffixes = { "qmlproject", "conf" }; + return p.fileName() == "qmldir" || suffixes.contains(p.suffix()); + }; + return isQmlFile(path) || isAssetFile(path) || isOtherFile(path); +} + +} // namespace QmlProjectManager. diff --git a/src/plugins/qmlprojectmanager/cmakegen/filetypes.h b/src/plugins/qmlprojectmanager/cmakegen/filetypes.h new file mode 100644 index 00000000000..efe07df118c --- /dev/null +++ b/src/plugins/qmlprojectmanager/cmakegen/filetypes.h @@ -0,0 +1,17 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include + +#include + +namespace QmlProjectManager { + +QMLPROJECTMANAGER_EXPORT QStringList imageFiles( + const std::function &transformer = nullptr); + +QMLPROJECTMANAGER_EXPORT bool isQmlFile(const Utils::FilePath &path); +QMLPROJECTMANAGER_EXPORT bool isAssetFile(const Utils::FilePath &path); +QMLPROJECTMANAGER_EXPORT bool isResource(const Utils::FilePath &path); + +} // namespace QmlProjectManager. diff --git a/src/plugins/qmlprojectmanager/cmakegen/templates/cmakeroot_v1.tpl b/src/plugins/qmlprojectmanager/cmakegen/templates/cmakeroot_v1.tpl index a5d5e2bd023..d0583efdf87 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/templates/cmakeroot_v1.tpl +++ b/src/plugins/qmlprojectmanager/cmakegen/templates/cmakeroot_v1.tpl @@ -16,17 +16,13 @@ set(QML_IMPORT_PATH ${QT_QML_OUTPUT_DIRECTORY} FORCE ) -find_package(Qt6 6.2 REQUIRED COMPONENTS Core Gui Qml Quick) - -if (Qt6_VERSION VERSION_GREATER_EQUAL 6.3) - qt_standard_project_setup() -endif() +%2 qt_add_executable(${CMAKE_PROJECT_NAME}) qt_add_resources(${CMAKE_PROJECT_NAME} "configuration" PREFIX "/" FILES -%2) +%3) include(qds) diff --git a/src/plugins/qmlprojectmanager/cmakegen/templates/qmlcomponents.tpl b/src/plugins/qmlprojectmanager/cmakegen/templates/qmlcomponents.tpl index 5640b85844c..0308c2ab745 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/templates/qmlcomponents.tpl +++ b/src/plugins/qmlprojectmanager/cmakegen/templates/qmlcomponents.tpl @@ -32,5 +32,5 @@ target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE add_subdirectory(${ds_SOURCE_DIR} ${ds_BINARY_DIR}) target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE - BULD_QDS_COMPONENTS=true + BUILD_QDS_COMPONENTS=true ) diff --git a/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.cpp b/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.cpp index e6028e1d7d5..7b63452c11c 100644 --- a/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.cpp +++ b/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.cpp @@ -29,23 +29,13 @@ static bool isMultilanguagePresent() != specs.cend(); } -static FilePath getMultilanguageDatabaseFilePath(ProjectExplorer::Target *target) -{ - if (target) { - auto filePath = target->project()->projectDirectory().pathAppended("translations.db"); - if (filePath.exists()) - return filePath; - } - return {}; -} - -static QObject *getPreviewPlugin() +static QObject *getPlugin(const QString &pluginName) { const ExtensionSystem::PluginSpecs &specs = ExtensionSystem::PluginManager::plugins(); - const auto pluginIt = std::find_if(specs.cbegin(), specs.cend(), - [](const ExtensionSystem::PluginSpec *p) { - return p->name() == "QmlPreview"; - }); + const auto pluginIt = std::find_if( + specs.cbegin(), specs.cend(), [pluginName](const ExtensionSystem::PluginSpec *p) { + return p->name() == pluginName; + }); if (pluginIt != specs.cend()) return (*pluginIt)->plugin(); @@ -91,7 +81,7 @@ void QmlMultiLanguageAspect::setCurrentLocale(const QString &locale) if (m_currentLocale == locale) return; m_currentLocale = locale; - if (auto previewPlugin = getPreviewPlugin()) + if (auto previewPlugin = getPlugin("QmlPreview")) previewPlugin->setProperty("localeIsoCode", locale); } @@ -102,9 +92,11 @@ QString QmlMultiLanguageAspect::currentLocale() const Utils::FilePath QmlMultiLanguageAspect::databaseFilePath() const { - if (m_databaseFilePath.isEmpty()) - m_databaseFilePath = getMultilanguageDatabaseFilePath(m_target); - return m_databaseFilePath; + if (auto previewPlugin = getPlugin("MultiLanguage")) { + const auto multilanguageDatabaseFilePath = previewPlugin->property("multilanguageDatabaseFilePath"); + return Utils::FilePath::fromString(multilanguageDatabaseFilePath.toString()); + } + return {}; } void QmlMultiLanguageAspect::toMap(Store &map) const diff --git a/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.h b/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.h index 8fcb0f9f879..45da11efff3 100644 --- a/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.h +++ b/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.h @@ -42,7 +42,6 @@ private: const void *origin() const { return this; } ProjectExplorer::Target *m_target = nullptr; - mutable Utils::FilePath m_databaseFilePath; QString m_currentLocale; }; diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs b/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs index 0fa49b5102a..b723fe4a4c1 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs +++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs @@ -51,6 +51,7 @@ QtcPlugin { "cmakewriter.cpp", "cmakewriter.h", "cmakewriterv0.cpp", "cmakewriterv0.h", "cmakewriterv1.cpp", "cmakewriterv1.h" + "filetypes.cpp", "filetypes.h" ] } diff --git a/src/plugins/studiowelcome/qdsnewdialog.cpp b/src/plugins/studiowelcome/qdsnewdialog.cpp index 54dec46f74f..1fa82e55034 100644 --- a/src/plugins/studiowelcome/qdsnewdialog.cpp +++ b/src/plugins/studiowelcome/qdsnewdialog.cpp @@ -414,7 +414,6 @@ void QdsNewDialog::reject() m_wizard.destroyWizard(); m_dialog->close(); - m_dialog.reset(); } QString QdsNewDialog::chooseProjectLocation() diff --git a/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml b/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml index 9cbf1e542ff..005c367cd9e 100644 --- a/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml +++ b/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml @@ -6,6 +6,7 @@ import QtQuick.Layouts 1.15 import StudioFonts 1.0 import projectmodel 1.0 import usagestatistics 1.0 +import studiousagestatistics 1.0 import QtQuick.Shapes 1.0 Rectangle { @@ -159,6 +160,10 @@ Rectangle { UsageStatisticModel { id: usageStatisticModel } + + StudioUsageStatisticModel { + id: studioUsageStatisticModel + } } //DOF seems to do nothing, we should probably just remove it. @@ -202,6 +207,7 @@ Rectangle { text: qsTr("Turn Off") fontpixelSize: 14 onClicked: { + studioUsageStatisticModel.setInsightEnabled(false) usageStatisticModel.setTelemetryEnabled(false) usageStatisticModel.setCrashReporterEnabled(false) welcome_splash.closeClicked() @@ -213,6 +219,7 @@ Rectangle { forceHover: false fontpixelSize: 14 onClicked: { + studioUsageStatisticModel.setInsightEnabled(true) usageStatisticModel.setTelemetryEnabled(true) usageStatisticModel.setCrashReporterEnabled(true) welcome_splash.closeClicked() diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp index 268b15110e0..cb348af0f6a 100644 --- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp +++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp @@ -29,6 +29,8 @@ #include #include +#include + #include #include #include @@ -70,6 +72,7 @@ using namespace Core; using namespace ProjectExplorer; using namespace Utils; +using namespace Core; namespace StudioWelcome { namespace Internal { @@ -202,6 +205,27 @@ private: QString m_versionString; }; +class StudioUsageStatisticPluginModel : public QObject +{ + Q_OBJECT +public: + explicit StudioUsageStatisticPluginModel(QObject *parent = nullptr) + : QObject(parent) + { + } + + Q_INVOKABLE void setInsightEnabled(bool b) + { + bool currentTrackingStatus = Core::ICore::settings()->value("InsightTracking", false).toBool(); + + if (currentTrackingStatus == b) + return; + + Core::ICore::settings()->setValue("InsightTracking", b); + Core::ICore::askForRestart(tr("The change will take effect after restart.")); + } +}; + class ProjectModel : public QAbstractListModel { Q_OBJECT @@ -210,6 +234,7 @@ public: Q_PROPERTY(bool communityVersion MEMBER m_communityVersion NOTIFY communityVersionChanged) Q_PROPERTY(bool enterpriseVersion MEMBER m_enterpriseVersion NOTIFY enterpriseVersionChanged) + Q_PROPERTY(bool liteDesignerEnabled MEMBER m_liteDesignerEnabled CONSTANT) Q_PROPERTY(int count READ count NOTIFY countChanged) explicit ProjectModel(QObject *parent = nullptr); @@ -378,6 +403,7 @@ private: bool m_communityVersion = true; bool m_enterpriseVersion = false; bool m_blockOpenRecent = false; + bool m_liteDesignerEnabled = false; }; void ProjectModel::setupVersion() @@ -385,6 +411,7 @@ void ProjectModel::setupVersion() QmlDesigner::FoundLicense license = QmlDesigner::checkLicense(); m_communityVersion = license == QmlDesigner::FoundLicense::community; m_enterpriseVersion = license == QmlDesigner::FoundLicense::enterprise; + m_liteDesignerEnabled = QmlDesigner::QmlDesignerBasePlugin::isLiteModeEnabled(); } ProjectModel::ProjectModel(QObject *parent) @@ -574,6 +601,7 @@ void StudioWelcomePlugin::initialize() { qmlRegisterType("projectmodel", 1, 0, "ProjectModel"); qmlRegisterType("usagestatistics", 1, 0, "UsageStatisticModel"); + qmlRegisterType("studiousagestatistics", 1, 0, "StudioUsageStatisticModel"); m_welcomeMode = new WelcomeMode; } diff --git a/src/plugins/studiowelcome/wizardfactories.cpp b/src/plugins/studiowelcome/wizardfactories.cpp index f114466b8da..0b285d1c493 100644 --- a/src/plugins/studiowelcome/wizardfactories.cpp +++ b/src/plugins/studiowelcome/wizardfactories.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include #include @@ -47,7 +49,7 @@ void WizardFactories::sortByCategoryAndId() void WizardFactories::filter() { QList acceptedFactories = Utils::filtered(m_factories, [&](auto *wizard) { - return wizard->isAvailable(m_platform) + return wizard->isAvailable(m_platform) && !wizard->detailsPageQmlPath().isEmpty() && wizard->kind() == JsonWizardFactory::ProjectWizard; }); diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index d6663680c25..576c626aaea 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -29,6 +29,7 @@ endif() add_subdirectory(processlauncher) if (WITH_QMLDESIGNER) add_subdirectory(qml2puppet) + add_subdirectory(sqlitetester) endif() add_subdirectory(qtcdebugger) ## windows only # add_subdirectory(qtcrashhandler) diff --git a/src/tools/qml2puppet/mockfiles/qt6/OverlayView3D.qml b/src/tools/qml2puppet/mockfiles/qt6/OverlayView3D.qml index 464e0b6b79c..7d7f419e429 100644 --- a/src/tools/qml2puppet/mockfiles/qt6/OverlayView3D.qml +++ b/src/tools/qml2puppet/mockfiles/qt6/OverlayView3D.qml @@ -498,7 +498,6 @@ View3D { targetNode: viewRoot.selectedNode globalOrientation: viewRoot.globalOrientation visible: viewRoot.selectedNode && viewRoot.transformMode === EditView3D.TransformMode.Move - && overlayView.isActive view3D: overlayView dragHelper: gizmoDragHelper property var propertyNames: ["position"] @@ -523,7 +522,6 @@ View3D { highlightOnHover: true targetNode: viewRoot.selectedNode visible: viewRoot.selectedNode && viewRoot.transformMode === EditView3D.TransformMode.Scale - && overlayView.isActive view3D: overlayView dragHelper: gizmoDragHelper property var propertyNames: ["scale"] @@ -550,7 +548,6 @@ View3D { targetNode: viewRoot.selectedNode globalOrientation: viewRoot.globalOrientation visible: viewRoot.selectedNode && viewRoot.transformMode === EditView3D.TransformMode.Rotate - && overlayView.isActive view3D: overlayView dragHelper: gizmoDragHelper property var propertyNames: ["eulerRotation"] @@ -588,7 +585,6 @@ View3D { Line3D { id: pivotLine visible: viewRoot.selectedNode && viewRoot.selectedNode !== viewRoot.multiSelectionNode - && overlayView.isActive name: "3D Edit View Pivot Line" color: "#ddd600" diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/mousearea3d.cpp b/src/tools/qml2puppet/qml2puppet/editor3d/mousearea3d.cpp index 118227360f7..51dc6416114 100644 --- a/src/tools/qml2puppet/qml2puppet/editor3d/mousearea3d.cpp +++ b/src/tools/qml2puppet/qml2puppet/editor3d/mousearea3d.cpp @@ -989,6 +989,12 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event) break; } + case QEvent::HoverLeave: { + setHovering(false); + if (s_mouseGrab == this && !dragging()) + s_mouseGrab = nullptr; + break; + } default: break; } diff --git a/src/tools/qml2puppet/qml2puppet/instances/nodeinstanceserver.cpp b/src/tools/qml2puppet/qml2puppet/instances/nodeinstanceserver.cpp index 9038ade7903..b4d6520512f 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/nodeinstanceserver.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/nodeinstanceserver.cpp @@ -382,18 +382,20 @@ void NodeInstanceServer::reparentInstances(const QVector &con ServerNodeInstance instance = instanceForId(container.instanceId()); if (instance.isValid()) { ServerNodeInstance newParent = instanceForId(container.newParentInstanceId()); - PropertyName newParentProperty = container.newParentProperty(); - if (!isInformationServer()) { - // Children of the component wraps are left out of the node tree to avoid - // incorrectly rendering them - if (newParent.isComponentWrap()) { - newParent = {}; - newParentProperty.clear(); + if (newParent.isValid()) { + PropertyName newParentProperty = container.newParentProperty(); + if (!isInformationServer()) { + // Children of the component wraps are left out of the node tree to avoid + // incorrectly rendering them + if (newParent.isComponentWrap()) { + newParent = {}; + newParentProperty.clear(); + } } + instance.reparent(instanceForId(container.oldParentInstanceId()), + container.oldParentProperty(), + newParent, newParentProperty); } - instance.reparent(instanceForId(container.oldParentInstanceId()), - container.oldParentProperty(), - newParent, newParentProperty); } } } diff --git a/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp b/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp index 2a673bb2e9e..69e791f0dd9 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp @@ -173,6 +173,11 @@ bool ObjectNodeInstance::isPropertyChange() const return false; } +bool ObjectNodeInstance::isComposedEffect() const +{ + return false; +} + bool ObjectNodeInstance::equalGraphicsItem(QGraphicsItem * /*item*/) const { return false; diff --git a/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.h b/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.h index 3fad24e661f..7164aae8319 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.h +++ b/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.h @@ -83,6 +83,7 @@ public: virtual bool isLayoutable() const; virtual bool isRenderable() const; virtual bool isPropertyChange() const; + virtual bool isComposedEffect() const; virtual bool equalGraphicsItem(QGraphicsItem *item) const; diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.cpp b/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.cpp index db5f9cba128..c6875b71d10 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.cpp @@ -17,11 +17,13 @@ #include +#include + #ifdef QUICK3D_MODULE #include #include #include -#include +#include #endif namespace QmlDesigner { @@ -35,7 +37,7 @@ Qt5Import3dNodeInstanceServer::Qt5Import3dNodeInstanceServer(NodeInstanceClientI #ifdef QUICK3D_MODULE m_generalHelper = new Internal::GeneralHelper(); QObject::connect(m_generalHelper, &Internal::GeneralHelper::requestRender, this, [this]() { - startRenderTimer(); + addCurrentNodeToRenderQueue(); }); #endif } @@ -51,7 +53,25 @@ void Qt5Import3dNodeInstanceServer::createScene(const CreateSceneCommand &comman registerFonts(command.resourceUrl); setTranslationLanguage(command.language); setupScene(command); - startRenderTimer(); + +#ifdef QUICK3D_MODULE + QObject *obj = rootItem(); + auto initView = [&obj, this](const QString &viewId, QQuick3DViewport *&view3D) { + QQmlProperty viewProp(obj, viewId, context()); + QObject *viewObj = viewProp.read().value(); + view3D = qobject_cast(viewObj); + }; + initView("view3d", m_view3D); + initView("iconView3d", m_iconView3D); + + if (m_view3D) { + QQmlProperty sceneNodeProp(obj, "sceneNode", context()); + m_sceneNode = sceneNodeProp.read().value(); + m_defaultCameraRotation = m_view3D->camera()->rotation(); + m_defaultCameraPosition = m_view3D->camera()->position(); + addInitToRenderQueue(); + } +#endif } void Qt5Import3dNodeInstanceServer::view3DAction([[maybe_unused]] const View3DActionCommand &command) @@ -66,9 +86,14 @@ void Qt5Import3dNodeInstanceServer::view3DAction([[maybe_unused]] const View3DAc QQmlProperty hProp(obj, "height", context()); wProp.write(size.width()); hProp.write(size.height()); + if (auto camera = qobject_cast(m_view3D->camera())) { + if (size.width() >= size.height()) + camera->setFieldOfViewOrientation(QQuick3DPerspectiveCamera::Vertical); + else + camera->setFieldOfViewOrientation(QQuick3DPerspectiveCamera::Horizontal); + } resizeCanvasToRootItem(); - - startRenderTimer(); + addCurrentNodeToRenderQueue(); } break; } @@ -76,15 +101,80 @@ void Qt5Import3dNodeInstanceServer::view3DAction([[maybe_unused]] const View3DAc QObject *obj = rootItem(); QQmlProperty sceneNodeProp(obj, "sceneNode", context()); auto sceneNode = sceneNodeProp.read().value(); - if (sceneNode) { + if (sceneNode && m_previewData.contains(m_currentNode)) { + PreviewData &data = m_previewData[m_currentNode]; QPointF delta = command.value().toPointF(); m_generalHelper->orbitCamera(m_view3D->camera(), m_view3D->camera()->eulerRotation(), - m_lookAt, {}, {float(delta.x()), float(delta.y()), 0.f}); - m_keepRendering = true; - startRenderTimer(); + data.lookAt, {}, {float(delta.x()), float(delta.y()), 0.f}); + // Add 2 renders to keep render timer alive for smooth rotation + addCurrentNodeToRenderQueue(2); + data.cameraRotation = m_view3D->camera()->rotation(); + data.cameraPosition = m_view3D->camera()->position(); } break; } + case View3DActionType::Import3dAddPreviewModel: { + const QVariantHash cmd = command.value().toHash(); + const QString name = cmd["name"].toString(); + const QString qmlName = cmd["qmlName"].toString(); + const QString folder = cmd["folder"].toString(); + + bool isUpdate = m_previewData.contains(name); + if (isUpdate) { + QQuick3DNode *node = m_previewData[name].node; + if (node) { + node->setParentItem({}); + node->setParent({}); + node->deleteLater(); + } + } + + PreviewData &data = m_previewData[name]; + data.name = name; + data.lookAt = {}; + if (!isUpdate) { + data.cameraRotation = m_defaultCameraRotation; + data.cameraPosition = m_defaultCameraPosition; + } + + QFileInfo fi(fileUrl().toLocalFile()); + QString compPath = fi.absolutePath() + '/' + folder + '/' + qmlName + ".qml"; + QQmlComponent comp(engine(), compPath, QQmlComponent::PreferSynchronous); + data.node = qobject_cast(comp.create(context())); + if (data.node) { + engine()->setObjectOwnership(data.node, QJSEngine::CppOwnership); + data.node->setParentItem(m_sceneNode); + data.node->setParent(m_sceneNode); + + addInitToRenderQueue(); + + if (m_currentNode == name) + addCurrentNodeToRenderQueue(); + + addIconToRenderQueue(name); + } + + break; + } + case View3DActionType::Import3dSetCurrentPreviewModel: { + QString newName = command.value().toString(); + if (m_previewData.contains(newName) && m_currentNode != newName) { + QQuick3DCamera *camera = m_view3D->camera(); + if (m_previewData.contains(m_currentNode)) { + PreviewData &oldData = m_previewData[m_currentNode]; + oldData.cameraPosition = camera->position(); + oldData.cameraRotation = camera->rotation(); + } + m_currentNode = newName; + const PreviewData &newData = m_previewData[m_currentNode]; + camera->setPosition(newData.cameraPosition); + camera->setRotation(newData.cameraRotation); + addInitToRenderQueue(); + addCurrentNodeToRenderQueue(); + } + break; + } + default: break; } @@ -93,8 +183,10 @@ void Qt5Import3dNodeInstanceServer::view3DAction([[maybe_unused]] const View3DAc void Qt5Import3dNodeInstanceServer::startRenderTimer() { - if (m_keepRendering && timerMode() == TimerMode::NormalTimer) +#ifdef QUICK3D_MODULE + if (!m_renderQueue.isEmpty() && timerMode() == TimerMode::NormalTimer) return; +#endif NodeInstanceServer::startRenderTimer(); } @@ -102,16 +194,52 @@ void Qt5Import3dNodeInstanceServer::startRenderTimer() void Qt5Import3dNodeInstanceServer::cleanup() { #ifdef QUICK3D_MODULE - delete m_previewNode; + for (const PreviewData &data : std::as_const(m_previewData)) + delete data.node; + m_previewData.clear(); delete m_generalHelper; #endif } -void Qt5Import3dNodeInstanceServer::finish() +#ifdef QUICK3D_MODULE +void Qt5Import3dNodeInstanceServer::addInitToRenderQueue() { - cleanup(); + startRenderTimer(); + + // "Init" render is simply a rendering of the entire scene without producing any images. + // This is done to make sure everything is initialized properly for subsequent renders. + + if (m_renderQueue.isEmpty() || m_renderQueue[0] != RenderType::Init) + m_renderQueue.prepend(RenderType::Init); } +void Qt5Import3dNodeInstanceServer::addCurrentNodeToRenderQueue(int count) +{ + startRenderTimer(); + + int remaining = count; + for (const RenderType &type : std::as_const(m_renderQueue)) { + if (type == RenderType::CurrentNode && --remaining <= 0) + return; + } + + int index = !m_renderQueue.isEmpty() && m_renderQueue[0] == RenderType::Init ? 1 : 0; + + while (remaining > 0) { + m_renderQueue.insert(index, RenderType::CurrentNode); + --remaining; + } +} + +void Qt5Import3dNodeInstanceServer::addIconToRenderQueue(const QString &assetName) +{ + startRenderTimer(); + + m_generateIconQueue.append(assetName); + m_renderQueue.append(RenderType::NextIcon); +} +#endif + void Qt5Import3dNodeInstanceServer::collectItemChangesAndSendChangeCommands() { static bool inFunction = false; @@ -133,75 +261,113 @@ void Qt5Import3dNodeInstanceServer::collectItemChangesAndSendChangeCommands() void Qt5Import3dNodeInstanceServer::render() { #ifdef QUICK3D_MODULE - ++m_renderCount; + if (m_renderQueue.isEmpty() || !m_view3D || !m_iconView3D) + return; - if (m_renderCount == 1) { - QObject *obj = rootItem(); - QQmlProperty viewProp(obj, "view3d", context()); - QObject *viewObj = viewProp.read().value(); - m_view3D = qobject_cast(viewObj); - if (m_view3D) { - QQmlProperty sceneModelNameProp(obj, "sceneModelName", context()); - QQmlProperty sceneNodeProp(obj, "sceneNode", context()); - auto sceneNode = sceneNodeProp.read().value(); - if (sceneNode) { - QString sceneModelName = sceneModelNameProp.read().toString(); - QFileInfo fi(fileUrl().toLocalFile()); - QString compPath = fi.absolutePath() + '/' + sceneModelName + ".qml"; - QQmlComponent comp(engine(), compPath, QQmlComponent::PreferSynchronous); - m_previewNode = qobject_cast(comp.create(context())); - if (m_previewNode) { - engine()->setObjectOwnership(m_previewNode, QJSEngine::CppOwnership); - m_previewNode->setParentItem(sceneNode); - m_previewNode->setParent(sceneNode); + RenderType currentType = m_renderQueue.takeFirst(); + PreviewData data; + QQuick3DViewport *currentView = m_view3D; + QVector3D cameraPosition = m_view3D->camera()->position(); + QQuaternion cameraRotation = m_view3D->camera()->rotation(); + + if (currentType == RenderType::Init) { + m_view3D->setVisible(true); + m_iconView3D->setVisible(true); + } else { + auto showNode = [this](const QString &name) { + for (const PreviewData &data : std::as_const(m_previewData)) + data.node->setVisible(data.name == name); + }; + + if (currentType == RenderType::CurrentNode) { + if (m_previewData.contains(m_currentNode)) { + showNode(m_currentNode); + data = m_previewData[m_currentNode]; + m_view3D->setVisible(true); + m_iconView3D->setVisible(false); + } + } else if (currentType == RenderType::NextIcon) { + if (!m_generateIconQueue.isEmpty()) { + const QString assetName = m_generateIconQueue.takeFirst(); + if (m_previewData.contains(assetName)) { + m_view3D->setVisible(false); + m_iconView3D->setVisible(true); + showNode(assetName); + data = m_previewData[assetName]; + m_refocus = true; + currentView = m_iconView3D; + currentView->camera()->setRotation(m_defaultCameraRotation); + currentView->camera()->setPosition(m_defaultCameraPosition); } } } + + if (m_refocus && data.node) { + m_generalHelper->calculateBoundsAndFocusCamera(currentView->camera(), data.node, + currentView, 1050, false, data.lookAt, + data.extents); + if (currentType == RenderType::CurrentNode) { + auto getExtentStr = [&data](int idx) -> QString { + int prec = 0; + float val = data.extents[idx]; + + if (val == 0.f) { + prec = 1; + } else { + while (val < 100.f) { + ++prec; + val *= 10.f; + } + } + // Strip unnecessary zeroes after decimal separator + if (prec > 0) { + QString checkStr = QString::number(data.extents[idx], 'f', prec); + while (prec > 0 && (checkStr.last(1) == "0" || checkStr.last(1) == ".")) { + --prec; + checkStr.chop(1); + } + } + QString retval = QLocale().toString(data.extents[idx], 'f', prec); + return retval; + }; + + QQmlProperty extentsProp(rootItem(), "extents", context()); + extentsProp.write(tr("Dimensions: %1 x %2 x %3").arg(getExtentStr(0)) + .arg(getExtentStr(1)) + .arg(getExtentStr(2))); + } + } } - // Render scene once to ensure geometries are intialized so bounds calculations work correctly - if (m_renderCount == 2 && m_view3D) { - QVector3D extents; - m_generalHelper->calculateBoundsAndFocusCamera(m_view3D->camera(), m_previewNode, - m_view3D, 1050, false, m_lookAt, extents); - auto getExtentStr = [&extents](int idx) -> QString { - int prec = 0; - float val = extents[idx]; - while (val < 100.f) { - ++prec; - val *= 10.f; - } - // Strip unnecessary zeroes after decimal separator - if (prec > 0) { - QString checkStr = QString::number(extents[idx], 'f', prec); - while (prec > 0 && (checkStr.last(1) == "0" || checkStr.last(1) == ".")) { - --prec; - checkStr.chop(1); - } - } - QString retval = QLocale().toString(extents[idx], 'f', prec); - return retval; - }; - QQmlProperty extentsProp(rootItem(), "extents", context()); - extentsProp.write(tr("Dimensions: %1 x %2 x %3").arg(getExtentStr(0)) - .arg(getExtentStr(1)) - .arg(getExtentStr(2))); - } - - rootNodeInstance().updateDirtyNodeRecursive(); + currentView->update(); QImage renderImage = grabWindow(); - if (m_renderCount >= 2) { - ImageContainer imgContainer(0, renderImage, m_renderCount); - nodeInstanceClient()->handlePuppetToCreatorCommand( - {PuppetToCreatorCommand::Import3DPreviewImage, - QVariant::fromValue(imgContainer)}); - - if (!m_keepRendering) - slowDownRenderTimer(); - - m_keepRendering = false; + if (currentType == RenderType::Init) { + m_refocus = true; + } else if (currentType == RenderType::CurrentNode) { + if (m_previewData.contains(m_currentNode)) { + ImageContainer imgContainer(0, renderImage, 1000000); + nodeInstanceClient()->handlePuppetToCreatorCommand( + {PuppetToCreatorCommand::Import3DPreviewImage, QVariant::fromValue(imgContainer)}); + } + } else if (currentType == RenderType::NextIcon) { + if (!data.name.isEmpty()) { + QSizeF iconSize = m_iconView3D->size(); + QImage iconImage = renderImage.copy(0, 0, iconSize.width(), iconSize.height()); + static qint32 renderId = 1000001; + ImageContainer imgContainer(0, iconImage, ++renderId); + QVariantList cmdData; + cmdData.append(data.name); + cmdData.append(QVariant::fromValue(imgContainer)); + nodeInstanceClient()->handlePuppetToCreatorCommand( + {PuppetToCreatorCommand::Import3DPreviewIcon, cmdData}); + } + m_refocus = true; + currentView->camera()->setRotation(cameraRotation); + currentView->camera()->setPosition(cameraPosition); } + if (m_renderQueue.isEmpty()) + slowDownRenderTimer(); #else slowDownRenderTimer(); #endif diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.h b/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.h index cfffa904bd2..ceebd9cfa3f 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.h +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.h @@ -8,9 +8,12 @@ #endif #include "qt5nodeinstanceserver.h" +#ifdef QUICK3D_MODULE +#include "generalhelper.h" QT_BEGIN_NAMESPACE class QQuick3DNode; QT_END_NAMESPACE +#endif namespace QmlDesigner { @@ -33,17 +36,42 @@ protected: void startRenderTimer() override; private: - void finish(); void cleanup(); - int m_renderCount = 0; - bool m_keepRendering = false; - #ifdef QUICK3D_MODULE + void addInitToRenderQueue(); + void addCurrentNodeToRenderQueue(int count = 1); + void addIconToRenderQueue(const QString &assetName); + QQuick3DViewport *m_view3D = nullptr; + QQuick3DViewport *m_iconView3D = nullptr; Internal::GeneralHelper *m_generalHelper = nullptr; - QQuick3DNode *m_previewNode = nullptr; - QVector3D m_lookAt; + + struct PreviewData + { + QString name; + QVector3D lookAt; + QVector3D extents; + QQuick3DNode *node = {}; + QQuaternion cameraRotation; + QVector3D cameraPosition; + }; + QHash m_previewData; + + enum class RenderType + { + Init, + CurrentNode, + NextIcon + }; + QList m_renderQueue; + + bool m_refocus = false; + QString m_currentNode; + QQuick3DNode *m_sceneNode = {}; + QStringList m_generateIconQueue; + QQuaternion m_defaultCameraRotation; + QVector3D m_defaultCameraPosition; #endif }; diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 9549f59d3f3..d81a0aa5644 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -1377,6 +1377,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView( // Key number is selected so that it is unlikely to conflict other ImageContainer use. ImageContainer imgContainer(cmd.instanceId(), {}, 2100000001 + cmd.instanceId()); imgContainer.setImage(renderImage); + imgContainer.setRequestId(cmd.requestId()); // send the rendered image to creator process nodeInstanceClient()->handlePuppetToCreatorCommand( @@ -1472,6 +1473,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode2DImageView(const Reques if (!renderImage.isNull()) { imgContainer.setImage(renderImage); + imgContainer.setRequestId(cmd.requestId()); // send the rendered image to creator process nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::RenderModelNodePreviewImage, diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5nodeinstanceserver.cpp b/src/tools/qml2puppet/qml2puppet/instances/qt5nodeinstanceserver.cpp index 765b52321bf..32a901f8d1e 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5nodeinstanceserver.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5nodeinstanceserver.cpp @@ -89,6 +89,7 @@ void Qt5NodeInstanceServer::initializeView() m_viewData.renderControl = new QQuickRenderControl; m_viewData.window = new QQuickWindow(m_viewData.renderControl); + m_viewData.window->setColor(Qt::transparent); setPipelineCacheConfig(m_viewData.window); m_viewData.renderControl->initialize(); m_qmlEngine = new QQmlEngine; @@ -379,9 +380,11 @@ QImage Qt5NodeInstanceServer::grabRenderControl([[maybe_unused]] RenderViewData QRhiReadbackResult readResult; readResult.completed = [&] { readCompleted = true; - QImage wrapperImage(reinterpret_cast(readResult.data.constData()), - readResult.pixelSize.width(), readResult.pixelSize.height(), - QImage::Format_RGBA8888_Premultiplied); + QImage wrapperImage( + reinterpret_cast(readResult.data.constData()), + readResult.pixelSize.width(), + readResult.pixelSize.height(), + QImage::Format_RGBA8888_Premultiplied); if (viewData.rhi->isYUpInFramebuffer()) renderImage = wrapperImage.mirrored(); else diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp b/src/tools/qml2puppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp index 53af00ab094..c8f1d489e3e 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp @@ -239,7 +239,7 @@ void Qt5RenderNodeInstanceServer::changePropertyValues(const ChangeValuesCommand instance = instanceForObject(targetObject); } - if (instance.hasParent() && instance.propertyNames().contains("_isEffectItem")) + if (instance.hasParent() && instance.isComposedEffect()) makeDirtyRecursive(instance.parent()); } else if (container.isDynamic() && hasInstanceForId(container.instanceId())) { // Changes to dynamic properties are not always noticed by normal signal spy mechanism @@ -263,13 +263,68 @@ void Qt5RenderNodeInstanceServer::changePropertyBindings(const ChangeBindingsCom } } -void Qt5RenderNodeInstanceServer::makeDirtyRecursive(const ServerNodeInstance &instance) +void Qt5RenderNodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command) { - const QList children = instance.childItems(); - for (const auto &child : children) { - m_dirtyInstanceSet.insert(child); - makeDirtyRecursive(child); + ServerNodeInstance effectNode; + ServerNodeInstance oldParent; + const QVector containers = command.reparentInstances(); + for (const ReparentContainer &container : containers) { + if (hasInstanceForId(container.instanceId())) { + ServerNodeInstance instance = instanceForId(container.instanceId()); + if (instance.isComposedEffect()) { + oldParent = instance.parent(); + effectNode = instance; + break; + } + } + } + + Qt5NodeInstanceServer::reparentInstances(command); + + if (oldParent.isValid()) + makeDirtyRecursive(oldParent); + if (effectNode.isValid()) { + ServerNodeInstance newParent = effectNode.parent(); + if (newParent.isValid()) { + // This is a hack to work around Image elements sometimes losing their textures when + // used as children of an effect. Toggling the visibility of the affected node seems + // to be the only way to fix this issue. + // Note that just marking the children's visibility dirty doesn't fix this issue. + QQuickItem *parentItem = newParent.rootQuickItem(); + if (parentItem && parentItem->isVisible()) { + parentItem->setVisible(false); + parentItem->setVisible(true); + } + } } } +void Qt5RenderNodeInstanceServer::removeInstances(const RemoveInstancesCommand &command) +{ + ServerNodeInstance oldParent; + const QVector ids = command.instanceIds(); + for (qint32 id : ids) { + if (hasInstanceForId(id)) { + ServerNodeInstance instance = instanceForId(id); + if (instance.isComposedEffect()) { + oldParent = instance.parent(); + break; + } + } + } + + Qt5NodeInstanceServer::removeInstances(command); + + if (oldParent.isValid()) + makeDirtyRecursive(oldParent); +} + +void Qt5RenderNodeInstanceServer::makeDirtyRecursive(const ServerNodeInstance &instance) +{ + m_dirtyInstanceSet.insert(instance); + const QList children = instance.childItems(); + for (const auto &child : children) + makeDirtyRecursive(child); +} + } // namespace QmlDesigner diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5rendernodeinstanceserver.h b/src/tools/qml2puppet/qml2puppet/instances/qt5rendernodeinstanceserver.h index 1e0f885da16..cefa1ff7453 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5rendernodeinstanceserver.h +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5rendernodeinstanceserver.h @@ -19,6 +19,8 @@ public: void removeSharedMemory(const RemoveSharedMemoryCommand &command) override; void changePropertyValues(const ChangeValuesCommand &command) override; void changePropertyBindings(const ChangeBindingsCommand &command) override; + void reparentInstances(const ReparentInstancesCommand &command) override; + void removeInstances(const RemoveInstancesCommand &command) override; protected: void collectItemChangesAndSendChangeCommands() override; diff --git a/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp b/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp index e2859f26845..7fcb26776de 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -150,8 +150,6 @@ void QuickItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &object if (instanceId() == 0) nodeInstanceServer()->setRootItem(quickItem()); - else - quickItem()->setParentItem(nodeInstanceServer()->rootItem()); ObjectNodeInstance::initialize(objectNodeInstance, flags); } @@ -181,6 +179,10 @@ void QuickItemNodeInstance::doComponentComplete() if (contentItemProperty.isValid()) m_contentItem = contentItemProperty.read().value(); + QQmlProperty composedEffectProperty(quickItem(), "_isEffectItem", engine()); + if (composedEffectProperty.isValid()) + m_isComposedEffect = true; + quickItem()->update(); } @@ -490,6 +492,11 @@ bool QuickItemNodeInstance::isRenderable() const return quickItem() && (!s_unifiedRenderPath || isRootNodeInstance()); } +bool QuickItemNodeInstance::isComposedEffect() const +{ + return m_isComposedEffect; +} + QList QuickItemNodeInstance::stateInstances() const { QList instanceList; diff --git a/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.h b/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.h index 69ee6c1671a..7291d1ba004 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.h +++ b/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.h @@ -75,6 +75,7 @@ public: bool isMovable() const override; bool isQuickItem() const override; bool isRenderable() const override; + bool isComposedEffect() const override; QList stateInstances() const override; @@ -123,6 +124,7 @@ private: //variables double m_width; double m_height; bool m_hidden = false; + bool m_isComposedEffect = false; static bool s_createEffectItem; static bool s_unifiedRenderPath; }; diff --git a/src/tools/qml2puppet/qml2puppet/instances/servernodeinstance.cpp b/src/tools/qml2puppet/qml2puppet/instances/servernodeinstance.cpp index aa91b8ffaa7..c238fcd4588 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/servernodeinstance.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/servernodeinstance.cpp @@ -158,6 +158,11 @@ bool ServerNodeInstance::isComponentWrap() const return m_nodeInstance->isComponentWrap(); } +bool ServerNodeInstance::isComposedEffect() const +{ + return m_nodeInstance->isComposedEffect(); +} + QQuickItem *ServerNodeInstance::contentItem() const { return m_nodeInstance->contentItem(); diff --git a/src/tools/qml2puppet/qml2puppet/instances/servernodeinstance.h b/src/tools/qml2puppet/qml2puppet/instances/servernodeinstance.h index 079c2fad2ba..491daf92c2c 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/servernodeinstance.h +++ b/src/tools/qml2puppet/qml2puppet/instances/servernodeinstance.h @@ -54,6 +54,7 @@ public: friend class Qt5BakeLightsNodeInstanceServer; friend class Qt5PreviewNodeInstanceServer; friend class Qt5CapturePreviewNodeInstanceServer; + friend class Qt5RenderNodeInstanceServer; friend class Qt5TestNodeInstanceServer; friend class QHash; friend QHashValueType qHash(const ServerNodeInstance &instance); @@ -160,6 +161,7 @@ public: bool holdsGraphical() const; bool isComponentWrap() const; + bool isComposedEffect() const; QQuickItem *contentItem() const; diff --git a/src/tools/qml2puppet/qml2puppet/qmlpuppet.cpp b/src/tools/qml2puppet/qml2puppet/qmlpuppet.cpp index 332def504ee..345e2c4cf74 100644 --- a/src/tools/qml2puppet/qml2puppet/qmlpuppet.cpp +++ b/src/tools/qml2puppet/qml2puppet/qmlpuppet.cpp @@ -124,13 +124,13 @@ void QmlPuppet::initQmlRunner() QString options = m_coreApp->arguments().at(4); Import3D::import3D(sourceAsset, outDir, options); + } else { + startCrashpad(QCoreApplication::applicationDirPath() + + '/' + RELATIVE_LIBEXEC_PATH, crashReportsPath()); + + new QmlDesigner::Qt5NodeInstanceClientProxy(m_coreApp.get()); } - startCrashpad(QCoreApplication::applicationDirPath() - + '/' + RELATIVE_LIBEXEC_PATH, crashReportsPath()); - - new QmlDesigner::Qt5NodeInstanceClientProxy(m_coreApp.get()); - #if defined(Q_OS_WIN) && defined(QT_NO_DEBUG) SetErrorMode(SEM_NOGPFAULTERRORBOX); //We do not want to see any message boxes #endif diff --git a/src/tools/qml2puppet/qmlprivategate/qmlprivategate.cpp b/src/tools/qml2puppet/qmlprivategate/qmlprivategate.cpp index e6eaa66a0b9..5a98d88e934 100644 --- a/src/tools/qml2puppet/qmlprivategate/qmlprivategate.cpp +++ b/src/tools/qml2puppet/qmlprivategate/qmlprivategate.cpp @@ -90,19 +90,7 @@ static QQuickDesignerSupport::PropertyNameList propertyNameListForWritableProper QMetaType jsType = QMetaType::fromType(); int userType = value.userType(); - //qDebug() << jsType << jsType.id(); - //qDebug() << "tp" << value.typeName(); - //qDebug() << "ut" << userType; - - if (userType == jsType.id()) { - qDebug() << "js value found"; - //QJSValue jsValue = value.value(); //crashes - //qDebug() << jsValue.isObject(); - //qDebug() << jsValue.isQObject(); - } else { - - - + if (userType != jsType.id()) { valueType->setValue(value); propertyNameList.append(propertyNameListForWritablePropertiesInternal(valueType, baseName + QQuickDesignerSupport::PropertyName(metaProperty.name()) @@ -175,36 +163,12 @@ static QQuickDesignerSupport::PropertyNameList allPropertyNamesFork(QObject *obj propertyNameList.append(baseName + QQuickDesignerSupport::PropertyName(metaProperty.name())); const QJsonValue jsonValue = value.toJsonValue(); - if (!jsonValue.isNull()) { - qDebug() << "llokhere"; - qDebug() << "name" << metaProperty.name(); - qDebug() << "value" << value; - qDebug() << jsonValue; - } - if (value.isValid() && jsonValue.isNull()) { - //qDebug() << "llokhere crash"; - //qDebug() << "name" << metaProperty.name(); - //qDebug() << "value" << value; - //qDebug() << jsonValue; - - QMetaType jsType = QMetaType::fromType(); int userType = value.userType(); - //qDebug() << jsType << jsType.id(); - //qDebug() << "tp" << value.typeName(); - //qDebug() << "ut" << userType; - - if (userType == jsType.id()) { - qDebug() << "js value found"; - //QJSValue jsValue = value.value(); //crashes - //qDebug() << jsValue.isObject(); - //qDebug() << jsValue.isQObject(); - } else { - - + if (userType != jsType.id()) { valueType->setValue(value); propertyNameList.append(allPropertyNamesFork(valueType, baseName diff --git a/src/tools/sqlitetester/CMakeLists.txt b/src/tools/sqlitetester/CMakeLists.txt new file mode 100644 index 00000000000..d259383c545 --- /dev/null +++ b/src/tools/sqlitetester/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.16) + +# standalone build +if (NOT QT_CREATOR_API_DEFINED) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake") + + project(sqlitetester) + + set(CMAKE_AUTOMOC ON) + set(CMAKE_AUTORCC ON) + set(CMAKE_AUTOUIC ON) + set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) + + set(DESTINATION DESTINATION .) + include(QtCreatorIDEBranding) + include(QtCreatorAPI) + qtc_handle_compiler_cache_support() + + find_package(Qt6 + COMPONENTS Core Gui Widgets + REQUIRED + ) +endif() + +add_qtc_executable(sqlitetester + ${DESTINATION} + CONDITION WINDOWS AND BUILD_DESIGNSTUDIO + DEPENDS + Sqlite + Qt::Core Qt::Widgets + INCLUDES + ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} + SOURCES + main.cpp +) diff --git a/src/tools/sqlitetester/main.cpp b/src/tools/sqlitetester/main.cpp new file mode 100644 index 00000000000..1f514baed60 --- /dev/null +++ b/src/tools/sqlitetester/main.cpp @@ -0,0 +1,137 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +class DatabaseApp : public QWidget { + Q_OBJECT + +public: + DatabaseApp(QWidget *parent = nullptr); + +private slots: + void onSetDirectoryClicked(); + void createDatabase(const QString &dirPath); + +private: + void deleteFileIfExist(const QString &filePath); + void logMessage(const QString &message); + void logDetailedWindowsError(); + + QLineEdit *directoryLineEdit; + QTextBrowser *logBrowser; + QString databaseDirectory; +}; + +DatabaseApp::DatabaseApp(QWidget *parent) : QWidget(parent) { + QVBoxLayout *layout = new QVBoxLayout(this); + + directoryLineEdit = new QLineEdit(this); + directoryLineEdit->setPlaceholderText("Enter database directory path"); + layout->addWidget(directoryLineEdit); + + QPushButton *setDirectoryButton = new QPushButton("Set Directory and Create Database", this); + layout->addWidget(setDirectoryButton); + + logBrowser = new QTextBrowser(this); + layout->addWidget(logBrowser); + + connect(setDirectoryButton, &QPushButton::clicked, this, &DatabaseApp::onSetDirectoryClicked); +} + +void DatabaseApp::onSetDirectoryClicked() { + QString dirPath = directoryLineEdit->text(); + if (dirPath.isEmpty()) { + logMessage("Directory path is empty."); + return; + } + + QDir dir(dirPath); + if (!dir.exists()) { + logMessage("Directory does not exist."); + return; + } + + QTemporaryFile tempFile(dirPath + "/tempfileXXXXXX"); + if (!tempFile.open()) { + logMessage("Cannot create temporary file in the directory: " + tempFile.errorString()); + logDetailedWindowsError(); + return; + } + tempFile.close(); + + createDatabase(dirPath); +} + +void DatabaseApp::deleteFileIfExist(const QString &filePath) { + if (QFile::exists(filePath)) { + if (!QFile::remove(filePath)) { + logMessage(QString("Failed to delete existing file %1 before creating database").arg(filePath)); + logDetailedWindowsError(); + return; + } + } +} + +void DatabaseApp::createDatabase(const QString &dirPath) { + databaseDirectory = dirPath; + QString dbPath = dirPath + "/mysqlitetester.db"; + dbPath.replace("\\", "/"); + deleteFileIfExist(dbPath); + + try { + Sqlite::Database database{Utils::PathString{dbPath}}; + } catch (const Sqlite::Exception &e) { + logMessage(QString("Cannot create %1: %2").arg(dbPath, QString::fromUtf8(e.what()))); + logDetailedWindowsError(); + } + deleteFileIfExist(dbPath); + logMessage(QString("Test with %1 was successful.").arg(dbPath)); +} + +void DatabaseApp::logMessage(const QString &message) { + logBrowser->append(message); +} + +void DatabaseApp::logDetailedWindowsError() { + DWORD errorCode = GetLastError(); + if (errorCode != 0) { + LPVOID errorMsg; + DWORD size = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&errorMsg, 0, NULL); + + if (size) { + QString detailedMessage = QString::fromWCharArray((LPWSTR)errorMsg, size); + logMessage("Windows error: " + detailedMessage); + LocalFree(errorMsg); + } + } +} + +int main(int argc, char *argv[]) { + Sqlite::LibraryInitializer::initialize(); + + + QApplication app(argc, argv); + DatabaseApp window; + window.setWindowTitle("SQLite Write Database Tester"); + window.resize(400, 300); + window.show(); + return app.exec(); +} + +#include "main.moc" diff --git a/tests/auto/qml/qmldesigner/coretests/testrewriterview.h b/tests/auto/qml/qmldesigner/coretests/testrewriterview.h index 594ba3d3d39..75d7a73330d 100644 --- a/tests/auto/qml/qmldesigner/coretests/testrewriterview.h +++ b/tests/auto/qml/qmldesigner/coretests/testrewriterview.h @@ -3,8 +3,8 @@ #pragma once +#include #include -#include namespace QmlDesigner { diff --git a/tests/unit/README.md b/tests/unit/README.md index 80247b769a8..396633f10a2 100644 --- a/tests/unit/README.md +++ b/tests/unit/README.md @@ -11,10 +11,156 @@ All tests here depend on the [GoogleTest][1] framework. ## Best Practices -We're following those patterns/approaches; +We follow these patterns/approaches for structuring our tests: -* The Arrange, Act, and Assert (AAA) Pattern -* Given When Then (GWT) Pattern +Arrange, Act, and Assert (AAA) / Given When Then (GWT) + +This pattern structures your tests into three distinct sections: + + Arrange (Given): Set up the initial conditions and inputs. + Act (When): Execute the code being tested. + Assert (Then): Verify the result. + +The test name is descriptive and uses underlines for readability. +In the Act block, only the code you want to test should exist. Don't +add the setup code there. It makes the debugging harder because you have +to step over it. + +```cpp +TEST(String, default_string_is_empty) +{ + String text; + + bool isEmpty = text.empty(); + + ASSERT_TRUE(isEmpty); +} +``` + +If the code block gets hard to read, you can write Arrange, Act, and Assert comments. +So the blocks are easier to identify. Don't write other comments. Use a descriptive +test name. + +```cpp +TEST(String, default_string_is_empty) +{ + // arrange + String text; + + // act + bool isEmpty = text.empty(); + + // assert + ASSERT_TRUE(isEmpty); +} +``` + +If you use a fixture, you can sometimes skip the arrange part. + +Fixtures should have the same name as your class. If you test functions, +it is the namespace. Sometimes you need multiple fixtures. Then you append +a descriptive text. You can put an underline in between. + +```cpp +class String : public ::testing::Test +{ +protected: + String text; +} + +TEST_F(String, default_string_is_empty) +{ + bool isEmpty = text.empty(); + + ASSERT_TRUE(isEmpty); +} +``` +For mocks, you have to reverse the order of act and assert. + +```cpp +class String : public ::testing::Test +{ +protected: + NiceMock outputMock; + Printer printer; +} + +TEST_F(String, printer_appends_message_to_the_end) +{ + // arrange + String text; + + // assert + EXPECT_CALL(outputMock, print(EndsWith(text))) + + // act + printer.print(text); +} +``` + +Don't write loops or branches in tests. Google Tests has many facilities supporting you to write clear tests. + +Matcher, for example, gives a much better error message. + +```cpp +TEST_F(Storage, return_all_entries_with_the_name_which_starts_with_foo) +{ + storage.load(filepath); + + auto entries = storage.entries("foo*"); + + ASSERT_THAT(entries, UnorderedElementsAre(IsEntry("foo", Field(&Entry::values), Contains(5)), + IsEntry("fooBar", Field(&Entry::values), IsSubset(42, 77)))); +} +``` + +You can even make the matcher easier to read. + +```cpp +template +auto FieldValues(const Matcher &matcher) +{ + return Field(&Entry::values, matcher); +} + +TEST_F(Storage, return_all_entries_with_the_name_which_starts_with_foo) +{ + storage.load(filepath); + + auto entries = storage.entries("foo*"); + + ASSERT_THAT(entries, UnorderedElementsAre(IsEntry("foo", FieldValues(Contains(5)), + IsEntry("fooBar", FieldValues(IsSubset(42, 77)))); +} +``` + +## Avoid + +Don't use using namespaces. It leads easily to name collisions. + +```cpp +using namespace QmlDesigner; +``` + +If you have long namespace names, you can use: + +```cpp +namespace ModelUtils = QmlDesigner::ModelUtils; +``` + +You can import single types too. But mind, that your tests are written +for reading, not for writing. They are part of the code documentation. + +```cpp +using QmlDesigner::ModelNode; +using Node = QmlDesigner::ModelNode; +``` + +There are exceptions like literal namespaces. + +```cpp +using namespace Qt::Literals; +``` ## Test Organization diff --git a/tests/unit/tests/mocks/projectstorageerrornotifiermock.h b/tests/unit/tests/mocks/projectstorageerrornotifiermock.h index 730c70a66ab..1142342f582 100644 --- a/tests/unit/tests/mocks/projectstorageerrornotifiermock.h +++ b/tests/unit/tests/mocks/projectstorageerrornotifiermock.h @@ -12,6 +12,16 @@ class ProjectStorageErrorNotifierMock : public QmlDesigner::ProjectStorageErrorN public: MOCK_METHOD(void, typeNameCannotBeResolved, - (Utils::SmallStringView typeName, QmlDesigner::SourceId souceId), + (Utils::SmallStringView typeName, QmlDesigner::SourceId sourceId), + (override)); + MOCK_METHOD(void, + missingDefaultProperty, + (Utils::SmallStringView typeName, + Utils::SmallStringView propertyName, + QmlDesigner::SourceId sourceId), + (override)); + MOCK_METHOD(void, + propertyNameDoesNotExists, + (Utils::SmallStringView propertyName, QmlDesigner::SourceId sourceId), (override)); }; diff --git a/tests/unit/tests/mocks/projectstoragemock.h b/tests/unit/tests/mocks/projectstoragemock.h index 8d9c3381b2e..b74949510b6 100644 --- a/tests/unit/tests/mocks/projectstoragemock.h +++ b/tests/unit/tests/mocks/projectstoragemock.h @@ -324,26 +324,21 @@ public: fetchSourceContextId, (::Utils::SmallStringView SourceContextPath), ()); - MOCK_METHOD(QmlDesigner::SourceId, - fetchSourceId, - (QmlDesigner::SourceContextId SourceContextId, ::Utils::SmallStringView sourceName), - ()); + MOCK_METHOD(QmlDesigner::SourceNameId, fetchSourceNameId, (::Utils::SmallStringView sourceName), ()); MOCK_METHOD(QmlDesigner::SourceContextId, fetchSourceContextIdUnguarded, - (::Utils::SmallStringView SourceContextPath), + (::Utils::SmallStringView sourceContextPath), ()); - MOCK_METHOD(QmlDesigner::SourceId, - fetchSourceIdUnguarded, - (QmlDesigner::SourceContextId SourceContextId, ::Utils::SmallStringView sourceName), + MOCK_METHOD(QmlDesigner::SourceNameId, + fetchSourceNameIdUnguarded, + (::Utils::SmallStringView sourceName), ()); MOCK_METHOD(::Utils::PathString, fetchSourceContextPath, (QmlDesigner::SourceContextId sourceContextId)); - MOCK_METHOD(QmlDesigner::Cache::SourceNameAndSourceContextId, - fetchSourceNameAndSourceContextId, - (QmlDesigner::SourceId sourceId)); + MOCK_METHOD(Utils::SmallString, fetchSourceName, (QmlDesigner::SourceNameId sourceId)); MOCK_METHOD(std::vector, fetchAllSourceContexts, (), ()); - MOCK_METHOD(std::vector, fetchAllSources, (), ()); + MOCK_METHOD(std::vector, fetchAllSourceNames, (), ()); MOCK_METHOD(QmlDesigner::SourceId, propertyEditorPathId, @@ -364,11 +359,13 @@ public: exportedTypeNameBySourceId; }; -class ProjectStorageMockWithQtQtuick : public ProjectStorageMock +class ProjectStorageMockWithQtQuick : public ProjectStorageMock { public: - ProjectStorageMockWithQtQtuick(QmlDesigner::SourceId sourceId) + ProjectStorageMockWithQtQuick(QmlDesigner::SourceId sourceId, + Utils::SmallStringView localPathModuleName) { + createModule(localPathModuleName, QmlDesigner::Storage::ModuleKind::PathLibrary); setupQtQuick(); setupQtQuickImportedTypeNameIds(sourceId); setupCommonTypeCache(); diff --git a/tests/unit/tests/mocks/sourcepathcachemock.h b/tests/unit/tests/mocks/sourcepathcachemock.h index ec3374859fb..3e151607235 100644 --- a/tests/unit/tests/mocks/sourcepathcachemock.h +++ b/tests/unit/tests/mocks/sourcepathcachemock.h @@ -41,10 +41,6 @@ public: sourceContextPath, (QmlDesigner::SourceContextId directoryPathId), (const, override)); - MOCK_METHOD(QmlDesigner::SourceContextId, - sourceContextId, - (QmlDesigner::SourceId sourceId), - (const, override)); MOCK_METHOD(void, populateIfEmpty, (), (override)); }; diff --git a/tests/unit/tests/mocks/sqlitereadstatementmock.h b/tests/unit/tests/mocks/sqlitereadstatementmock.h index ed23409b97d..45c30d46290 100644 --- a/tests/unit/tests/mocks/sqlitereadstatementmock.h +++ b/tests/unit/tests/mocks/sqlitereadstatementmock.h @@ -69,11 +69,10 @@ public: (std::size_t), ()); - MOCK_METHOD(std::vector, valuesReturnCacheSources, (std::size_t), ()); - - MOCK_METHOD(QmlDesigner::Cache::SourceNameAndSourceContextId, - valueReturnCacheSourceNameAndSourceContextId, - (int) ); + MOCK_METHOD(std::vector, + valuesReturnCacheSourceNames, + (std::size_t), + ()); MOCK_METHOD(Sqlite::TimeStamp, valueWithTransactionReturnsTimeStamp, (Utils::SmallStringView), ()); MOCK_METHOD(int, valueWithTransactionReturnsInt, (Utils::SmallStringView), ()); @@ -162,8 +161,6 @@ public: else if constexpr (std::is_same_v>) return valueReturnsPropertyDeclaration(queryValues...); - else if constexpr (std::is_same_v) - return valueReturnCacheSourceNameAndSourceContextId(queryValues...); else if constexpr (std::is_same_v) return valueReturnsSourceContextId(queryValues...); else if constexpr (std::is_same_v) @@ -212,8 +209,8 @@ public: return valuesReturnRowIds(reserveSize); else if constexpr (std::is_same_v) return valuesReturnCacheSourceContexts(reserveSize); - else if constexpr (std::is_same_v) - return valuesReturnCacheSources(reserveSize); + else if constexpr (std::is_same_v) + return valuesReturnCacheSourceNames(reserveSize); else if constexpr (std::is_same_v) return valuesReturnsStorageTypes(reserveSize, queryValues...); else if constexpr (std::is_same_v) diff --git a/tests/unit/tests/printers/gtest-creator-printing.cpp b/tests/unit/tests/printers/gtest-creator-printing.cpp index 8ca65f4526e..4d70b5b68bf 100644 --- a/tests/unit/tests/printers/gtest-creator-printing.cpp +++ b/tests/unit/tests/printers/gtest-creator-printing.cpp @@ -24,6 +24,8 @@ #include #include +#include + namespace std { template ostream &operator<<(ostream &out, const QVector &vector) { @@ -157,7 +159,7 @@ void PrintTo(const Utils::SmallString &text, ::std::ostream *os) *os << "\"" << text << "\""; } -void PrintTo(const Utils::BasicSmallString<94> &text, ::std::ostream *os) +void PrintTo(const Utils::BasicSmallString<96> &text, ::std::ostream *os) { *os << "\"" << text << "\""; } @@ -534,6 +536,42 @@ std::ostream &operator<<(std::ostream &out, FlagIs flagIs) return out; } +std::ostream &operator<<(std::ostream &out, const BasicAuxiliaryDataKey &key) +{ + return out << "(" << key.name << ", " << key.type << ")"; +} + +std::ostream &operator<<(std::ostream &out, const BasicAuxiliaryDataKey &key) +{ + return out << "(" << key.name << ", " << key.type << ")"; +} + +std::ostream &operator<<(std::ostream &out, AuxiliaryDataType type) +{ + switch (type) { + case AuxiliaryDataType::None: + out << "None"; + break; + case AuxiliaryDataType::Temporary: + out << "Temporary"; + break; + case AuxiliaryDataType::Document: + out << "Document"; + break; + case AuxiliaryDataType::NodeInstancePropertyOverwrite: + out << "NodeInstancePropertyOverwrite"; + break; + case AuxiliaryDataType::NodeInstanceAuxiliary: + out << "NodeInstanceAuxiliary"; + break; + case AuxiliaryDataType::Persistent: + out << "Persistent"; + break; + } + + return out; +} + namespace Cache { std::ostream &operator<<(std::ostream &out, const SourceContext &sourceContext) @@ -576,12 +614,6 @@ std::ostream &operator<<(std::ostream &out, TypeTraits traits) if (traits.isFileComponent) out << " | isFileComponent"; - if (traits.isProjectComponent) - out << " | isProjectComponent"; - - if (traits.isInProjectModule) - out << " | isInProjectModule"; - if (traits.usesCustomParser) out << " | usesCustomParser"; @@ -669,8 +701,7 @@ std::ostream &operator<<(std::ostream &out, const PropertyDeclaration &propertyD { using Utils::operator<<; return out << "(\"" << propertyDeclaration.typeId << "\", " << propertyDeclaration.name << ", " - << propertyDeclaration.typeId << ", " << propertyDeclaration.traits << ", " - << propertyDeclaration.propertyTypeId << ")"; + << propertyDeclaration.traits << ", " << propertyDeclaration.propertyTypeId << ")"; } std::ostream &operator<<(std::ostream &out, const Type &type) @@ -835,8 +866,9 @@ std::ostream &operator<<(std::ostream &out, const Type &type) using Utils::operator<<; return out << "( typename: \"" << type.typeName << "\", prototype: {\"" << type.prototype << "\", " << type.prototypeId << "}, " << "\", extension: {\"" << type.extension - << "\", " << type.extensionId << "}, " << type.traits << ", source: " << type.sourceId - << ", exports: " << type.exportedTypes << ", properties: " << type.propertyDeclarations + << "\", " << type.extensionId << "}, traits" << type.traits + << ", source: " << type.sourceId << ", exports: " << type.exportedTypes + << ", properties: " << type.propertyDeclarations << ", functions: " << type.functionDeclarations << ", signals: " << type.signalDeclarations << ", changeLevel: " << type.changeLevel << ", default: " << type.defaultPropertyName << ")"; diff --git a/tests/unit/tests/printers/gtest-creator-printing.h b/tests/unit/tests/printers/gtest-creator-printing.h index 2444b9d98b5..8ca7595d0c5 100644 --- a/tests/unit/tests/printers/gtest-creator-printing.h +++ b/tests/unit/tests/printers/gtest-creator-printing.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include @@ -22,6 +23,8 @@ enum class LockingMode : char; class TimeStamp; template class BasicId; +template +class CompoundBasicId; std::ostream &operator<<(std::ostream &out, const Value &value); std::ostream &operator<<(std::ostream &out, const ValueView &value); @@ -36,6 +39,12 @@ std::ostream &operator<<(std::ostream &out, const BasicId &optional, ::std::ostream *os) void PrintTo(Utils::SmallStringView text, ::std::ostream *os); void PrintTo(const Utils::SmallString &text, ::std::ostream *os); -void PrintTo(const Utils::BasicSmallString<94> &text, ::std::ostream *os); +void PrintTo(const Utils::BasicSmallString<96> &text, ::std::ostream *os); void PrintTo(const Utils::PathString &text, ::std::ostream *os); } // namespace Utils @@ -126,6 +135,8 @@ class NodeMetaInfo; class PropertyMetaInfo; struct CompoundPropertyMetaInfo; enum class FlagIs : unsigned int; +template +class BasicAuxiliaryDataKey; std::ostream &operator<<(std::ostream &out, const ModelNode &node); std::ostream &operator<<(std::ostream &out, const VariantProperty &property); @@ -142,6 +153,9 @@ std::ostream &operator<<(std::ostream &out, const NodeMetaInfo &metaInfo); std::ostream &operator<<(std::ostream &out, const PropertyMetaInfo &metaInfo); std::ostream &operator<<(std::ostream &out, const CompoundPropertyMetaInfo &metaInfo); std::ostream &operator<<(std::ostream &out, FlagIs flagIs); +std::ostream &operator<<(std::ostream &out, const BasicAuxiliaryDataKey &key); +std::ostream &operator<<(std::ostream &out, const BasicAuxiliaryDataKey &key); +std::ostream &operator<<(std::ostream &out, AuxiliaryDataType type); namespace Cache { class SourceContext; diff --git a/tests/unit/tests/printers/gtest-qt-printing.cpp b/tests/unit/tests/printers/gtest-qt-printing.cpp index f432d87398c..970eae8fd96 100644 --- a/tests/unit/tests/printers/gtest-qt-printing.cpp +++ b/tests/unit/tests/printers/gtest-qt-printing.cpp @@ -12,10 +12,10 @@ QT_BEGIN_NAMESPACE -std::ostream &operator<<(std::ostream &out, const QByteArray &byteArray) +std::ostream &operator<<(std::ostream &out, QByteArrayView byteArray) { if (byteArray.contains('\n')) { - QByteArray formattedArray = byteArray; + QByteArray formattedArray = byteArray.toByteArray(); formattedArray.replace("\n", "\n\t"); out << "\n\t"; out.write(formattedArray.data(), formattedArray.size()); @@ -28,6 +28,11 @@ std::ostream &operator<<(std::ostream &out, const QByteArray &byteArray) return out; } +std::ostream &operator<<(std::ostream &out, const QByteArray &byteArray) +{ + return out << QByteArrayView{byteArray}; +} + std::ostream &operator<<(std::ostream &out, const QString &text) { return out << text.toUtf8(); diff --git a/tests/unit/tests/printers/gtest-qt-printing.h b/tests/unit/tests/printers/gtest-qt-printing.h index 97e6822a7bd..a81994be167 100644 --- a/tests/unit/tests/printers/gtest-qt-printing.h +++ b/tests/unit/tests/printers/gtest-qt-printing.h @@ -39,6 +39,7 @@ std::ostream &operator<<(std::ostream &out, const QVariant &QVariant); std::ostream &operator<<(std::ostream &out, const QString &text); std::ostream &operator<<(std::ostream &out, QStringView text); std::ostream &operator<<(std::ostream &out, const QByteArray &byteArray); +std::ostream &operator<<(std::ostream &out, QByteArrayView byteArray); std::ostream &operator<<(std::ostream &out, const QTextCharFormat &format); std::ostream &operator<<(std::ostream &out, const QImage &image); std::ostream &operator<<(std::ostream &out, const QIcon &icon); diff --git a/tests/unit/tests/printers/gtest-std-printing.h b/tests/unit/tests/printers/gtest-std-printing.h index af62ddfb1ee..f2ad83ef619 100644 --- a/tests/unit/tests/printers/gtest-std-printing.h +++ b/tests/unit/tests/printers/gtest-std-printing.h @@ -4,6 +4,8 @@ #pragma once #include +#include +#include #include namespace std { @@ -24,4 +26,41 @@ ostream &operator<<(ostream &out, const vector &vector) return out; } +template +ostream &operator<<(ostream &out, const span &span) +{ + out << "["; + + for (auto current = span.begin(); current != span.end(); ++current) { + out << *current; + + if (std::next(current) != span.end()) + out << ", "; + } + + out << "]"; + + return out; +} + +template +ostream &operator<<(ostream &out, const pair &pair) +{ + out << "{"; + + out << pair.first; + + out << ", "; + + out << pair.second; + + out << "}"; + + return out; +} + +inline ostream &operator<<(ostream &out, std::byte byte) +{ + return out << std::hex << static_cast(byte) << std::dec; +} } // namespace std diff --git a/tests/unit/tests/testdesignercore/CMakeLists.txt b/tests/unit/tests/testdesignercore/CMakeLists.txt index c446af81a35..a06525bccb7 100644 --- a/tests/unit/tests/testdesignercore/CMakeLists.txt +++ b/tests/unit/tests/testdesignercore/CMakeLists.txt @@ -18,6 +18,7 @@ add_qtc_library(TestDesignerCore OBJECT ${QmlDesignerDir}/designercore ${QmlDesignerDir}/designercore/include ${QmlDesignerDir}/designercore/imagecache + ${QmlDesignerDir}/designercore/designercoreutils PUBLIC_DEFINES UNIT_TESTS DONT_CHECK_MESSAGE_COUNTER @@ -80,6 +81,7 @@ add_qtc_library(TestDesignerCore OBJECT metainfo/nodemetainfo.cpp model/abstractproperty.cpp model/abstractview.cpp + model/auxiliarypropertystorageview.cpp model/auxiliarypropertystorageview.h model/annotation.cpp model/bindingproperty.cpp model/import.cpp @@ -104,9 +106,9 @@ add_qtc_library(TestDesignerCore OBJECT model/modelnode.cpp model/modelresourcemanagementinterface.h model/modelresourcemanagement.cpp model/modelresourcemanagement.h - model/modelutils.cpp model/modelutils.h - model/propertycontainer.cpp - model/propertyparser.cpp + designercoreutils/modelutils.cpp designercoreutils/modelutils.h + rewriter/propertycontainer.cpp + rewriter/propertyparser.cpp model/nodeabstractproperty.cpp model/nodelistproperty.cpp model/nodeproperty.cpp @@ -147,10 +149,10 @@ add_qtc_library(TestDesignerCore OBJECT projectstorage/qmldocumentparserinterface.h projectstorage/qmltypesparserinterface.h tracing/qmldesignertracing.cpp tracing/qmldesignertracing.h - rewritertransaction.cpp - rewritertransaction.h - uniquename.cpp - uniquename.h + rewriter/rewritertransaction.cpp + include/rewritertransaction.h + designercoreutils/uniquename.cpp + designercoreutils/uniquename.h ) extend_qtc_library(TestDesignerCore diff --git a/tests/unit/tests/unittests/CMakeLists.txt b/tests/unit/tests/unittests/CMakeLists.txt index 77cf7a716cd..0c5f8bfd5ed 100644 --- a/tests/unit/tests/unittests/CMakeLists.txt +++ b/tests/unit/tests/unittests/CMakeLists.txt @@ -45,6 +45,7 @@ function(unittest_copy_data_folder) endfunction(unittest_copy_data_folder) add_subdirectory(componentcore) +add_subdirectory(designercoreutils) add_subdirectory(listmodeleditor) add_subdirectory(imagecache) add_subdirectory(metainfo) diff --git a/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp b/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp index b36966dda16..72788bbd83e 100644 --- a/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp +++ b/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp @@ -172,7 +172,7 @@ protected: inline static QSharedPointer simpleReaderNode; NiceMock viewMock; NiceMock pathCacheMock{"/path/foo.qml"}; - NiceMock projectStorageMock{pathCacheMock.sourceId}; + NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; NiceMock resourceManagementMock; QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", diff --git a/tests/unit/tests/unittests/componentcore/propertyeditorcomponentgenerator-test.cpp b/tests/unit/tests/unittests/componentcore/propertyeditorcomponentgenerator-test.cpp index 398c54bfad4..ff46d6536d1 100644 --- a/tests/unit/tests/unittests/componentcore/propertyeditorcomponentgenerator-test.cpp +++ b/tests/unit/tests/unittests/componentcore/propertyeditorcomponentgenerator-test.cpp @@ -84,7 +84,7 @@ protected: protected: QmlDesigner::SourceId sourceId = QmlDesigner::SourceId::create(10); - NiceMock projectStorageMock{sourceId}; + NiceMock projectStorageMock{sourceId, "/path"}; NiceMock propertyGeneratorMock; QmlDesigner::PropertyEditorComponentGenerator generator{propertyGeneratorMock}; QmlDesigner::ModuleId qtQuickModuleId = projectStorageMock.createModule("QtQuick", diff --git a/tests/unit/tests/unittests/designercoreutils/CMakeLists.txt b/tests/unit/tests/unittests/designercoreutils/CMakeLists.txt new file mode 100644 index 00000000000..51bd3a88d11 --- /dev/null +++ b/tests/unit/tests/unittests/designercoreutils/CMakeLists.txt @@ -0,0 +1,9 @@ +# qmldesigner/designercore/model +extend_qtc_test(unittest + DEPENDS + QmlDesignerUtils + SOURCES + modelutils-test.cpp + uniquename-test.cpp + version-test.cpp +) diff --git a/tests/unit/tests/unittests/designercoreutils/modelutils-test.cpp b/tests/unit/tests/unittests/designercoreutils/modelutils-test.cpp new file mode 100644 index 00000000000..24393accd04 --- /dev/null +++ b/tests/unit/tests/unittests/designercoreutils/modelutils-test.cpp @@ -0,0 +1,704 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include + +#include +#include +#include +#include +#include +#include + +namespace { +using QmlDesigner::ModelNode; +using QmlDesigner::ModelNodes; +using QmlDesigner::Storage::ModuleKind; + +class ModelUtilsWithModel : public ::testing::Test +{ +protected: + NiceMock pathCacheMock{"/path/model.qml"}; + QmlDesigner::SourceId sourceId = pathCacheMock.createSourceId("/path/foo.qml"); + NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; + QmlDesigner::ModuleId moduleId = projectStorageMock.moduleId("QtQuick", ModuleKind::QmlLibrary); + QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, + "Item", + {QmlDesigner::Import::createLibraryImport("QML"), + QmlDesigner::Import::createLibraryImport("QtQuick"), + QmlDesigner::Import::createLibraryImport("QtQml.Models")}, + QUrl::fromLocalFile(pathCacheMock.path.toQString())}; +}; + +TEST_F(ModelUtilsWithModel, component_file_path) +{ + QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Reference}; + traits.isFileComponent = true; + auto typeId = projectStorageMock.createType(moduleId, "Foo", traits, {}, sourceId); + QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock}; + + auto path = QmlDesigner::ModelUtils::componentFilePath(pathCacheMock, metaInfo); + + ASSERT_THAT(path, "/path/foo.qml"); +} + +TEST_F(ModelUtilsWithModel, empty_component_file_path_for_non_file_component) +{ + auto typeId = projectStorageMock.createType(moduleId, "Foo", {}, {}, sourceId); + QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock}; + + auto path = QmlDesigner::ModelUtils::componentFilePath(pathCacheMock, metaInfo); + + ASSERT_THAT(path, IsEmpty()); +} + +TEST_F(ModelUtilsWithModel, empty_component_file_path_for_invalid_meta_info) +{ + QmlDesigner::NodeMetaInfo metaInfo; + + auto path = QmlDesigner::ModelUtils::componentFilePath(pathCacheMock, metaInfo); + + ASSERT_THAT(path, IsEmpty()); +} + +TEST_F(ModelUtilsWithModel, component_file_path_for_node) +{ + QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Reference}; + traits.isFileComponent = true; + auto typeId = projectStorageMock.createType(moduleId, "Foo", traits, {}, sourceId); + projectStorageMock.createImportedTypeNameId(pathCacheMock.sourceId, "Foo", typeId); + auto node = model.createModelNode("Foo"); + + auto path = QmlDesigner::ModelUtils::componentFilePath(node); + + ASSERT_THAT(path, "/path/foo.qml"); +} + +TEST_F(ModelUtilsWithModel, component_file_path_for_invalid_node_is_empty) +{ + auto path = QmlDesigner::ModelUtils::componentFilePath(QmlDesigner::ModelNode{}); + + ASSERT_THAT(path, IsEmpty()); +} + +TEST_F(ModelUtilsWithModel, component_file_path_for_node_without_metainfo_is_empty) +{ + QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Reference}; + traits.isFileComponent = true; + projectStorageMock.createType(moduleId, "Foo", traits, {}, sourceId); + auto node = model.createModelNode("Foo"); + + auto path = QmlDesigner::ModelUtils::componentFilePath(node); + + ASSERT_THAT(path, IsEmpty()); +} + +TEST_F(ModelUtilsWithModel, component_file_path_for_non_file_component_node_is_empty) +{ + auto typeId = projectStorageMock.createType(moduleId, "Foo", {}, {}, sourceId); + projectStorageMock.createImportedTypeNameId(pathCacheMock.sourceId, "Foo", typeId); + auto node = model.createModelNode("Foo"); + + auto path = QmlDesigner::ModelUtils::componentFilePath(node); + + ASSERT_THAT(path, IsEmpty()); +} + +TEST_F(ModelUtilsWithModel, find_lowest_common_ancestor) +{ + auto child1 = model.createModelNode("Item"); + auto child2 = model.createModelNode("Item"); + model.rootModelNode().defaultNodeAbstractProperty().reparentHere(child1); + model.rootModelNode().defaultNodeAbstractProperty().reparentHere(child2); + ModelNodes nodes{child1, child2}; + + auto commonAncestor = QmlDesigner::ModelUtils::lowestCommonAncestor(nodes); + + ASSERT_THAT(commonAncestor, model.rootModelNode()); +} + +TEST_F(ModelUtilsWithModel, lowest_common_ancestor_return_invalid_node_if_argument_is_invalid) +{ + auto child1 = model.createModelNode("Item"); + auto child2 = ModelNode{}; + model.rootModelNode().defaultNodeAbstractProperty().reparentHere(child1); + ModelNodes nodes{child1, child2}; + + auto commonAncestor = QmlDesigner::ModelUtils::lowestCommonAncestor(nodes); + + ASSERT_THAT(commonAncestor, Not(IsValid())); +} + +TEST_F(ModelUtilsWithModel, find_lowest_common_ancestor_when_one_of_the_nodes_is_parent) +{ + auto parentNode = model.createModelNode("Item"); + auto childNode = model.createModelNode("Item"); + parentNode.defaultNodeAbstractProperty().reparentHere(childNode); + model.rootModelNode().defaultNodeAbstractProperty().reparentHere(parentNode); + ModelNodes nodes{childNode, parentNode}; + + auto commonAncestor = QmlDesigner::ModelUtils::lowestCommonAncestor(nodes); + + ASSERT_THAT(commonAncestor, parentNode); +} + +TEST_F(ModelUtilsWithModel, lowest_common_ancestor_for_uncle_and_nephew_should_return_the_grandfather) +{ + auto grandFatherNode = model.createModelNode("Item"); + auto fatherNode = model.createModelNode("Item"); + auto uncleNode = model.createModelNode("Item"); + auto nephewNode = model.createModelNode("Item"); + fatherNode.defaultNodeAbstractProperty().reparentHere(nephewNode); + grandFatherNode.defaultNodeAbstractProperty().reparentHere(fatherNode); + grandFatherNode.defaultNodeAbstractProperty().reparentHere(uncleNode); + model.rootModelNode().defaultNodeAbstractProperty().reparentHere(grandFatherNode); + ModelNodes nodes{uncleNode, nephewNode}; + + auto commonAncestor = QmlDesigner::ModelUtils::lowestCommonAncestor(nodes); + + ASSERT_THAT(commonAncestor, grandFatherNode); +} + +TEST(ModelUtils, isValidQmlIdentifier_fails_on_empty_values) +{ + QStringView emptyValue = u""; + + bool isValidQmlIdentifier = QmlDesigner::ModelUtils::isValidQmlIdentifier(emptyValue); + + ASSERT_FALSE(isValidQmlIdentifier); +} + +TEST(ModelUtils, isValidQmlIdentifier_fails_on_upper_case_first_letter) +{ + QStringView id = u"Lmn"; + + bool isValidQmlIdentifier = QmlDesigner::ModelUtils::isValidQmlIdentifier(id); + + ASSERT_FALSE(isValidQmlIdentifier); +} + +TEST(ModelUtils, isValidQmlIdentifier_fails_on_digital_first_letter) +{ + QStringView id = u"6mn"; + + bool isValidQmlIdentifier = QmlDesigner::ModelUtils::isValidQmlIdentifier(id); + + ASSERT_FALSE(isValidQmlIdentifier); +} + +TEST(ModelUtils, isValidQmlIdentifier_fails_on_unicodes) +{ + QStringView id = u"sähköverkko"; + + bool isValidQmlIdentifier = QmlDesigner::ModelUtils::isValidQmlIdentifier(id); + + ASSERT_FALSE(isValidQmlIdentifier); +} + +TEST(ModelUtils, isValidQmlIdentifier_passes_on_lower_case_first_letter) +{ + QStringView id = u"mn"; + + bool isValidQmlIdentifier = QmlDesigner::ModelUtils::isValidQmlIdentifier(id); + + ASSERT_TRUE(isValidQmlIdentifier); +} + +TEST(ModelUtils, isValidQmlIdentifier_passes_on_underscored_first_letter) +{ + QStringView id = u"_m"; + + bool isValidQmlIdentifier = QmlDesigner::ModelUtils::isValidQmlIdentifier(id); + + ASSERT_TRUE(isValidQmlIdentifier); +} + +TEST(ModelUtils, isValidQmlIdentifier_passes_on_digital_non_first_letter) +{ + QStringView id = u"_6"; + + bool isValidQmlIdentifier = QmlDesigner::ModelUtils::isValidQmlIdentifier(id); + + ASSERT_TRUE(isValidQmlIdentifier); +} + +TEST(ModelUtils, isValidQmlIdentifier_passes_on_upper_case_non_first_letter) +{ + QStringView id = u"mN"; + + bool isValidQmlIdentifier = QmlDesigner::ModelUtils::isValidQmlIdentifier(id); + + ASSERT_TRUE(isValidQmlIdentifier); +} + +TEST(ModelUtils, isValidQmlIdentifier_passes_on_underscore_only) +{ + QStringView id = u"_"; + + bool isValidQmlIdentifier = QmlDesigner::ModelUtils::isValidQmlIdentifier(id); + + ASSERT_TRUE(isValidQmlIdentifier); +} + +class IsQmlKeywords : public testing::TestWithParam +{}; + +INSTANTIATE_TEST_SUITE_P(ModelUtils, + IsQmlKeywords, + testing::Values(u"alias", + u"as", + u"break", + u"case", + u"catch", + u"continue", + u"debugger", + u"default", + u"delete", + u"do", + u"else", + u"finally", + u"for", + u"function", + u"if", + u"import", + u"in", + u"instanceof", + u"new", + u"print", + u"return", + u"switch", + u"this", + u"throw", + u"try", + u"typeof", + u"var", + u"void", + u"while", + u"with")); + +TEST_P(IsQmlKeywords, is_qml_keyword) +{ + QStringView id = GetParam(); + + bool isQmlKeyword = QmlDesigner::ModelUtils::isQmlKeyword(id); + + ASSERT_THAT(isQmlKeyword, IsTrue()); +} + +TEST(ModelUtils, is_not_qml_keyword) +{ + QStringView id = u"foo"; + + bool isQmlKeyword = QmlDesigner::ModelUtils::isQmlKeyword(id); + + ASSERT_THAT(isQmlKeyword, IsFalse()); +} + +TEST(ModelUtils, empty_is_not_qml_keyword) +{ + QStringView id = u""; + + bool isQmlKeyword = QmlDesigner::ModelUtils::isQmlKeyword(id); + + ASSERT_THAT(isQmlKeyword, IsFalse()); +} + +class IsDiscouragedQmlId : public testing::TestWithParam +{}; + +INSTANTIATE_TEST_SUITE_P(ModelUtils, + IsDiscouragedQmlId, + testing::Values(u"action", + u"anchors", + u"baseState", + u"border", + u"bottom", + u"clip", + u"data", + u"enabled", + u"flow", + u"focus", + u"font", + u"height", + u"id", + u"item", + u"layer", + u"left", + u"margin", + u"opacity", + u"padding", + u"parent", + u"right", + u"scale", + u"shaderInfo", + u"source", + u"sprite", + u"spriteSequence", + u"state", + u"text", + u"texture", + u"time", + u"top", + u"visible", + u"width", + u"x", + u"y", + u"z")); + +TEST_P(IsDiscouragedQmlId, is_discouraged_Qml_id) +{ + QStringView id = GetParam(); + + bool isDiscouragedQmlId = QmlDesigner::ModelUtils::isDiscouragedQmlId(id); + + ASSERT_THAT(isDiscouragedQmlId, IsTrue()); +} + +TEST(ModelUtils, is_not_discouraged_Qml_id) +{ + QStringView id = u"foo"; + + bool isDiscouragedQmlId = QmlDesigner::ModelUtils::isDiscouragedQmlId(id); + + ASSERT_THAT(isDiscouragedQmlId, IsFalse()); +} + +TEST(ModelUtils, empty_is_not_discouraged_Qml_id) +{ + QStringView id = u""; + + bool isDiscouragedQmlId = QmlDesigner::ModelUtils::isDiscouragedQmlId(id); + + ASSERT_THAT(isDiscouragedQmlId, IsFalse()); +} + +class IsQmlBuiltinType : public testing::TestWithParam +{}; + +INSTANTIATE_TEST_SUITE_P(ModelUtils, + IsQmlBuiltinType, + testing::Values(u"bool", + u"color", + u"date", + u"double", + u"enumeration", + u"font", + u"int", + u"list", + u"matrix4x4", + u"point", + u"quaternion", + u"real", + u"rect", + u"size", + u"string", + u"url", + u"var", + u"variant", + u"vector", + u"vector2d", + u"vector3d", + u"vector4d")); + +TEST_P(IsQmlBuiltinType, is_Qml_builtin_type) +{ + QStringView id = GetParam(); + + bool isQmlBuiltinType = QmlDesigner::ModelUtils::isQmlBuiltinType(id); + + ASSERT_THAT(isQmlBuiltinType, IsTrue()); +} + +TEST(ModelUtils, is_not_Qml_builtin_type) +{ + QStringView id = u"foo"; + + bool isQmlBuiltinType = QmlDesigner::ModelUtils::isQmlBuiltinType(id); + + ASSERT_THAT(isQmlBuiltinType, IsFalse()); +} + +TEST(ModelUtils, empty_is_not_Qml_builtin_type) +{ + QStringView id = u""; + + bool isQmlBuiltinType = QmlDesigner::ModelUtils::isQmlBuiltinType(id); + + ASSERT_THAT(isQmlBuiltinType, IsFalse()); +} + +class IsBannedQmlId : public testing::TestWithParam +{}; + +INSTANTIATE_TEST_SUITE_P(ModelUtils, + IsBannedQmlId, + testing::Values(u"alias", + u"as", + u"break", + u"case", + u"catch", + u"continue", + u"debugger", + u"default", + u"delete", + u"do", + u"else", + u"finally", + u"for", + u"function", + u"if", + u"import", + u"in", + u"instanceof", + u"new", + u"print", + u"return", + u"switch", + u"this", + u"throw", + u"try", + u"typeof", + u"var", + u"void", + u"while", + u"with", + u"action", + u"anchors", + u"baseState", + u"border", + u"bottom", + u"clip", + u"data", + u"enabled", + u"flow", + u"focus", + u"font", + u"height", + u"id", + u"item", + u"layer", + u"left", + u"margin", + u"opacity", + u"padding", + u"parent", + u"right", + u"scale", + u"shaderInfo", + u"source", + u"sprite", + u"spriteSequence", + u"state", + u"text", + u"texture", + u"time", + u"top", + u"visible", + u"width", + u"x", + u"y", + u"z", + u"bool", + u"color", + u"date", + u"double", + u"enumeration", + u"font", + u"int", + u"list", + u"matrix4x4", + u"point", + u"quaternion", + u"real", + u"rect", + u"size", + u"string", + u"url", + u"var", + u"variant", + u"vector", + u"vector2d", + u"vector3d", + u"vector4d")); + +TEST_P(IsBannedQmlId, is_banned_Qml_id) +{ + QStringView id = GetParam(); + + bool isBannedQmlId = QmlDesigner::ModelUtils::isBannedQmlId(id); + + ASSERT_THAT(isBannedQmlId, IsTrue()); +} + +TEST(ModelUtils, is_not_banned_Qml_id) +{ + QStringView id = u"foo"; + + bool isBannedQmlId = QmlDesigner::ModelUtils::isBannedQmlId(id); + + ASSERT_THAT(isBannedQmlId, IsFalse()); +} + +TEST(ModelUtils, empty_is_not_banned_Qml_id) +{ + QStringView id = u""; + + bool isBannedQmlId = QmlDesigner::ModelUtils::isBannedQmlId(id); + + ASSERT_THAT(isBannedQmlId, IsFalse()); +} + +TEST(ModelUtils, expressionToList_empty_expression_returns_empty_list) +{ + QString expression = ""; + + QStringList list = QmlDesigner::ModelUtils::expressionToList(expression); + + ASSERT_THAT(list, IsEmpty()); +} + +TEST(ModelUtils, expressionToList_empty_array_returns_empty_list) +{ + QString expression = "[]"; + + QStringList list = QmlDesigner::ModelUtils::expressionToList(expression); + + ASSERT_THAT(list, IsEmpty()); +} + +TEST(ModelUtils, expressionToList_comma_only_array_returns_empty_list) +{ + QString expression = "[,,,]"; + + QStringList list = QmlDesigner::ModelUtils::expressionToList(expression); + + ASSERT_THAT(list, IsEmpty()); +} + +TEST(ModelUtils, expressionToList_space_only_array_returns_empty_list) +{ + QString expression = "[ , , , ]"; + + QStringList list = QmlDesigner::ModelUtils::expressionToList(expression); + + ASSERT_THAT(list, IsEmpty()); +} + +TEST(ModelUtils, expressionToList_single_expression_returns_single_item_list) +{ + QString expression = "aaa"; + + QStringList list = QmlDesigner::ModelUtils::expressionToList(expression); + + ASSERT_THAT(list, UnorderedElementsAre("aaa")); +} + +TEST(ModelUtils, expressionToList_single_expression_keeps_middle_spaces) +{ + QString expression = "aa a b"; + + QStringList list = QmlDesigner::ModelUtils::expressionToList(expression); + + ASSERT_THAT(list, UnorderedElementsAre("aa a b")); +} + +TEST(ModelUtils, expressionToList_single_expression_omites_side_spaces) +{ + QString expression = " aa a b "; + + QStringList list = QmlDesigner::ModelUtils::expressionToList(expression); + + ASSERT_THAT(list, UnorderedElementsAre("aa a b")); +} + +TEST(ModelUtils, expressionToList_single_item_array_returns_single_item_list) +{ + QString expression = "[aaa]"; + + QStringList list = QmlDesigner::ModelUtils::expressionToList(expression); + + ASSERT_THAT(list, UnorderedElementsAre("aaa")); +} + +TEST(ModelUtils, expressionToList_array_with_multiple_items_returns_all) +{ + QString expression = "[bbb,aaa,ccc]"; + + QStringList list = QmlDesigner::ModelUtils::expressionToList(expression); + + ASSERT_THAT(list, UnorderedElementsAre("bbb", "aaa", "ccc")); +} + +TEST(ModelUtils, expressionToList_array_with_empty_items_returns_clean_list) +{ + QString expression = "[,aaa,,bbb,ccc,,]"; + + QStringList list = QmlDesigner::ModelUtils::expressionToList(expression); + + ASSERT_THAT(list, UnorderedElementsAre("aaa", "bbb", "ccc")); +} + +TEST(ModelUtils, expressionToList_keeps_middle_spaces_in_tokens) +{ + QString expression = "[aaa,,a bb b,ccc]"; + + QStringList list = QmlDesigner::ModelUtils::expressionToList(expression); + + ASSERT_THAT(list, UnorderedElementsAre("aaa", "a bb b", "ccc")); +} + +TEST(ModelUtils, expressionToList_omits_side_spaces_in_tokens) +{ + QString expression = "[aaa,, a bb b ,ccc]"; + + QStringList list = QmlDesigner::ModelUtils::expressionToList(expression); + + ASSERT_THAT(list, UnorderedElementsAre("aaa", "a bb b", "ccc")); +} + +TEST(ModelUtils, expressionToList_unicodes_supported) +{ + QString expression = "[你好, foo]"; + + QStringList list = QmlDesigner::ModelUtils::expressionToList(expression); + + ASSERT_THAT(list, UnorderedElementsAre("你好", "foo")); +} + +TEST(ModelUtils, listToExpression_returns_non_array_expression_for_single_items) +{ + QStringList list = {"aaa"}; + + QString expression = QmlDesigner::ModelUtils::listToExpression(list); + + ASSERT_THAT(expression, Eq("aaa")); +} + +TEST(ModelUtils, listToExpression_returns_expression) +{ + QStringList list = {"aaa", "bbb", "ccc"}; + + QString expression = QmlDesigner::ModelUtils::listToExpression(list); + + ASSERT_THAT(expression, Eq("[aaa,bbb,ccc]")); +} + +TEST(ModelUtils, listToExpression_returns_expression_with_empty_items) +{ + QStringList list = {"aaa", "bbb", "", "ccc"}; + + QString expression = QmlDesigner::ModelUtils::listToExpression(list); + + ASSERT_THAT(expression, Eq("[aaa,bbb,,ccc]")); +} + +TEST(ModelUtils, listToExpression_returns_empty_for_empty_expressions) +{ + QStringList list = {}; + + QString expression = QmlDesigner::ModelUtils::listToExpression(list); + + ASSERT_THAT(expression, IsEmpty()); +} + +} // namespace diff --git a/tests/unit/tests/unittests/model/uniquename-test.cpp b/tests/unit/tests/unittests/designercoreutils/uniquename-test.cpp similarity index 63% rename from tests/unit/tests/unittests/model/uniquename-test.cpp rename to tests/unit/tests/unittests/designercoreutils/uniquename-test.cpp index c1caa346fa5..5967936713e 100644 --- a/tests/unit/tests/unittests/model/uniquename-test.cpp +++ b/tests/unit/tests/unittests/designercoreutils/uniquename-test.cpp @@ -81,6 +81,71 @@ TEST(UniqueName, generateId_prefixes_with_underscore_if_id_is_a_number) ASSERT_THAT(uniqueId, "_436"); } +TEST(UniqueName, generateId_stable_captilzation) +{ + QString id = "A CaMeL*cAsE"; + + QString uniqueId = UniqueName::generateId(id); + + ASSERT_THAT(uniqueId, "aCaMeLCAsE"); +} + +TEST(UniqueName, generateId_begins_with_non_latin) +{ + QString id = "😂_saneId"; + + QString uniqueId = UniqueName::generateId(id); + + ASSERT_THAT(uniqueId, "_saneId"); +} + +TEST(UniqueName, generateId_non_latin_chars) +{ + QString id = "😂1😂test😅*chars"; + + QString uniqueId = UniqueName::generateId(id); + + ASSERT_THAT(uniqueId, "_1TestChars"); +} + +TEST(UniqueName, generateId_use_fallback_id) +{ + QString id = "😂😂 😅* "; + + QString uniqueId = UniqueName::generateId(id, "validFallbackId"); + + ASSERT_THAT(uniqueId, "validFallbackId"); +} + +TEST(UniqueName, generateId_unused_fallback_id) +{ + QString id = "saneId"; + + QString uniqueId = UniqueName::generateId(id, "fallbackId"); + + ASSERT_THAT(uniqueId, "saneId"); +} + +TEST(UniqueName, generateId_use_emtpy_fallback) +{ + QString id = "😂😂 😅* "; + + QString uniqueId = UniqueName::generateId(id, QString{}); + + ASSERT_TRUE(uniqueId.isEmpty()); +} + +TEST(UniqueName, generateId_use_fallback_when_id_exists) +{ + QStringList existingIds = {"validFallbackId", "validFallbackId1"}; + auto pred = [&](const QString &id) -> bool { return existingIds.contains(id); }; + QString id = "😂😂 😅* "; + + QString uniqueId = UniqueName::generateId(id, "validFallbackId", pred); + + ASSERT_THAT(uniqueId, "validFallbackId2"); +} + TEST(UniqueName, generatePath_returns_same_path_when_path_doesnt_exist) { QString path = "<<>>"; diff --git a/tests/unit/tests/unittests/designercoreutils/version-test.cpp b/tests/unit/tests/unittests/designercoreutils/version-test.cpp new file mode 100644 index 00000000000..00fca5e8fb9 --- /dev/null +++ b/tests/unit/tests/unittests/designercoreutils/version-test.cpp @@ -0,0 +1,341 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include + +namespace { + +TEST(Version, same_versions_are_equal) +{ + QmlDesigner::Version version1{6, 5, 2}; + QmlDesigner::Version version2{6, 5, 2}; + + bool isEqual = version1 == version2; + + ASSERT_TRUE(isEqual); +} + +TEST(Version, invalid_versions_are_equal) +{ + QmlDesigner::Version version1; + QmlDesigner::Version version2; + + bool isEqual = version1 == version2; + + ASSERT_TRUE(isEqual); +} + +TEST(Version, different_minor_versions_are_not_equal) +{ + QmlDesigner::Version version1{6, 4}; + QmlDesigner::Version version2{6, 5}; + + bool isEqual = version1 == version2; + + ASSERT_FALSE(isEqual); +} + +TEST(Version, different_major_versions_are_not_equal) +{ + QmlDesigner::Version version1{5, 5}; + QmlDesigner::Version version2{6, 5}; + + bool isEqual = version1 == version2; + + ASSERT_FALSE(isEqual); +} + +TEST(Version, different_patch_versions_are_not_equal) +{ + QmlDesigner::Version version1{6, 5, 1}; + QmlDesigner::Version version2{6, 5, 2}; + + bool isEqual = version1 == version2; + + ASSERT_FALSE(isEqual); +} + +TEST(Version, less_minor_versions_are_less) +{ + QmlDesigner::Version version1{6, 4}; + QmlDesigner::Version version2{6, 5}; + + bool isLess = version1 < version2; + + ASSERT_TRUE(isLess); +} + +TEST(Version, less_major_versions_are_less) +{ + QmlDesigner::Version version1{5, 15}; + QmlDesigner::Version version2{6, 5}; + + bool isLess = version1 < version2; + + ASSERT_TRUE(isLess); +} + +TEST(Version, less_patch_versions_are_less) +{ + QmlDesigner::Version version1{6, 5, 3}; + QmlDesigner::Version version2{6, 5, 15}; + + bool isLess = version1 < version2; + + ASSERT_TRUE(isLess); +} + +TEST(Version, same_versions_are_not_less) +{ + QmlDesigner::Version version1{6, 5, 1}; + QmlDesigner::Version version2{6, 5, 1}; + + bool isLess = version1 < version2; + + ASSERT_FALSE(isLess); +} + +TEST(Version, empty_version_is_not_less) +{ + QmlDesigner::Version version1; + QmlDesigner::Version version2{6, 5}; + + bool isLess = version1 < version2; + + ASSERT_FALSE(isLess); +} + +TEST(Version, non_empty_version_is_is_less_than_empty_version) +{ + QmlDesigner::Version version1{6, 5}; + QmlDesigner::Version version2; + + bool isLess = version1 < version2; + + ASSERT_TRUE(isLess); +} + +TEST(Version, greater_minor_versions_are_greater) +{ + QmlDesigner::Version version1{6, 6}; + QmlDesigner::Version version2{6, 5}; + + bool isGreater = version1 > version2; + + ASSERT_TRUE(isGreater); +} + +TEST(Version, greater_major_versions_are_greater) +{ + QmlDesigner::Version version1{6, 5}; + QmlDesigner::Version version2{5, 15}; + + bool isGreater = version1 > version2; + + ASSERT_TRUE(isGreater); +} + +TEST(Version, same_versions_are_not_greater) +{ + QmlDesigner::Version version1{6, 5}; + QmlDesigner::Version version2{6, 5}; + + bool isGreater = version1 > version2; + + ASSERT_FALSE(isGreater); +} + +TEST(Version, empty_version_is_greater) +{ + QmlDesigner::Version version1; + QmlDesigner::Version version2{6, 5}; + + bool isGreater = version1 > version2; + + ASSERT_TRUE(isGreater); +} + +TEST(Version, empty_version_is_greater_than_non_empty_version) +{ + QmlDesigner::Version version1{6, 5}; + QmlDesigner::Version version2; + + bool isGreater = version1 > version2; + + ASSERT_FALSE(isGreater); +} + +TEST(Version, less_equal_minor_versions_are_less_equal) +{ + QmlDesigner::Version version1{6, 4}; + QmlDesigner::Version version2{6, 5}; + + bool isLessEqual = version1 <= version2; + + ASSERT_TRUE(isLessEqual); +} + +TEST(Version, lessqual_major_versions_are_lessqual) +{ + QmlDesigner::Version version1{5, 15}; + QmlDesigner::Version version2{6, 5}; + + bool isLessEqual = version1 <= version2; + + ASSERT_TRUE(isLessEqual); +} + +TEST(Version, same_versions_are_lessqual) +{ + QmlDesigner::Version version1{6, 5}; + QmlDesigner::Version version2{6, 5}; + + bool isLessEqual = version1 <= version2; + + ASSERT_TRUE(isLessEqual); +} + +TEST(Version, empty_version_is_not_lessqual) +{ + QmlDesigner::Version version1; + QmlDesigner::Version version2{6, 5}; + + bool isLessEqual = version1 <= version2; + + ASSERT_FALSE(isLessEqual); +} + +TEST(Version, non_empty_version_is_is_lessqual_than_empty_version) +{ + QmlDesigner::Version version1{6, 5}; + QmlDesigner::Version version2; + + bool isLessEqual = version1 <= version2; + + ASSERT_TRUE(isLessEqual); +} + +TEST(Version, greater_equal_minor_versions_are_greater_equal) +{ + QmlDesigner::Version version1{6, 6}; + QmlDesigner::Version version2{6, 5}; + + bool isGreaterEqual = version1 >= version2; + + ASSERT_TRUE(isGreaterEqual); +} + +TEST(Version, greater_equal_major_versions_are_greater_equal) +{ + QmlDesigner::Version version1{6, 5}; + QmlDesigner::Version version2{5, 15}; + + bool isGreaterEqual = version1 >= version2; + + ASSERT_TRUE(isGreaterEqual); +} + +TEST(Version, same_versions_are_greater_equal) +{ + QmlDesigner::Version version1{6, 5}; + QmlDesigner::Version version2{6, 5}; + + bool isGreaterEqual = version1 >= version2; + + ASSERT_TRUE(isGreaterEqual); +} + +TEST(Version, empty_version_is_greater_equal) +{ + QmlDesigner::Version version1; + QmlDesigner::Version version2{6, 5}; + + bool isGreaterEqual = version1 >= version2; + + ASSERT_TRUE(isGreaterEqual); +} + +TEST(Version, non_empty_version_is_is_not_greater_equal_than_empty_version) +{ + QmlDesigner::Version version1{6, 5}; + QmlDesigner::Version version2; + + bool isGreaterEqual = version1 >= version2; + + ASSERT_FALSE(isGreaterEqual); +} + +TEST(Version, version_fromString_empty_string_makes_empty_version) +{ + QStringView versionStr = u""; + + QmlDesigner::Version version = QmlDesigner::Version::fromString(versionStr); + + ASSERT_TRUE(version.isEmpty()); +} + +TEST(Version, version_fromString_is_the_same_as_initialized_version) +{ + QStringView versionStr = u"6.9.2"; + + QmlDesigner::Version version = QmlDesigner::Version::fromString(versionStr); + + ASSERT_THAT(version, Eq(QmlDesigner::Version{6, 9, 2})); +} + +TEST(Version, version_fromString_sets_zero_for_minor_and_patch) +{ + QStringView versionStr = u"6"; + + auto version = QmlDesigner::Version::fromString(versionStr); + + ASSERT_THAT(version, FieldsAre(6, 0, 0)); +} + +TEST(Version, version_fromString_sets_zero_for_patch) +{ + QStringView versionStr = u"6.3"; + + auto version = QmlDesigner::Version::fromString(versionStr); + + ASSERT_THAT(version, FieldsAre(6, 3, 0)); +} + +TEST(Version, version_fromString_empty_parts_are_zero) +{ + QStringView versionStr = u"6."; + + auto version = QmlDesigner::Version::fromString(versionStr); + + ASSERT_THAT(version, FieldsAre(6, 0, 0)); +} + +TEST(Version, version_fromString_non_standard_version_is_empty) +{ + QStringView versionStr = u"1-beta1"; + + auto version = QmlDesigner::Version::fromString(versionStr); + + ASSERT_TRUE(version.isEmpty()); +} + +TEST(Version, version_fromString_with_negative_major_is_empty) +{ + QStringView versionStr = u"-1"; + + auto version = QmlDesigner::Version::fromString(versionStr); + + ASSERT_TRUE(version.isEmpty()); +} + +TEST(Version, version_fromString_negative_minor_will_be_changed_to_zero) +{ + QStringView versionStr = u"6.-1"; + + auto version = QmlDesigner::Version::fromString(versionStr); + + ASSERT_THAT(version, FieldsAre(6, 0, 0)); +} + +} // namespace diff --git a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp index 06ab4f930cd..e866ad81c7f 100644 --- a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp +++ b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp @@ -71,7 +71,7 @@ MATCHER_P2(IsAbstractProperty, node, name, std::string(negation ? "isn't " : "is class ListModelEditor : public testing::Test { - using SourcePathCache = QmlDesigner::SourcePathCache, + using SourcePathCache = QmlDesigner::SourcePathCache, QmlDesigner::NonLockingMutex>; public: @@ -184,7 +184,7 @@ public: protected: NiceMock pathCacheMock{"/path/foo.qml"}; - NiceMock projectStorageMock{pathCacheMock.sourceId}; + NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; NiceMock> goIntoComponentMock; QmlDesigner::ModelPointer designerModel{ QmlDesigner::Model::create(QmlDesigner::ProjectStorageDependencies{projectStorageMock, diff --git a/tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp b/tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp index c96def356ab..b17a38098ee 100644 --- a/tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp +++ b/tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp @@ -100,7 +100,7 @@ protected: protected: NiceMock pathCache{"/path/foo.qml"}; - NiceMock projectStorageMock{pathCache.sourceId}; + NiceMock projectStorageMock{pathCache.sourceId, "/path"}; QmlDesigner::Model model{{projectStorageMock, pathCache}, "Item", {QmlDesigner::Import::createLibraryImport("QML"), @@ -230,74 +230,6 @@ TEST_F(NodeMetaInfo, component_is_file_component) ASSERT_TRUE(isFileComponent); } -TEST_F(NodeMetaInfo, is_project_component) -{ - auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); - TypeTraits traits{TypeTraitsKind::Reference}; - traits.isProjectComponent = true; - auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); - QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock}; - - bool isProjectComponent = metaInfo.isProjectComponent(); - - ASSERT_TRUE(isProjectComponent); -} - -TEST_F(NodeMetaInfo, is_not_project_component) -{ - using QmlDesigner::Storage::TypeTraits; - auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); - auto typeId = projectStorageMock.createType(moduleId, "Foo", {}); - QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock}; - - bool isProjectComponent = metaInfo.isProjectComponent(); - - ASSERT_FALSE(isProjectComponent); -} - -TEST_F(NodeMetaInfo, invalid_is_not_project_component) -{ - QmlDesigner::NodeMetaInfo metaInfo; - - bool isProjectComponent = metaInfo.isProjectComponent(); - - ASSERT_FALSE(isProjectComponent); -} - -TEST_F(NodeMetaInfo, is_in_project_module) -{ - auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); - TypeTraits traits{TypeTraitsKind::Reference}; - traits.isInProjectModule = true; - auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); - QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock}; - - bool isInProjectModule = metaInfo.isInProjectModule(); - - ASSERT_TRUE(isInProjectModule); -} - -TEST_F(NodeMetaInfo, is_not_in_project_module) -{ - using QmlDesigner::Storage::TypeTraits; - auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); - auto typeId = projectStorageMock.createType(moduleId, "Foo", {}); - QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock}; - - bool isInProjectModule = metaInfo.isInProjectModule(); - - ASSERT_FALSE(isInProjectModule); -} - -TEST_F(NodeMetaInfo, invalid_is_not_in_project_module) -{ - QmlDesigner::NodeMetaInfo metaInfo; - - bool isInProjectModule = metaInfo.isInProjectModule(); - - ASSERT_FALSE(isInProjectModule); -} - TEST_F(NodeMetaInfo, has_property) { auto metaInfo = model.qtQuickItemMetaInfo(); diff --git a/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp b/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp index d2ec90b7a81..d78c9ee8739 100644 --- a/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp +++ b/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp @@ -42,7 +42,7 @@ protected: protected: NiceMock pathCache{"/path/foo.qml"}; - NiceMock projectStorageMock{pathCache.sourceId}; + NiceMock projectStorageMock{pathCache.sourceId, "/path"}; QmlDesigner::Model model{{projectStorageMock, pathCache}, "Item", {QmlDesigner::Import::createLibraryImport("QML"), diff --git a/tests/unit/tests/unittests/model/CMakeLists.txt b/tests/unit/tests/unittests/model/CMakeLists.txt index 43d6154c504..b29eda3995f 100644 --- a/tests/unit/tests/unittests/model/CMakeLists.txt +++ b/tests/unit/tests/unittests/model/CMakeLists.txt @@ -1,11 +1,10 @@ # qmldesigner/designercore/model extend_qtc_test(unittest SOURCES + auxiliarypropertystorageview-test.cpp import-test.cpp model-test.cpp modelnode-test.cpp modelresourcemanagement-test.cpp - modelutils-test.cpp nodelistproperty-test.cpp - uniquename-test.cpp ) diff --git a/tests/unit/tests/unittests/model/auxiliarypropertystorageview-test.cpp b/tests/unit/tests/unittests/model/auxiliarypropertystorageview-test.cpp new file mode 100644 index 00000000000..a7d68390032 --- /dev/null +++ b/tests/unit/tests/unittests/model/auxiliarypropertystorageview-test.cpp @@ -0,0 +1,230 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include + +#include +#include +#include +#include + +#include + +namespace { + +using QmlDesigner::AuxiliaryDataKey; +using QmlDesigner::AuxiliaryDataType; +using QmlDesigner::ModelNode; + +template +auto AuxiliaryProperty(AuxiliaryDataType type, const NameMatcher &nameMatcher, const QVariant &value) +{ + return Pair(AllOf(Field(&AuxiliaryDataKey::type, type), + Field(&AuxiliaryDataKey::name, nameMatcher)), + value); +} + +class AuxiliaryPropertyStorageView : public ::testing::Test +{ +protected: + struct StaticData + { + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + }; + + ~AuxiliaryPropertyStorageView() { view.resetForTestsOnly(); } + + static void SetUpTestSuite() { staticData = std::make_unique(); } + + static void TearDownTestSuite() { staticData.reset(); } + + inline static std::unique_ptr staticData; + Sqlite::Database &database = staticData->database; + NiceMock pathCacheMock{"/path/foo.qml"}; + NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; + NiceMock resourceManagementMock; + QmlDesigner::Imports imports = {QmlDesigner::Import::createLibraryImport("QtQuick")}; + QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, + "Item", + imports, + pathCacheMock.path.toQString(), + std::make_unique( + resourceManagementMock)}; + QmlDesigner::Model model2{{projectStorageMock, pathCacheMock}, + "Item", + imports, + pathCacheMock.path.toQString(), + std::make_unique( + resourceManagementMock)}; + NiceMock externalDependenciesMock; + QmlDesigner::AuxiliaryPropertyStorageView view{database, externalDependenciesMock}; + ModelNode rootNode = model.rootModelNode(); + ModelNode rootNode2 = model2.rootModelNode(); + QmlDesigner::AuxiliaryDataKeyView persistentFooKey{AuxiliaryDataType::Persistent, "foo"}; + QmlDesigner::AuxiliaryDataKeyView temporaryFooKey{AuxiliaryDataType::Temporary, "foo"}; +}; + +TEST_F(AuxiliaryPropertyStorageView, store_persistent_auxiliary_property) +{ + // arrange + model.attachView(&view); + rootNode.setIdWithoutRefactoring("root"); + rootNode2.setIdWithoutRefactoring("root"); + + // act + rootNode.setAuxiliaryData(persistentFooKey, "text"); + + // assert + model.detachView(&view); + model2.attachView(&view); + ASSERT_THAT(rootNode2.auxiliaryData(), + Contains(AuxiliaryProperty(AuxiliaryDataType::Persistent, "foo", "text"))); +} + +TEST_F(AuxiliaryPropertyStorageView, store_color_auxiliary_property) +{ + // arrange + model.attachView(&view); + rootNode.setIdWithoutRefactoring("root"); + rootNode2.setIdWithoutRefactoring("root"); + QColor color{Qt::red}; + + // act + rootNode.setAuxiliaryData(persistentFooKey, color); + + // assert + model.detachView(&view); + model2.attachView(&view); + ASSERT_THAT(rootNode2.auxiliaryData(), + Contains(AuxiliaryProperty(AuxiliaryDataType::Persistent, "foo", color))); +} + +TEST_F(AuxiliaryPropertyStorageView, do_not_store_temporary_auxiliary_property) +{ + // arrange + model.attachView(&view); + rootNode.setIdWithoutRefactoring("root"); + rootNode2.setIdWithoutRefactoring("root"); + + // act + rootNode.setAuxiliaryData(temporaryFooKey, "text"); + + // assert + model.detachView(&view); + model2.attachView(&view); + ASSERT_THAT(rootNode2.auxiliaryData(), + Not(Contains(AuxiliaryProperty(AuxiliaryDataType::Temporary, "foo", "text")))); +} + +TEST_F(AuxiliaryPropertyStorageView, do_not_load_node_without_id) +{ + // arrange + model.attachView(&view); + rootNode.setIdWithoutRefactoring("root"); + + // act + rootNode.setAuxiliaryData(persistentFooKey, "text"); + + // assert + model.detachView(&view); + model2.attachView(&view); + ASSERT_THAT(rootNode2.auxiliaryData(), + Not(Contains(AuxiliaryProperty(AuxiliaryDataType::Persistent, "foo", "text")))); +} + +TEST_F(AuxiliaryPropertyStorageView, do_not_store_node_without_id) +{ + // arrange + model.attachView(&view); + rootNode2.setIdWithoutRefactoring("root"); + + // act + rootNode.setAuxiliaryData(persistentFooKey, "text"); + + // assert + model.detachView(&view); + model2.attachView(&view); + ASSERT_THAT(rootNode2.auxiliaryData(), + Not(Contains(AuxiliaryProperty(AuxiliaryDataType::Persistent, "foo", "text")))); +} + +TEST_F(AuxiliaryPropertyStorageView, do_not_load_from_different_document) +{ + // arrange + model2.setFileUrl(QUrl{"/path/foo2.qml"}); + model.attachView(&view); + rootNode.setIdWithoutRefactoring("root"); + rootNode2.setIdWithoutRefactoring("root"); + + // act + rootNode.setAuxiliaryData(persistentFooKey, "text"); + + // assert + model.detachView(&view); + model2.attachView(&view); + ASSERT_THAT(rootNode2.auxiliaryData(), + Not(Contains(AuxiliaryProperty(AuxiliaryDataType::Persistent, "foo", "text")))); +} + +TEST_F(AuxiliaryPropertyStorageView, removing_node_erases_entries) +{ + // arrange + auto node = model.createModelNode("Item"); + node.setIdWithoutRefactoring("node1"); + node.setAuxiliaryData(persistentFooKey, "some value"); + auto node2 = model2.createModelNode("Item"); + node2.setIdWithoutRefactoring("node1"); + model.attachView(&view); + rootNode.setIdWithoutRefactoring("root"); + rootNode2.setIdWithoutRefactoring("root"); + + // act + node.destroy(); + + // assert + model.detachView(&view); + model2.attachView(&view); + ASSERT_THAT(node2.auxiliaryData(), + Not(Contains(AuxiliaryProperty(AuxiliaryDataType::Persistent, "foo", "some value")))); +} + +TEST_F(AuxiliaryPropertyStorageView, changing_node_id_is_saving_data_under_new_id) +{ + // arrange + model.attachView(&view); + rootNode.setIdWithoutRefactoring("root"); + rootNode2.setIdWithoutRefactoring("root2"); + rootNode.setAuxiliaryData(persistentFooKey, "text"); + model.detachView(&view); + model.attachView(&view); + + // act + rootNode.setIdWithoutRefactoring("root2"); + + // assert + model.detachView(&view); + model2.attachView(&view); + ASSERT_THAT(rootNode2.auxiliaryData(), + Contains(AuxiliaryProperty(AuxiliaryDataType::Persistent, "foo", "text"))); +} + +TEST_F(AuxiliaryPropertyStorageView, changing_node_id_is_removing_data_from_old_id) +{ + // arrange + model.attachView(&view); + rootNode.setIdWithoutRefactoring("root"); + rootNode2.setIdWithoutRefactoring("root"); + rootNode.setAuxiliaryData(persistentFooKey, "text"); + model.detachView(&view); + model.attachView(&view); + + // act + rootNode.setIdWithoutRefactoring("root2"); + + // assert + model.detachView(&view); + model2.attachView(&view); + ASSERT_THAT(rootNode2.auxiliaryData(), + Not(Contains(AuxiliaryProperty(AuxiliaryDataType::Persistent, "foo", "text")))); +} +} // namespace diff --git a/tests/unit/tests/unittests/model/import-test.cpp b/tests/unit/tests/unittests/model/import-test.cpp index 695d286f376..c1ff4a6a935 100644 --- a/tests/unit/tests/unittests/model/import-test.cpp +++ b/tests/unit/tests/unittests/model/import-test.cpp @@ -4,6 +4,7 @@ #include "../utils/googletest.h" #include +#include namespace { @@ -13,7 +14,7 @@ TEST(Import, parse_version) auto version = import.toVersion(); - ASSERT_THAT(version, FieldsAre(6, 5)); + ASSERT_THAT(version, FieldsAre(6, 5, 0)); } TEST(Import, parse_major_version) @@ -97,244 +98,4 @@ TEST(Import, empty_version_string_is_empty_version) ASSERT_TRUE(version.isEmpty()); } -TEST(Import, same_versions_are_equal) -{ - QmlDesigner::Version version1{6, 5}; - QmlDesigner::Version version2{6, 5}; - - bool isEqual = version1 == version2; - - ASSERT_TRUE(isEqual); -} - -TEST(Import, invalid_versions_are_equal) -{ - QmlDesigner::Version version1; - QmlDesigner::Version version2; - - bool isEqual = version1 == version2; - - ASSERT_TRUE(isEqual); -} - -TEST(Import, different_minor_versions_are_not_equal) -{ - QmlDesigner::Version version1{6, 4}; - QmlDesigner::Version version2{6, 5}; - - bool isEqual = version1 == version2; - - ASSERT_FALSE(isEqual); -} - -TEST(Import, different_major_versions_are_not_equal) -{ - QmlDesigner::Version version1{5, 5}; - QmlDesigner::Version version2{6, 5}; - - bool isEqual = version1 == version2; - - ASSERT_FALSE(isEqual); -} - -TEST(Import, less_minor_versions_are_less) -{ - QmlDesigner::Version version1{6, 4}; - QmlDesigner::Version version2{6, 5}; - - bool isLess = version1 < version2; - - ASSERT_TRUE(isLess); -} - -TEST(Import, less_major_versions_are_less) -{ - QmlDesigner::Version version1{5, 15}; - QmlDesigner::Version version2{6, 5}; - - bool isLess = version1 < version2; - - ASSERT_TRUE(isLess); -} - -TEST(Import, same_versions_are_not_less) -{ - QmlDesigner::Version version1{6, 5}; - QmlDesigner::Version version2{6, 5}; - - bool isLess = version1 < version2; - - ASSERT_FALSE(isLess); -} - -TEST(Import, empty_version_is_not_less) -{ - QmlDesigner::Version version1; - QmlDesigner::Version version2{6, 5}; - - bool isLess = version1 < version2; - - ASSERT_FALSE(isLess); -} - -TEST(Import, non_empty_version_is_is_less_than_empty_version) -{ - QmlDesigner::Version version1{6, 5}; - QmlDesigner::Version version2; - - bool isLess = version1 < version2; - - ASSERT_TRUE(isLess); -} - -TEST(Import, greater_minor_versions_are_greater) -{ - QmlDesigner::Version version1{6, 6}; - QmlDesigner::Version version2{6, 5}; - - bool isGreater = version1 > version2; - - ASSERT_TRUE(isGreater); -} - -TEST(Import, greater_major_versions_are_greater) -{ - QmlDesigner::Version version1{6, 5}; - QmlDesigner::Version version2{5, 15}; - - bool isGreater = version1 > version2; - - ASSERT_TRUE(isGreater); -} - -TEST(Import, same_versions_are_not_greater) -{ - QmlDesigner::Version version1{6, 5}; - QmlDesigner::Version version2{6, 5}; - - bool isGreater = version1 > version2; - - ASSERT_FALSE(isGreater); -} - -TEST(Import, empty_version_is_greater) -{ - QmlDesigner::Version version1; - QmlDesigner::Version version2{6, 5}; - - bool isGreater = version1 > version2; - - ASSERT_TRUE(isGreater); -} - -TEST(Import, non_empty_version_is_is_not_greater_than_empty_version) -{ - QmlDesigner::Version version1{6, 5}; - QmlDesigner::Version version2; - - bool isGreater = version1 > version2; - - ASSERT_FALSE(isGreater); -} - -TEST(Import, less_equal_minor_versions_are_less_equal) -{ - QmlDesigner::Version version1{6, 4}; - QmlDesigner::Version version2{6, 5}; - - bool isLessEqual = version1 <= version2; - - ASSERT_TRUE(isLessEqual); -} - -TEST(Import, lessqual_major_versions_are_lessqual) -{ - QmlDesigner::Version version1{5, 15}; - QmlDesigner::Version version2{6, 5}; - - bool isLessEqual = version1 <= version2; - - ASSERT_TRUE(isLessEqual); -} - -TEST(Import, same_versions_are_lessqual) -{ - QmlDesigner::Version version1{6, 5}; - QmlDesigner::Version version2{6, 5}; - - bool isLessEqual = version1 <= version2; - - ASSERT_TRUE(isLessEqual); -} - -TEST(Import, empty_version_is_not_lessqual) -{ - QmlDesigner::Version version1; - QmlDesigner::Version version2{6, 5}; - - bool isLessEqual = version1 <= version2; - - ASSERT_FALSE(isLessEqual); -} - -TEST(Import, non_empty_version_is_is_lessqual_than_empty_version) -{ - QmlDesigner::Version version1{6, 5}; - QmlDesigner::Version version2; - - bool isLessEqual = version1 <= version2; - - ASSERT_TRUE(isLessEqual); -} - -TEST(Import, greater_equal_minor_versions_are_greater_equal) -{ - QmlDesigner::Version version1{6, 6}; - QmlDesigner::Version version2{6, 5}; - - bool isGreaterEqual = version1 >= version2; - - ASSERT_TRUE(isGreaterEqual); -} - -TEST(Import, greater_equal_major_versions_are_greater_equal) -{ - QmlDesigner::Version version1{6, 5}; - QmlDesigner::Version version2{5, 15}; - - bool isGreaterEqual = version1 >= version2; - - ASSERT_TRUE(isGreaterEqual); -} - -TEST(Import, same_versions_are_greater_equal) -{ - QmlDesigner::Version version1{6, 5}; - QmlDesigner::Version version2{6, 5}; - - bool isGreaterEqual = version1 >= version2; - - ASSERT_TRUE(isGreaterEqual); -} - -TEST(Import, empty_version_is_greater_equal) -{ - QmlDesigner::Version version1; - QmlDesigner::Version version2{6, 5}; - - bool isGreaterEqual = version1 >= version2; - - ASSERT_TRUE(isGreaterEqual); -} - -TEST(Import, non_empty_version_is_is_not_greater_equal_than_empty_version) -{ - QmlDesigner::Version version1{6, 5}; - QmlDesigner::Version version2; - - bool isGreaterEqual = version1 >= version2; - - ASSERT_FALSE(isGreaterEqual); -} - } // namespace diff --git a/tests/unit/tests/unittests/model/model-test.cpp b/tests/unit/tests/unittests/model/model-test.cpp index 227360c01f6..3c70993681f 100644 --- a/tests/unit/tests/unittests/model/model-test.cpp +++ b/tests/unit/tests/unittests/model/model-test.cpp @@ -117,7 +117,7 @@ protected: protected: NiceMock pathCacheMock{"/path/foo.qml"}; - NiceMock projectStorageMock{pathCacheMock.sourceId}; + NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; NiceMock resourceManagementMock; QmlDesigner::Imports imports = {QmlDesigner::Import::createLibraryImport("QtQuick")}; QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, @@ -764,6 +764,7 @@ TEST_F(Model, change_imports_is_synchronizing_imports_with_project_storage) ON_CALL(pathCacheMock, sourceId(Eq("/path/foo/."))).WillByDefault(Return(directoryPathId)); auto qtQuickModuleId = projectStorageMock.moduleId("QtQuick", ModuleKind::QmlLibrary); auto qtQmlModelsModuleId = projectStorageMock.moduleId("QtQml.Models", ModuleKind::QmlLibrary); + auto localPathModuleId = projectStorageMock.moduleId("/path", ModuleKind::PathLibrary); auto qtQuickImport = QmlDesigner::Import::createLibraryImport("QtQuick", "2.1"); auto qtQmlModelsImport = QmlDesigner::Import::createLibraryImport("QtQml.Models"); auto directoryImport = QmlDesigner::Import::createFileImport("foo"); @@ -771,7 +772,8 @@ TEST_F(Model, change_imports_is_synchronizing_imports_with_project_storage) EXPECT_CALL(projectStorageMock, synchronizeDocumentImports( UnorderedElementsAre(IsImport(qtQuickModuleId, filePathId, 2, 1), - IsImport(qtQmlModelsModuleId, filePathId, -1, -1)), + IsImport(qtQmlModelsModuleId, filePathId, -1, -1), + IsImport(localPathModuleId, filePathId, -1, -1)), filePathId)); model.changeImports({qtQuickImport, qtQmlModelsImport}, {}); @@ -798,6 +800,7 @@ TEST_F(Model, change_imports_is_adding_import_in_project_storage) ON_CALL(pathCacheMock, sourceId(Eq("/path/foo/."))).WillByDefault(Return(directoryPathId)); auto qtQuickModuleId = projectStorageMock.moduleId("QtQuick", ModuleKind::QmlLibrary); auto qtQmlModelsModuleId = projectStorageMock.moduleId("QtQml.Models", ModuleKind::QmlLibrary); + auto localPathModuleId = projectStorageMock.moduleId("/path", ModuleKind::PathLibrary); auto qtQuickImport = QmlDesigner::Import::createLibraryImport("QtQuick", "2.1"); auto qtQmlModelsImport = QmlDesigner::Import::createLibraryImport("QtQml.Models"); auto directoryImport = QmlDesigner::Import::createFileImport("foo"); @@ -806,7 +809,8 @@ TEST_F(Model, change_imports_is_adding_import_in_project_storage) EXPECT_CALL(projectStorageMock, synchronizeDocumentImports( UnorderedElementsAre(IsImport(qtQuickModuleId, filePathId, 2, 1), - IsImport(qtQmlModelsModuleId, filePathId, -1, -1)), + IsImport(qtQmlModelsModuleId, filePathId, -1, -1), + IsImport(localPathModuleId, filePathId, -1, -1)), filePathId)); model.changeImports({qtQuickImport}, {}); @@ -817,15 +821,17 @@ TEST_F(Model, change_imports_is_removing_import_in_project_storage) QmlDesigner::SourceId directoryPathId = QmlDesigner::SourceId::create(2); ON_CALL(pathCacheMock, sourceId(Eq("/path/foo/."))).WillByDefault(Return(directoryPathId)); auto qtQmlModelsModuleId = projectStorageMock.moduleId("QtQml.Models", ModuleKind::QmlLibrary); + auto localPathModuleId = projectStorageMock.moduleId("/path", ModuleKind::PathLibrary); auto qtQuickImport = QmlDesigner::Import::createLibraryImport("QtQuick", "2.1"); auto qtQmlModelsImport = QmlDesigner::Import::createLibraryImport("QtQml.Models"); auto directoryImport = QmlDesigner::Import::createFileImport("foo"); model.changeImports({qtQuickImport, qtQmlModelsImport}, {}); EXPECT_CALL(projectStorageMock, - synchronizeDocumentImports(UnorderedElementsAre( - IsImport(qtQmlModelsModuleId, filePathId, -1, -1)), - filePathId)); + synchronizeDocumentImports( + UnorderedElementsAre(IsImport(qtQmlModelsModuleId, filePathId, -1, -1), + IsImport(localPathModuleId, filePathId, -1, -1)), + filePathId)); model.changeImports({}, {qtQuickImport}); } @@ -851,6 +857,7 @@ TEST_F(Model, change_imports_is_changing_import_version_with_project_storage) ON_CALL(pathCacheMock, sourceId(Eq("/path/foo/."))).WillByDefault(Return(directoryPathId)); auto qtQuickModuleId = projectStorageMock.moduleId("QtQuick", ModuleKind::QmlLibrary); auto qtQmlModelsModuleId = projectStorageMock.moduleId("QtQml.Models", ModuleKind::QmlLibrary); + auto localPathModuleId = projectStorageMock.moduleId("/path", ModuleKind::PathLibrary); auto qtQuickImport = QmlDesigner::Import::createLibraryImport("QtQuick", "2.1"); auto qtQmlModelsImport = QmlDesigner::Import::createLibraryImport("QtQml.Models"); auto directoryImport = QmlDesigner::Import::createFileImport("foo"); @@ -860,7 +867,8 @@ TEST_F(Model, change_imports_is_changing_import_version_with_project_storage) EXPECT_CALL(projectStorageMock, synchronizeDocumentImports( UnorderedElementsAre(IsImport(qtQuickModuleId, filePathId, 3, 1), - IsImport(qtQmlModelsModuleId, filePathId, -1, -1)), + IsImport(qtQmlModelsModuleId, filePathId, -1, -1), + IsImport(localPathModuleId, filePathId, -1, -1)), filePathId)); model.changeImports({qtQuickImport}, {}); diff --git a/tests/unit/tests/unittests/model/modelnode-test.cpp b/tests/unit/tests/unittests/model/modelnode-test.cpp index a93a56952f7..61d81f6178f 100644 --- a/tests/unit/tests/unittests/model/modelnode-test.cpp +++ b/tests/unit/tests/unittests/model/modelnode-test.cpp @@ -16,7 +16,7 @@ class ModelNode : public testing::Test { protected: NiceMock pathCache{"/path/foo.qml"}; - NiceMock projectStorageMock{pathCache.sourceId}; + NiceMock projectStorageMock{pathCache.sourceId, "/path"}; QmlDesigner::Model model{{projectStorageMock, pathCache}, "Item"}; QmlDesigner::ModelNode rootNode = model.rootModelNode(); }; diff --git a/tests/unit/tests/unittests/model/modelresourcemanagement-test.cpp b/tests/unit/tests/unittests/model/modelresourcemanagement-test.cpp index fd3d3c70c35..b020c7cfd0d 100644 --- a/tests/unit/tests/unittests/model/modelresourcemanagement-test.cpp +++ b/tests/unit/tests/unittests/model/modelresourcemanagement-test.cpp @@ -72,7 +72,7 @@ protected: protected: NiceMock viewMock; NiceMock pathCacheMock{"/path/foo.qml"}; - NiceMock projectStorageMock{pathCacheMock.sourceId}; + NiceMock projectStorageMock{pathCacheMock.sourceId, "/path"}; QmlDesigner::ModelResourceManagement management; QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", diff --git a/tests/unit/tests/unittests/model/modelutils-test.cpp b/tests/unit/tests/unittests/model/modelutils-test.cpp deleted file mode 100644 index 2d49c6c94e6..00000000000 --- a/tests/unit/tests/unittests/model/modelutils-test.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (C) 2023 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include - -#include -#include -#include -#include -#include -#include - -namespace { -using QmlDesigner::ModelNode; -using QmlDesigner::ModelNodes; -using QmlDesigner::Storage::ModuleKind; - -class ModelUtils : public ::testing::Test -{ -protected: - NiceMock pathCacheMock{"/path/model.qml"}; - QmlDesigner::SourceId sourceId = pathCacheMock.createSourceId("/path/foo.qml"); - NiceMock projectStorageMock{pathCacheMock.sourceId}; - QmlDesigner::ModuleId moduleId = projectStorageMock.moduleId("QtQuick", ModuleKind::QmlLibrary); - QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, - "Item", - {QmlDesigner::Import::createLibraryImport("QML"), - QmlDesigner::Import::createLibraryImport("QtQuick"), - QmlDesigner::Import::createLibraryImport("QtQml.Models")}, - QUrl::fromLocalFile(pathCacheMock.path.toQString())}; -}; - -TEST_F(ModelUtils, component_file_path) -{ - QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Reference}; - traits.isFileComponent = true; - auto typeId = projectStorageMock.createType(moduleId, "Foo", traits, {}, sourceId); - QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock}; - - auto path = QmlDesigner::ModelUtils::componentFilePath(pathCacheMock, metaInfo); - - ASSERT_THAT(path, "/path/foo.qml"); -} - -TEST_F(ModelUtils, empty_component_file_path_for_non_file_component) -{ - auto typeId = projectStorageMock.createType(moduleId, "Foo", {}, {}, sourceId); - QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock}; - - auto path = QmlDesigner::ModelUtils::componentFilePath(pathCacheMock, metaInfo); - - ASSERT_THAT(path, IsEmpty()); -} - -TEST_F(ModelUtils, empty_component_file_path_for_invalid_meta_info) -{ - QmlDesigner::NodeMetaInfo metaInfo; - - auto path = QmlDesigner::ModelUtils::componentFilePath(pathCacheMock, metaInfo); - - ASSERT_THAT(path, IsEmpty()); -} - -TEST_F(ModelUtils, component_file_path_for_node) -{ - QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Reference}; - traits.isFileComponent = true; - auto typeId = projectStorageMock.createType(moduleId, "Foo", traits, {}, sourceId); - projectStorageMock.createImportedTypeNameId(pathCacheMock.sourceId, "Foo", typeId); - auto node = model.createModelNode("Foo"); - - auto path = QmlDesigner::ModelUtils::componentFilePath(node); - - ASSERT_THAT(path, "/path/foo.qml"); -} - -TEST_F(ModelUtils, component_file_path_for_invalid_node_is_empty) -{ - auto path = QmlDesigner::ModelUtils::componentFilePath(QmlDesigner::ModelNode{}); - - ASSERT_THAT(path, IsEmpty()); -} - -TEST_F(ModelUtils, component_file_path_for_node_without_metainfo_is_empty) -{ - QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Reference}; - traits.isFileComponent = true; - projectStorageMock.createType(moduleId, "Foo", traits, {}, sourceId); - auto node = model.createModelNode("Foo"); - - auto path = QmlDesigner::ModelUtils::componentFilePath(node); - - ASSERT_THAT(path, IsEmpty()); -} - -TEST_F(ModelUtils, component_file_path_for_non_file_component_node_is_empty) -{ - auto typeId = projectStorageMock.createType(moduleId, "Foo", {}, {}, sourceId); - projectStorageMock.createImportedTypeNameId(pathCacheMock.sourceId, "Foo", typeId); - auto node = model.createModelNode("Foo"); - - auto path = QmlDesigner::ModelUtils::componentFilePath(node); - - ASSERT_THAT(path, IsEmpty()); -} - -TEST_F(ModelUtils, find_lowest_common_ancestor) -{ - auto child1 = model.createModelNode("Item"); - auto child2 = model.createModelNode("Item"); - model.rootModelNode().defaultNodeAbstractProperty().reparentHere(child1); - model.rootModelNode().defaultNodeAbstractProperty().reparentHere(child2); - ModelNodes nodes{child1, child2}; - - auto commonAncestor = QmlDesigner::ModelUtils::lowestCommonAncestor(nodes); - - ASSERT_THAT(commonAncestor, model.rootModelNode()); -} - -TEST_F(ModelUtils, lowest_common_ancestor_return_invalid_node_if_argument_is_invalid) -{ - auto child1 = model.createModelNode("Item"); - auto child2 = ModelNode{}; - model.rootModelNode().defaultNodeAbstractProperty().reparentHere(child1); - ModelNodes nodes{child1, child2}; - - auto commonAncestor = QmlDesigner::ModelUtils::lowestCommonAncestor(nodes); - - ASSERT_THAT(commonAncestor, Not(IsValid())); -} - -TEST_F(ModelUtils, find_lowest_common_ancestor_when_one_of_the_nodes_is_parent) -{ - auto parentNode = model.createModelNode("Item"); - auto childNode = model.createModelNode("Item"); - parentNode.defaultNodeAbstractProperty().reparentHere(childNode); - model.rootModelNode().defaultNodeAbstractProperty().reparentHere(parentNode); - ModelNodes nodes{childNode, parentNode}; - - auto commonAncestor = QmlDesigner::ModelUtils::lowestCommonAncestor(nodes); - - ASSERT_THAT(commonAncestor, parentNode); -} - -TEST_F(ModelUtils, lowest_common_ancestor_for_uncle_and_nephew_should_return_the_grandfather) -{ - auto grandFatherNode = model.createModelNode("Item"); - auto fatherNode = model.createModelNode("Item"); - auto uncleNode = model.createModelNode("Item"); - auto nephewNode = model.createModelNode("Item"); - fatherNode.defaultNodeAbstractProperty().reparentHere(nephewNode); - grandFatherNode.defaultNodeAbstractProperty().reparentHere(fatherNode); - grandFatherNode.defaultNodeAbstractProperty().reparentHere(uncleNode); - model.rootModelNode().defaultNodeAbstractProperty().reparentHere(grandFatherNode); - ModelNodes nodes{uncleNode, nephewNode}; - - auto commonAncestor = QmlDesigner::ModelUtils::lowestCommonAncestor(nodes); - - ASSERT_THAT(commonAncestor, grandFatherNode); -} - -} // namespace diff --git a/tests/unit/tests/unittests/model/nodelistproperty-test.cpp b/tests/unit/tests/unittests/model/nodelistproperty-test.cpp index 238e2f5d158..023126f0f70 100644 --- a/tests/unit/tests/unittests/model/nodelistproperty-test.cpp +++ b/tests/unit/tests/unittests/model/nodelistproperty-test.cpp @@ -74,7 +74,7 @@ protected: protected: NiceMock pathCache{"/path/foo.qml"}; - NiceMock projectStorageMock{pathCache.sourceId}; + NiceMock projectStorageMock{pathCache.sourceId, "/path"}; QmlDesigner::ModelPointer model{ QmlDesigner::Model::create(QmlDesigner::ProjectStorageDependencies{projectStorageMock, pathCache}, diff --git a/tests/unit/tests/unittests/projectstorage/CMakeLists.txt b/tests/unit/tests/unittests/projectstorage/CMakeLists.txt index a2374ae265f..2f7aaccf7a3 100644 --- a/tests/unit/tests/unittests/projectstorage/CMakeLists.txt +++ b/tests/unit/tests/unittests/projectstorage/CMakeLists.txt @@ -15,17 +15,18 @@ extend_qtc_test(unittest ) extend_qtc_test(unittest - CONDITION TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate AND Qt6_VERSION VERSION_GREATER_EQUAL 6.5.0 AND Qt6_VERSION VERSION_LESS 6.6.0 + CONDITION TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate AND IS_SUPPORTED_PROJECTSTORAGE_QT DEPENDS Qt6::QmlDomPrivate Qt6::QmlCompilerPrivate SOURCES qmldocumentparser-test.cpp qmltypesparser-test.cpp ) + extend_qtc_test(unittest - CONDITION TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate AND Qt6_VERSION VERSION_GREATER_EQUAL 6.5.0 AND Qt6_VERSION VERSION_LESS 6.6.0 + CONDITION TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate AND IS_SUPPORTED_PROJECTSTORAGE_QT SOURCES_PREFIX "${QmlDesignerDir}/designercore" DEPENDS Qt6::QmlDomPrivate Qt6::QmlCompilerPrivate - DEFINES QDS_BUILD_QMLPARSER + DEFINES QDS_BUILD_QMLPARSER QML_DOM_MSVC2019_COMPAT # QML_DOM_MSVC2019_COMPAT can be revmoved for Qt 6.8 SOURCES projectstorage/qmldocumentparser.cpp projectstorage/qmldocumentparser.h projectstorage/qmltypesparser.cpp projectstorage/qmltypesparser.h diff --git a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp index fc806d73a95..5b9d0c8d059 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp @@ -19,8 +19,8 @@ namespace { -using QmlDesigner::Cache::Source; using QmlDesigner::Cache::SourceContext; +using QmlDesigner::Cache::SourceName; using QmlDesigner::FileStatus; using QmlDesigner::FileStatuses; using QmlDesigner::FlagIs; @@ -29,6 +29,7 @@ using QmlDesigner::PropertyDeclarationId; using QmlDesigner::SourceContextId; using QmlDesigner::SourceId; using QmlDesigner::SourceIds; +using QmlDesigner::SourceNameId; using QmlDesigner::Storage::ModuleKind; using QmlDesigner::Storage::Synchronization::SynchronizationPackage; using QmlDesigner::Storage::Synchronization::TypeAnnotations; @@ -66,18 +67,6 @@ MATCHER_P2(IsSourceContext, return sourceContext.id == id && sourceContext.value == value; } -MATCHER_P2(IsSourceNameAndSourceContextId, - name, - id, - std::string(negation ? "isn't " : "is ") - + PrintToString(QmlDesigner::Cache::SourceNameAndSourceContextId{name, id})) -{ - const QmlDesigner::Cache::SourceNameAndSourceContextId &sourceNameAndSourceContextId = arg; - - return sourceNameAndSourceContextId.sourceName == name - && sourceNameAndSourceContextId.sourceContextId == id; -} - MATCHER_P4(IsStorageType, sourceId, typeName, @@ -160,49 +149,50 @@ MATCHER_P4(IsExportedType, && type.version == Storage::Version{majorVersion, minorVersion}; } -MATCHER_P3( - IsPropertyDeclaration, - name, - propertyTypeId, - traits, - std::string(negation ? "isn't " : "is ") - + PrintToString(Storage::Synchronization::PropertyDeclaration{name, propertyTypeId, traits})) +template +auto IsPropertyDeclaration(Utils::SmallStringView name, + const PropertyTypeIdMatcher &propertyTypeIdMatcher) { - const Storage::Synchronization::PropertyDeclaration &propertyDeclaration = arg; - - return propertyDeclaration.name == name && propertyTypeId == propertyDeclaration.propertyTypeId - && propertyDeclaration.traits == traits; + return AllOf(Field(&Storage::Synchronization::PropertyDeclaration::name, name), + Field(&Storage::Synchronization::PropertyDeclaration::propertyTypeId, + propertyTypeIdMatcher)); } -MATCHER_P4(IsPropertyDeclaration, - name, - propertyTypeId, - traits, - aliasPropertyName, - std::string(negation ? "isn't " : "is ") - + PrintToString(Storage::Synchronization::PropertyDeclaration{ - name, propertyTypeId, traits, aliasPropertyName})) +template +auto IsPropertyDeclaration(Utils::SmallStringView name, + const PropertyTypeIdMatcher &propertyTypeIdMatcher, + TraitsMatcher traitsMatcher) { - const Storage::Synchronization::PropertyDeclaration &propertyDeclaration = arg; - - return propertyDeclaration.name == name && propertyTypeId == propertyDeclaration.propertyTypeId - && propertyDeclaration.aliasPropertyName == aliasPropertyName - && propertyDeclaration.traits == traits; + return AllOf(Field(&Storage::Synchronization::PropertyDeclaration::name, name), + Field(&Storage::Synchronization::PropertyDeclaration::propertyTypeId, + propertyTypeIdMatcher), + Field(&Storage::Synchronization::PropertyDeclaration::traits, traitsMatcher)); } -MATCHER_P4(IsInfoPropertyDeclaration, - typeId, - name, - traits, - propertyTypeId, - std::string(negation ? "isn't " : "is ") - + PrintToString(Storage::Info::PropertyDeclaration{typeId, name, traits, propertyTypeId})) +template +auto IsPropertyDeclaration(Utils::SmallStringView name, + const PropertyTypeIdMatcher &propertyTypeIdMatcher, + TraitsMatcher traitsMatcher, + Utils::SmallStringView aliasPropertyName) { - const Storage::Info::PropertyDeclaration &propertyDeclaration = arg; + return AllOf(Field(&Storage::Synchronization::PropertyDeclaration::name, name), + Field(&Storage::Synchronization::PropertyDeclaration::propertyTypeId, + propertyTypeIdMatcher), + Field(&Storage::Synchronization::PropertyDeclaration::traits, traitsMatcher), + Field(&Storage::Synchronization::PropertyDeclaration::aliasPropertyName, + aliasPropertyName)); +} - return propertyDeclaration.typeId == typeId && propertyDeclaration.name == name - && propertyDeclaration.propertyTypeId == propertyTypeId - && propertyDeclaration.traits == traits; +template +auto IsInfoPropertyDeclaration(TypeId typeId, + Utils::SmallStringView name, + TraitsMatcher traitsMatcher, + const PropertyTypeIdMatcher &propertyTypeIdMatcher) +{ + return AllOf(Field(&Storage::Info::PropertyDeclaration::typeId, typeId), + Field(&Storage::Info::PropertyDeclaration::name, name), + Field(&Storage::Info::PropertyDeclaration::propertyTypeId, propertyTypeIdMatcher), + Field(&Storage::Info::PropertyDeclaration::traits, traitsMatcher)); } auto IsUnresolvedTypeId() @@ -210,18 +200,52 @@ auto IsUnresolvedTypeId() return Property(&QmlDesigner::TypeId::internalId, -1); } +auto IsNullTypeId() +{ + return Property(&QmlDesigner::TypeId::isNull, true); +} + +auto IsNullPropertyDeclarationId() +{ + return Property(&QmlDesigner::PropertyDeclarationId::isNull, true); +} + template -auto IsPrototypeId(const Matcher &matcher) +auto HasPrototypeId(const Matcher &matcher) { return Field(&Storage::Synchronization::Type::prototypeId, matcher); } template -auto IsExtensionId(const Matcher &matcher) +auto HasExtensionId(const Matcher &matcher) { return Field(&Storage::Synchronization::Type::extensionId, matcher); } +template +auto PropertyDeclarations(const Matcher &matcher) +{ + return Field(&Storage::Synchronization::Type::propertyDeclarations, matcher); +} + +template +auto HasPropertyTypeId(const Matcher &matcher) +{ + return Field(&Storage::Synchronization::PropertyDeclaration::propertyTypeId, matcher); +} + +template +auto HasTypeName(const Matcher &matcher) +{ + return Field(&Storage::Synchronization::Type::typeName, matcher); +} + +template +auto HasDefaultPropertyName(const Matcher &matcher) +{ + return Field(&Storage::Synchronization::Type::defaultPropertyName, matcher); +} + class HasNameMatcher { public: @@ -317,24 +341,23 @@ protected: void addSomeDummyData() { - auto sourceContextId1 = storage.fetchSourceContextId("/path/dummy"); - auto sourceContextId2 = storage.fetchSourceContextId("/path/dummy2"); - auto sourceContextId3 = storage.fetchSourceContextId("/path/"); + storage.fetchSourceContextId("/path/dummy"); + storage.fetchSourceContextId("/path/dummy2"); + storage.fetchSourceContextId("/path/"); - storage.fetchSourceId(sourceContextId1, "foo"); - storage.fetchSourceId(sourceContextId1, "dummy"); - storage.fetchSourceId(sourceContextId2, "foo"); - storage.fetchSourceId(sourceContextId2, "bar"); - storage.fetchSourceId(sourceContextId3, "foo"); - storage.fetchSourceId(sourceContextId3, "bar"); - storage.fetchSourceId(sourceContextId1, "bar"); - storage.fetchSourceId(sourceContextId3, "bar"); + storage.fetchSourceNameId("foo"); + storage.fetchSourceNameId("dummy"); + storage.fetchSourceNameId("bar"); + storage.fetchSourceNameId("bar"); } auto createVerySimpleSynchronizationPackage() { SynchronizationPackage package; + importsSourceId1.emplace_back(qmlModuleId, Storage::Version{}, sourceId1); + importsSourceId1.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId1); + package.types.push_back(Storage::Synchronization::Type{ "QQuickItem", Storage::Synchronization::ImportedType{}, @@ -1144,6 +1167,24 @@ protected: return storage.fetchTypeIdByName(sourceId, name); } + auto fetchType(SourceId sourceId, Utils::SmallStringView name) + { + return storage.fetchTypeByTypeId(storage.fetchTypeIdByName(sourceId, name)); + } + + auto defaultPropertyDeclarationId(SourceId sourceId, Utils::SmallStringView typeName) + { + return storage.defaultPropertyDeclarationId(storage.fetchTypeIdByName(sourceId, typeName)); + } + + auto propertyDeclarationId(SourceId sourceId, + Utils::SmallStringView typeName, + Utils::SmallStringView propertyName) + { + return storage.propertyDeclarationId(storage.fetchTypeIdByName(sourceId, typeName), + propertyName); + } + static auto &findType(Storage::Synchronization::SynchronizationPackage &package, Utils::SmallStringView name) { @@ -1286,92 +1327,53 @@ TEST_F(ProjectStorage, fetch_all_source_contexts) TEST_F(ProjectStorage, fetch_source_id_first_time) { addSomeDummyData(); - auto sourceContextId = storage.fetchSourceContextId("/path/to"); - auto sourceId = storage.fetchSourceId(sourceContextId, "foo"); + auto sourceNameId = storage.fetchSourceNameId("foo"); - ASSERT_TRUE(sourceId.isValid()); + ASSERT_TRUE(sourceNameId.isValid()); } TEST_F(ProjectStorage, fetch_existing_source_id) { addSomeDummyData(); - auto sourceContextId = storage.fetchSourceContextId("/path/to"); - auto createdSourceId = storage.fetchSourceId(sourceContextId, "foo"); + auto createdSourceNameId = storage.fetchSourceNameId("foo"); - auto sourceId = storage.fetchSourceId(sourceContextId, "foo"); + auto sourceNameId = storage.fetchSourceNameId("foo"); - ASSERT_THAT(sourceId, createdSourceId); -} - -TEST_F(ProjectStorage, fetch_source_id_with_different_context_id_are_not_equal) -{ - addSomeDummyData(); - auto sourceContextId = storage.fetchSourceContextId("/path/to"); - auto sourceContextId2 = storage.fetchSourceContextId("/path/to2"); - auto sourceId2 = storage.fetchSourceId(sourceContextId2, "foo"); - - auto sourceId = storage.fetchSourceId(sourceContextId, "foo"); - - ASSERT_THAT(sourceId, Ne(sourceId2)); + ASSERT_THAT(sourceNameId, createdSourceNameId); } TEST_F(ProjectStorage, fetch_source_id_with_different_name_are_not_equal) { addSomeDummyData(); - auto sourceContextId = storage.fetchSourceContextId("/path/to"); - auto sourceId2 = storage.fetchSourceId(sourceContextId, "foo"); + auto sourceNameId2 = storage.fetchSourceNameId("foo"); - auto sourceId = storage.fetchSourceId(sourceContextId, "foo2"); + auto sourceNameId = storage.fetchSourceNameId("foo2"); - ASSERT_THAT(sourceId, Ne(sourceId2)); -} - -TEST_F(ProjectStorage, fetch_source_id_with_non_existing_source_context_id_throws) -{ - ASSERT_THROW(storage.fetchSourceId(SourceContextId::create(42), "foo"), - Sqlite::ConstraintPreventsModification); + ASSERT_THAT(sourceNameId, Ne(sourceNameId2)); } TEST_F(ProjectStorage, fetch_source_name_and_source_context_id_for_non_existing_source_id) { - ASSERT_THROW(storage.fetchSourceNameAndSourceContextId(SourceId::create(212)), - QmlDesigner::SourceIdDoesNotExists); + ASSERT_THROW(storage.fetchSourceName(SourceNameId::create(212)), + QmlDesigner::SourceNameIdDoesNotExists); } -TEST_F(ProjectStorage, fetch_source_name_and_source_context_id_for_non_existing_entry) +TEST_F(ProjectStorage, fetch_source_name_for_non_existing_entry) { addSomeDummyData(); - auto sourceContextId = storage.fetchSourceContextId("/path/to"); - auto sourceId = storage.fetchSourceId(sourceContextId, "foo"); + auto sourceNameId = storage.fetchSourceNameId("foo"); - auto sourceNameAndSourceContextId = storage.fetchSourceNameAndSourceContextId(sourceId); + auto sourceName = storage.fetchSourceName(sourceNameId); - ASSERT_THAT(sourceNameAndSourceContextId, IsSourceNameAndSourceContextId("foo", sourceContextId)); -} - -TEST_F(ProjectStorage, fetch_source_context_id_for_non_existing_source_id) -{ - ASSERT_THROW(storage.fetchSourceContextId(SourceId::create(212)), - QmlDesigner::SourceIdDoesNotExists); -} - -TEST_F(ProjectStorage, fetch_source_context_id_for_existing_source_id) -{ - addSomeDummyData(); - auto originalSourceContextId = storage.fetchSourceContextId("/path/to3"); - auto sourceId = storage.fetchSourceId(originalSourceContextId, "foo"); - - auto sourceContextId = storage.fetchSourceContextId(sourceId); - - ASSERT_THAT(sourceContextId, Eq(originalSourceContextId)); + ASSERT_THAT(sourceName, Eq("foo")); } TEST_F(ProjectStorage, fetch_all_sources) { storage.clearSources(); - auto sources = storage.fetchAllSources(); + auto sources = storage.fetchAllSourceNames(); ASSERT_THAT(toValues(sources), IsEmpty()); } @@ -1379,10 +1381,9 @@ TEST_F(ProjectStorage, fetch_all_sources) TEST_F(ProjectStorage, fetch_source_id_unguarded_first_time) { addSomeDummyData(); - auto sourceContextId = storage.fetchSourceContextId("/path/to"); std::lock_guard lock{database}; - auto sourceId = storage.fetchSourceIdUnguarded(sourceContextId, "foo"); + auto sourceId = storage.fetchSourceNameIdUnguarded("foo"); ASSERT_TRUE(sourceId.isValid()); } @@ -1390,48 +1391,25 @@ TEST_F(ProjectStorage, fetch_source_id_unguarded_first_time) TEST_F(ProjectStorage, fetch_existing_source_id_unguarded) { addSomeDummyData(); - auto sourceContextId = storage.fetchSourceContextId("/path/to"); std::lock_guard lock{database}; - auto createdSourceId = storage.fetchSourceIdUnguarded(sourceContextId, "foo"); + auto createdSourceId = storage.fetchSourceNameIdUnguarded("foo"); - auto sourceId = storage.fetchSourceIdUnguarded(sourceContextId, "foo"); + auto sourceId = storage.fetchSourceNameIdUnguarded("foo"); ASSERT_THAT(sourceId, createdSourceId); } -TEST_F(ProjectStorage, fetch_source_id_unguarded_with_different_context_id_are_not_equal) -{ - addSomeDummyData(); - auto sourceContextId = storage.fetchSourceContextId("/path/to"); - auto sourceContextId2 = storage.fetchSourceContextId("/path/to2"); - std::lock_guard lock{database}; - auto sourceId2 = storage.fetchSourceIdUnguarded(sourceContextId2, "foo"); - - auto sourceId = storage.fetchSourceIdUnguarded(sourceContextId, "foo"); - - ASSERT_THAT(sourceId, Ne(sourceId2)); -} - TEST_F(ProjectStorage, fetch_source_id_unguarded_with_different_name_are_not_equal) { addSomeDummyData(); - auto sourceContextId = storage.fetchSourceContextId("/path/to"); std::lock_guard lock{database}; - auto sourceId2 = storage.fetchSourceIdUnguarded(sourceContextId, "foo"); + auto sourceId2 = storage.fetchSourceNameIdUnguarded("foo"); - auto sourceId = storage.fetchSourceIdUnguarded(sourceContextId, "foo2"); + auto sourceId = storage.fetchSourceNameIdUnguarded("foo2"); ASSERT_THAT(sourceId, Ne(sourceId2)); } -TEST_F(ProjectStorage, fetch_source_id_unguarded_with_non_existing_source_context_id_throws) -{ - std::lock_guard lock{database}; - - ASSERT_THROW(storage.fetchSourceIdUnguarded(SourceContextId::create(42), "foo"), - Sqlite::ConstraintPreventsModification); -} - TEST_F(ProjectStorage, synchronize_types_adds_new_types) { auto package{createSimpleSynchronizationPackage()}; @@ -1549,8 +1527,7 @@ TEST_F(ProjectStorage, synchronize_types_adds_unknown_prototype_as_unresolved_ty storage.synchronize(std::move(package)); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - IsPrototypeId(IsUnresolvedTypeId())); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasPrototypeId(IsUnresolvedTypeId())); } TEST_F(ProjectStorage, synchronize_types_updates_unresolved_prototype_after_exported_type_name_is_added) @@ -1562,8 +1539,7 @@ TEST_F(ProjectStorage, synchronize_types_updates_unresolved_prototype_after_expo storage.synchronize(std::move(package)); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - IsPrototypeId(fetchTypeId(sourceId2, "QObject"))); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasPrototypeId(fetchTypeId(sourceId2, "QObject"))); } TEST_F(ProjectStorage, @@ -1577,8 +1553,7 @@ TEST_F(ProjectStorage, storage.synchronize(std::move(package)); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - IsPrototypeId(IsUnresolvedTypeId())); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasPrototypeId(IsUnresolvedTypeId())); } TEST_F(ProjectStorage, @@ -1593,8 +1568,7 @@ TEST_F(ProjectStorage, storage.synchronize(std::move(package)); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - IsPrototypeId(fetchTypeId(sourceId2, "QObject"))); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasPrototypeId(fetchTypeId(sourceId2, "QObject"))); } TEST_F(ProjectStorage, @@ -1610,8 +1584,7 @@ TEST_F(ProjectStorage, storage.synchronize(std::move(package)); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - IsPrototypeId(IsUnresolvedTypeId())); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasPrototypeId(IsUnresolvedTypeId())); } TEST_F(ProjectStorage, @@ -1639,8 +1612,7 @@ TEST_F(ProjectStorage, synchronize_types_updates_unresolved_extension_after_expo storage.synchronize(std::move(package)); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - IsExtensionId(fetchTypeId(sourceId2, "QObject"))); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasExtensionId(fetchTypeId(sourceId2, "QObject"))); } TEST_F(ProjectStorage, @@ -1654,8 +1626,7 @@ TEST_F(ProjectStorage, storage.synchronize(std::move(package)); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - IsExtensionId(IsUnresolvedTypeId())); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasExtensionId(IsUnresolvedTypeId())); } TEST_F(ProjectStorage, @@ -1670,8 +1641,7 @@ TEST_F(ProjectStorage, storage.synchronize(std::move(package)); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - IsExtensionId(fetchTypeId(sourceId2, "QObject"))); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasExtensionId(fetchTypeId(sourceId2, "QObject"))); } TEST_F(ProjectStorage, @@ -1687,8 +1657,7 @@ TEST_F(ProjectStorage, storage.synchronize(std::move(package)); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - IsExtensionId(IsUnresolvedTypeId())); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasExtensionId(IsUnresolvedTypeId())); } TEST_F(ProjectStorage, @@ -2119,27 +2088,80 @@ TEST_F(ProjectStorage, update_exported_types_if_type_name_changes) "QQuickItem")))))); } -TEST_F(ProjectStorage, breaking_prototype_chain_by_deleting_base_component_throws) +TEST_F(ProjectStorage, + breaking_prototype_chain_by_deleting_base_component_notifies_unresolved_type_name) { - auto package{createSimpleSynchronizationPackage()}; + auto package{createVerySimpleSynchronizationPackage()}; + package.types[0].prototype = Storage::Synchronization::ImportedType{"Object"}; storage.synchronize(package); - ASSERT_THROW(storage.synchronize(SynchronizationPackage{importsSourceId1, - {package.types[0]}, - {sourceId1, sourceId2}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId1)); + + storage.synchronize( + SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1, sourceId2}}); } -TEST_F(ProjectStorage, breaking_extension_chain_by_deleting_base_component_throws) +TEST_F(ProjectStorage, breaking_prototype_chain_by_deleting_base_component_has_unresolved_type_name) { - auto package{createSimpleSynchronizationPackage()}; - std::swap(package.types.front().extension, package.types.front().prototype); + auto package{createVerySimpleSynchronizationPackage()}; + package.types[0].prototype = Storage::Synchronization::ImportedType{"Object"}; storage.synchronize(package); - ASSERT_THROW(storage.synchronize(SynchronizationPackage{importsSourceId1, - {package.types[0]}, - {sourceId1, sourceId2}}), - QmlDesigner::TypeNameDoesNotExists); + storage.synchronize( + SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1, sourceId2}}); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasPrototypeId(IsUnresolvedTypeId())); +} + +TEST_F(ProjectStorage, repairing_prototype_chain_by_fixing_base_component) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.types[0].prototype = Storage::Synchronization::ImportedType{"Object"}; + storage.synchronize(package); + storage.synchronize( + SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1, sourceId2}}); + + storage.synchronize(SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasPrototypeId(fetchTypeId(sourceId2, "QObject"))); +} + +TEST_F(ProjectStorage, + breaking_extension_chain_by_deleting_base_component_notifies_unresolved_type_name) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.types[0].extension = Storage::Synchronization::ImportedType{"Object"}; + storage.synchronize(package); + + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId1)); + + storage.synchronize( + SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1, sourceId2}}); +} + +TEST_F(ProjectStorage, breaking_extension_chain_by_deleting_base_component_has_unresolved_type_name) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.types[0].extension = Storage::Synchronization::ImportedType{"Object"}; + storage.synchronize(package); + + storage.synchronize( + SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1, sourceId2}}); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasExtensionId(IsUnresolvedTypeId())); +} + +TEST_F(ProjectStorage, repairing_extension_chain_by_fixing_base_component) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.types[0].extension = Storage::Synchronization::ImportedType{"Object"}; + storage.synchronize(package); + storage.synchronize( + SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1, sourceId2}}); + + storage.synchronize(SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasExtensionId(fetchTypeId(sourceId2, "QObject"))); } TEST_F(ProjectStorage, synchronize_types_add_property_declarations) @@ -2166,12 +2188,39 @@ TEST_F(ProjectStorage, synchronize_types_add_property_declarations) | Storage::PropertyDeclarationTraits::IsReadOnly)))))); } -TEST_F(ProjectStorage, synchronize_types_add_property_declarations_with_missing_imports) +TEST_F(ProjectStorage, + synchronize_adds_property_declarations_with_missing_imports_notifies_unresolved_type_name) { auto package{createSimpleSynchronizationPackage()}; package.imports.clear(); - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Item"), sourceId1)); + + storage.synchronize(package); +} + +TEST_F(ProjectStorage, synchronize_adds_property_declarations_with_missing_imports_has_null_type_id) +{ + auto package{createSimpleSynchronizationPackage()}; + package.imports.clear(); + + storage.synchronize(package); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations(Contains(HasPropertyTypeId(IsNullTypeId())))); +} + +TEST_F(ProjectStorage, synchronize_fixes_unresolved_property_declarations_with_missing_imports) +{ + auto package{createSimpleSynchronizationPackage()}; + package.imports.clear(); + storage.synchronize(package); + + storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}}); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations( + Contains(IsPropertyDeclaration("data", fetchTypeId(sourceId2, "QObject"))))); } TEST_F(ProjectStorage, synchronize_types_add_property_declaration_qualified_type) @@ -2359,40 +2408,141 @@ TEST_F(ProjectStorage, synchronize_types_rename_a_property_declaration) | Storage::PropertyDeclarationTraits::IsReadOnly)))))); } -TEST_F(ProjectStorage, using_non_existing_property_type_throws) +TEST_F(ProjectStorage, using_non_existing_property_type_notifies_unresolved_type_name) { - auto package{createSimpleSynchronizationPackage()}; - package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::ImportedType{ - "QObject2"}; - package.types.pop_back(); - package.imports = importsSourceId1; + auto package{createVerySimpleSynchronizationPackage()}; + package.types[0].propertyDeclarations.emplace_back("data", + Storage::Synchronization::ImportedType{ + "QObject2"}, + Storage::PropertyDeclarationTraits::IsList); - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("QObject2"), sourceId1)); + + storage.synchronize(package); } -TEST_F(ProjectStorage, using_non_existing_qualified_exported_property_type_with_wrong_name_throws) +TEST_F(ProjectStorage, using_non_existing_property_type_has_null_type_id) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.types[0].propertyDeclarations.emplace_back("data", + Storage::Synchronization::ImportedType{ + "QObject2"}, + Storage::PropertyDeclarationTraits::IsList); + + storage.synchronize(package); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations(Contains(HasPropertyTypeId(IsNullTypeId())))); +} + +TEST_F(ProjectStorage, resolve_type_id_after_fixing_non_existing_property_type) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.types[0].propertyDeclarations.emplace_back("data", + Storage::Synchronization::ImportedType{ + "QObject2"}, + Storage::PropertyDeclarationTraits::IsList); + storage.synchronize(package); + package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::ImportedType{ + "Object"}; + + storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}}); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations(Contains(HasPropertyTypeId(fetchTypeId(sourceId2, "QObject"))))); +} + +TEST_F(ProjectStorage, + using_non_existing_qualified_exported_property_type_with_wrong_name_notifies_unresovled_type_name) { auto package{createSimpleSynchronizationPackage()}; package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ "QObject2", Storage::Import{qmlNativeModuleId, Storage::Version{}, sourceId1}}; - package.types.pop_back(); - package.imports = importsSourceId1; - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("QObject2"), sourceId1)); + + storage.synchronize(package); } -TEST_F(ProjectStorage, using_non_existing_qualified_exported_property_type_with_wrong_module_throws) +TEST_F(ProjectStorage, + using_non_existing_qualified_exported_property_type_with_wrong_name_has_null_type_id) { auto package{createSimpleSynchronizationPackage()}; package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ - "QObject", Storage::Import{qmlModuleId, Storage::Version{}, sourceId1}}; + "QObject2", Storage::Import{qmlNativeModuleId, Storage::Version{}, sourceId1}}; + + storage.synchronize(package); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations(Contains(HasPropertyTypeId(IsNullTypeId())))); +} + +TEST_F(ProjectStorage, resolve_type_id_after_fixing_non_existing_qualified_property_type) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ + "QObject2", Storage::Import{qmlNativeModuleId, Storage::Version{}, sourceId1}}; + storage.synchronize(package); + package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ + "QObject", Storage::Import{qmlNativeModuleId, Storage::Version{}, sourceId1}}; + + storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}}); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations( + Contains(IsPropertyDeclaration("data", fetchTypeId(sourceId2, "QObject"))))); +} + +TEST_F(ProjectStorage, + using_non_existing_qualified_exported_property_type_with_wrong_module_notifies_unresovled_type_name) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].prototype = {}; + package.types[0].propertyDeclarations.pop_back(); + package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ + "Object", Storage::Import{qmlNativeModuleId, Storage::Version{}, sourceId1}}; package.types.pop_back(); package.imports = importsSourceId1; - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId1)); + + storage.synchronize(package); } -TEST_F(ProjectStorage, breaking_property_declaration_type_dependency_by_deleting_type_throws) +TEST_F(ProjectStorage, + using_non_existing_qualified_exported_property_type_with_wrong_module_has_null_type_id) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ + "Object", Storage::Import{qmlNativeModuleId, Storage::Version{}, sourceId1}}; + package.types.pop_back(); + package.imports = importsSourceId1; + + storage.synchronize(package); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations(Contains(HasPropertyTypeId(IsNullTypeId())))); +} + +TEST_F(ProjectStorage, resolve_qualified_exported_property_type_with_fixed_module) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ + "Object", Storage::Import{qmlNativeModuleId, Storage::Version{}, sourceId1}}; + package.types.pop_back(); + package.imports = importsSourceId1; + storage.synchronize(package); + package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ + "Object", Storage::Import{qmlModuleId, Storage::Version{}, sourceId1}}; + + storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}}); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations(Contains(HasPropertyTypeId(IsNullTypeId())))); +} + +TEST_F(ProjectStorage, + breaking_property_declaration_type_dependency_by_deleting_type_nofifies_unresolved_type_name) { auto package{createSimpleSynchronizationPackage()}; storage.synchronize(package); @@ -2400,7 +2550,40 @@ TEST_F(ProjectStorage, breaking_property_declaration_type_dependency_by_deleting package.types.pop_back(); package.imports = importsSourceId1; - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("QObject"), sourceId1)); + + storage.synchronize(package); +} + +TEST_F(ProjectStorage, breaking_property_declaration_type_dependency_by_deleting_type_has_null_type_id) +{ + auto package{createSimpleSynchronizationPackage()}; + storage.synchronize(package); + package.types[0].prototype = Storage::Synchronization::ImportedType{}; + package.types.pop_back(); + package.imports = importsSourceId1; + + storage.synchronize(package); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations(Contains(IsPropertyDeclaration("data", IsNullTypeId())))); +} + +TEST_F(ProjectStorage, fixing_broken_property_declaration_type_dependenc_has_valid_id) +{ + auto package{createSimpleSynchronizationPackage()}; + storage.synchronize(package); + package.types[0].prototype = Storage::Synchronization::ImportedType{}; + auto objectType = package.types.back(); + package.types.pop_back(); + package.imports = importsSourceId1; + storage.synchronize(package); + + storage.synchronize({{importsSourceId2}, {objectType}, {sourceId2}}); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations( + Contains(IsPropertyDeclaration("data", fetchTypeId(sourceId2, "QObject"))))); } TEST_F(ProjectStorage, synchronize_types_add_function_declarations) @@ -3224,31 +3407,87 @@ TEST_F(ProjectStorage, synchronize_types_remove_alias_declarations) Storage::PropertyDeclarationTraits::IsList)))))); } -TEST_F(ProjectStorage, synchronize_types_add_alias_declarations_throws_for_wrong_type_name) +TEST_F(ProjectStorage, + synchronize_types_add_alias_declarations_notifies_unresolved_type_name_for_wrong_type) { auto package{createSynchronizationPackageWithAliases()}; package.types[2].propertyDeclarations[1].typeName = Storage::Synchronization::ImportedType{ "QQuickItemWrong"}; - ASSERT_THROW(storage.synchronize(SynchronizationPackage{importsSourceId4, - {package.types[2]}, - {sourceId4}, - moduleDependenciesSourceId4, - {sourceId4}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("QQuickItemWrong"), sourceId3)); + + storage.synchronize(package); } -TEST_F(ProjectStorage, synchronize_types_add_alias_declarations_throws_for_wrong_property_name) +TEST_F(ProjectStorage, synchronize_types_add_alias_declarations_set_null_type_id_for_wrong_type) +{ + auto package{createSynchronizationPackageWithAliases()}; + package.types[2].propertyDeclarations[1].typeName = Storage::Synchronization::ImportedType{ + "QQuickItemWrong"}; + + storage.synchronize(package); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations(Contains(IsPropertyDeclaration("items", IsNullTypeId())))); +} + +TEST_F(ProjectStorage, synchronize_types_fixes_null_type_id_after_add_alias_declarations_for_wrong_type) +{ + auto package{createSynchronizationPackageWithAliases()}; + package.types[2].propertyDeclarations[1].typeName = Storage::Synchronization::ImportedType{ + "QQuickItemWrong"}; + storage.synchronize(package); + package.types[2].propertyDeclarations[1].typeName = Storage::Synchronization::ImportedType{ + "QQuickItem"}; + + storage.synchronize( + {moduleDependenciesSourceId3 + importsSourceId3, {package.types[2]}, {sourceId3}}); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations( + Contains(IsPropertyDeclaration("items", fetchTypeId(sourceId1, "QQuickItem"))))); +} + +TEST_F(ProjectStorage, synchronize_types_add_alias_declarations_notifies_error_for_wrong_property_name) { auto package{createSynchronizationPackageWithAliases()}; package.types[2].propertyDeclarations[1].aliasPropertyName = "childrenWrong"; - ASSERT_THROW(storage.synchronize(SynchronizationPackage{package.imports, - package.types, - {sourceId4}, - package.moduleDependencies, - {sourceId4}}), - QmlDesigner::PropertyNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, propertyNameDoesNotExists(Eq("childrenWrong"), sourceId3)) + .Times(AtLeast(1)); + + storage.synchronize( + {package.imports, package.types, {sourceId4}, package.moduleDependencies, {sourceId4}}); +} + +TEST_F(ProjectStorage, + synchronize_types_add_alias_declarations_returns_invalid_type_for_wrong_property_name) +{ + auto package{createSynchronizationPackageWithAliases()}; + package.types[2].propertyDeclarations[1].aliasPropertyName = "childrenWrong"; + + storage.synchronize( + {package.imports, package.types, {sourceId4}, package.moduleDependencies, {sourceId4}}); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations(Contains(IsPropertyDeclaration("items", IsNullTypeId())))); +} + +TEST_F(ProjectStorage, + synchronize_types_update_alias_declarations_returns_item_type_for_fixed_property_name) +{ + auto package{createSynchronizationPackageWithAliases()}; + package.types[2].propertyDeclarations[1].aliasPropertyName = "childrenWrong"; + storage.synchronize( + {package.imports, package.types, {sourceId4}, package.moduleDependencies, {sourceId4}}); + package.types[2].propertyDeclarations[1].aliasPropertyName = "children"; + + storage.synchronize( + {importsSourceId3 + moduleDependenciesSourceId3, {package.types[2]}, {sourceId3}}); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations( + Contains(IsPropertyDeclaration("items", fetchTypeId(sourceId1, "QQuickItem"))))); } TEST_F(ProjectStorage, synchronize_types_change_alias_declarations_type_name) @@ -3478,7 +3717,8 @@ TEST_F(ProjectStorage, synchronize_types_remove_property_declaration_and_alias) Storage::PropertyDeclarationTraits::IsList)))))); } -TEST_F(ProjectStorage, synchronize_types_remove_type_with_alias_target_property_declaration_throws) +TEST_F(ProjectStorage, + synchronize_remove_type_with_alias_target_property_declaration_nofifies_unresolved_type_name) { auto package{createSynchronizationPackageWithAliases()}; package.types[2].propertyDeclarations[2].typeName = Storage::Synchronization::ImportedType{ @@ -3486,8 +3726,42 @@ TEST_F(ProjectStorage, synchronize_types_remove_type_with_alias_target_property_ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId3); storage.synchronize(package); - ASSERT_THROW(storage.synchronize(SynchronizationPackage{{sourceId4}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object2"), sourceId3)); + + storage.synchronize(SynchronizationPackage{{sourceId4}}); +} + +TEST_F(ProjectStorage, + synchronize_remove_type_with_alias_target_property_declaration_set_unresolved_type_id) +{ + auto package{createSynchronizationPackageWithAliases()}; + package.types[2].propertyDeclarations[2].typeName = Storage::Synchronization::ImportedType{ + "Object2"}; + package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId3); + storage.synchronize(package); + + storage.synchronize(SynchronizationPackage{{sourceId4}}); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations(Contains(IsPropertyDeclaration("objects", IsNullTypeId())))); +} + +TEST_F(ProjectStorage, synchronize_fixes_type_with_alias_target_property_declaration) +{ + auto package{createSynchronizationPackageWithAliases()}; + package.types[2].propertyDeclarations[2].typeName = Storage::Synchronization::ImportedType{ + "Object2"}; + package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId3); + storage.synchronize(package); + storage.synchronize(SynchronizationPackage{{sourceId4}}); + + storage.synchronize(SynchronizationPackage{importsSourceId4 + moduleDependenciesSourceId4, + {package.types[3]}, + {sourceId4}}); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations( + Contains(IsPropertyDeclaration("objects", fetchTypeId(sourceId2, "QObject"))))); } TEST_F(ProjectStorage, synchronize_types_remove_type_and_alias_property_declaration) @@ -3659,9 +3933,51 @@ TEST_F(ProjectStorage, do_not_relink_alias_property_for_qualified_imported_type_ package.types[3].exportedTypes[0].moduleId = qtQuickModuleId; importsSourceId4.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId4); - ASSERT_THROW(storage.synchronize( - SynchronizationPackage{importsSourceId4, {package.types[3]}, {sourceId4}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object2"), sourceId2)); + + storage.synchronize(SynchronizationPackage{importsSourceId4 + moduleDependenciesSourceId4, + {package.types[3]}, + {sourceId4}}); +} + +TEST_F(ProjectStorage, not_relinked_alias_property_for_qualified_imported_type_name_has_null_type_id) +{ + auto package{createSynchronizationPackageWithAliases()}; + package.types[1].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ + "Object2", Storage::Import{pathToModuleId, Storage::Version{}, sourceId2}}; + package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2); + storage.synchronize(package); + package.types[3].exportedTypes[0].moduleId = qtQuickModuleId; + importsSourceId4.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId4); + + storage.synchronize(SynchronizationPackage{importsSourceId4 + moduleDependenciesSourceId4, + {package.types[3]}, + {sourceId4}}); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations(Contains(IsPropertyDeclaration("objects", IsNullTypeId())))); +} + +TEST_F(ProjectStorage, + relinked_alias_property_for_qualified_imported_type_name_after_alias_chain_was_fixed) +{ + auto package{createSynchronizationPackageWithAliases()}; + package.types[1].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ + "Object2", Storage::Import{pathToModuleId, Storage::Version{}, sourceId2}}; + package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2); + storage.synchronize(package); + package.types[3].exportedTypes[0].moduleId = qtQuickModuleId; + importsSourceId4.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId4); + storage.synchronize(SynchronizationPackage{importsSourceId4, {package.types[3]}, {sourceId4}}); + package.types[3].exportedTypes[0].moduleId = pathToModuleId; + + storage.synchronize(SynchronizationPackage{importsSourceId4 + moduleDependenciesSourceId4, + {package.types[3]}, + {sourceId4}}); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations( + Contains(IsPropertyDeclaration("objects", fetchTypeId(sourceId4, "QObject2"))))); } TEST_F(ProjectStorage, @@ -3799,7 +4115,7 @@ TEST_F(ProjectStorage, do_not_relink_alias_property_for_deleted_type_and_propert TypeTraitsKind::Reference)))); } -TEST_F(ProjectStorage, do_not_relink_property_type_does_not_exists) +TEST_F(ProjectStorage, do_not_relink_property_type_does_not_exists_notifies_unresolved_type_name) { auto package{createSynchronizationPackageWithAliases()}; package.types[1].propertyDeclarations[0].typeName = Storage::Synchronization::ImportedType{ @@ -3808,11 +4124,63 @@ TEST_F(ProjectStorage, do_not_relink_property_type_does_not_exists) package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId2); storage.synchronize(package); - ASSERT_THROW(storage.synchronize(SynchronizationPackage{{sourceId4}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object2"), sourceId2)); + + storage.synchronize(SynchronizationPackage{{sourceId4}}); } -TEST_F(ProjectStorage, do_not_relink_alias_property_type_does_not_exists) +TEST_F(ProjectStorage, not_relinked_property_type_has_null_type_id) +{ + auto package{createSynchronizationPackageWithAliases()}; + package.types[1].propertyDeclarations[0].typeName = Storage::Synchronization::ImportedType{ + "Object2"}; + package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2); + package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId2); + storage.synchronize(package); + + storage.synchronize({{sourceId4}}); + + ASSERT_THAT(fetchType(sourceId2, "QObject"), + PropertyDeclarations(Contains(IsPropertyDeclaration("objects", IsNullTypeId())))); +} + +TEST_F(ProjectStorage, not_relinked_property_type_fixed_after_adding_property_type_again) +{ + auto package{createSynchronizationPackageWithAliases()}; + package.types[1].propertyDeclarations[0].typeName = Storage::Synchronization::ImportedType{ + "Object2"}; + package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2); + package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId2); + storage.synchronize(package); + storage.synchronize({{sourceId4}}); + + storage.synchronize( + {importsSourceId4 + moduleDependenciesSourceId4, {package.types[3]}, {sourceId4}}); + + ASSERT_THAT(fetchType(sourceId2, "QObject"), + PropertyDeclarations( + Contains(IsPropertyDeclaration("objects", fetchTypeId(sourceId4, "QObject2"))))); +} + +TEST_F(ProjectStorage, not_relinked_property_type_fixed_after_type_is_added_again) +{ + auto package{createSynchronizationPackageWithAliases()}; + package.types[1].propertyDeclarations[0].typeName = Storage::Synchronization::ImportedType{ + "Object2"}; + package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2); + package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId2); + storage.synchronize(package); + storage.synchronize({{sourceId4}}); + + storage.synchronize( + {importsSourceId4 + moduleDependenciesSourceId4, {package.types[3]}, {sourceId4}}); + + ASSERT_THAT(fetchType(sourceId2, "QObject"), + PropertyDeclarations( + Contains(IsPropertyDeclaration("objects", fetchTypeId(sourceId4, "QObject2"))))); +} + +TEST_F(ProjectStorage, do_not_relink_alias_property_type_does_not_exists_notifies_unresolved_type_name) { auto package{createSynchronizationPackageWithAliases2()}; package.types[1].propertyDeclarations[0].typeName = Storage::Synchronization::ImportedType{ @@ -3820,8 +4188,40 @@ TEST_F(ProjectStorage, do_not_relink_alias_property_type_does_not_exists) package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2); storage.synchronize(package); - ASSERT_THROW(storage.synchronize(SynchronizationPackage{{sourceId1}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Item"), sourceId3)); + + storage.synchronize(SynchronizationPackage{{sourceId1}}); +} + +TEST_F(ProjectStorage, not_relinked_alias_property_type_has_null_type_id) +{ + auto package{createSynchronizationPackageWithAliases2()}; + package.types[1].propertyDeclarations[0].typeName = Storage::Synchronization::ImportedType{ + "Object2"}; + package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2); + storage.synchronize(package); + + storage.synchronize(SynchronizationPackage{{sourceId1}}); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations(Contains(IsPropertyDeclaration("objects", IsNullTypeId())))); +} + +TEST_F(ProjectStorage, not_relinked_alias_property_type_fixed_after_referenced_type_is_added_again) +{ + auto package{createSynchronizationPackageWithAliases2()}; + package.types[1].propertyDeclarations[0].typeName = Storage::Synchronization::ImportedType{ + "Object2"}; + package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2); + storage.synchronize(package); + storage.synchronize({{sourceId1}}); + + storage.synchronize( + {importsSourceId1 + moduleDependenciesSourceId1, {package.types[0]}, {sourceId1}}); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations( + Contains(IsPropertyDeclaration("objects", fetchTypeId(sourceId4, "QObject2"))))); } TEST_F(ProjectStorage, change_prototype_type_name) @@ -4620,13 +5020,45 @@ TEST_F(ProjectStorage, qualified_property_declaration_type_name) Storage::PropertyDeclarationTraits::IsList))))); } -TEST_F(ProjectStorage, qualified_property_declaration_type_name_down_the_module_chain_throws) +TEST_F(ProjectStorage, + qualified_property_declaration_type_name_down_the_module_chain_nofifies_unresolved_type_name) { auto package{createSimpleSynchronizationPackage()}; package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ - "Object", Storage::Import{qtQuickModuleId, Storage::Version{}, sourceId1}}; + "Obj", Storage::Import{qtQuickModuleId, Storage::Version{}, sourceId1}}; - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Obj"), sourceId1)); + + storage.synchronize(package); +} + +TEST_F(ProjectStorage, + qualified_property_declaration_type_name_down_the_module_chain_has_null_type_name) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ + "Obj", Storage::Import{qtQuickModuleId, Storage::Version{}, sourceId1}}; + + storage.synchronize(package); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations(Contains(HasPropertyTypeId(IsNullTypeId())))); +} + +TEST_F(ProjectStorage, borken_qualified_property_declaration_type_name_down_the_module_chain_fixed) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ + "Obj", Storage::Import{qtQuickModuleId, Storage::Version{}, sourceId1}}; + storage.synchronize(package); + package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ + "Obj", Storage::Import{qmlModuleId, Storage::Version{}, sourceId1}}; + + storage.synchronize( + {importsSourceId1 + moduleDependenciesSourceId1, {package.types[0]}, {sourceId1}}); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations(Not(Contains(HasPropertyTypeId(IsNullTypeId()))))); } TEST_F(ProjectStorage, qualified_property_declaration_type_name_in_the_module_chain) @@ -4672,7 +5104,7 @@ TEST_F(ProjectStorage, qualified_property_declaration_type_name_with_version) Storage::PropertyDeclarationTraits::IsList))))); } -TEST_F(ProjectStorage, change_property_type_module_id_with_qualified_type_throws) +TEST_F(ProjectStorage, change_property_type_module_id_with_qualified_type_notifies_unresolved_type_name) { auto package{createSimpleSynchronizationPackage()}; package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ @@ -4680,9 +5112,48 @@ TEST_F(ProjectStorage, change_property_type_module_id_with_qualified_type_throws storage.synchronize(package); package.types[1].exportedTypes[0].moduleId = qtQuickModuleId; - ASSERT_THROW(storage.synchronize( - SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId1)); + + storage.synchronize(SynchronizationPackage{importsSourceId2 + moduleDependenciesSourceId2, + {package.types[1]}, + {sourceId2}}); +} + +TEST_F(ProjectStorage, change_property_type_module_id_with_qualified_type_sets_type_id_to_null) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ + "Object", Storage::Import{qmlModuleId, Storage::Version{}, sourceId1}}; + storage.synchronize(package); + package.types[1].exportedTypes[0].moduleId = qtQuickModuleId; + + storage.synchronize(SynchronizationPackage{importsSourceId2 + moduleDependenciesSourceId2, + {package.types[1]}, + {sourceId2}}); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations(Contains(HasPropertyTypeId(IsNullTypeId())))); +} + +TEST_F(ProjectStorage, + fixed_broken_change_property_type_module_id_with_qualified_type_sets_fixes_type_idl) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].propertyDeclarations[0].typeName = Storage::Synchronization::QualifiedImportedType{ + "Object", Storage::Import{qmlModuleId, Storage::Version{}, sourceId1}}; + storage.synchronize(package); + package.types[1].exportedTypes[0].moduleId = qtQuickModuleId; + storage.synchronize(SynchronizationPackage{importsSourceId2 + moduleDependenciesSourceId2, + {package.types[1]}, + {sourceId2}}); + package.types[1].exportedTypes[0].moduleId = qmlModuleId; + + storage.synchronize(SynchronizationPackage{importsSourceId2 + moduleDependenciesSourceId2, + {package.types[1]}, + {sourceId2}}); + + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), + PropertyDeclarations(Not(Contains(HasPropertyTypeId(IsNullTypeId()))))); } TEST_F(ProjectStorage, change_property_type_module_id_with_qualified_type) @@ -5280,7 +5751,7 @@ TEST_F(ProjectStorage, minimal_updates) "QQuickItem", {}, Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, sourceId1, {Storage::Synchronization::ExportedType{qtQuickModuleId, "Item", Storage::Version{2, 0}}, Storage::Synchronization::ExportedType{qtQuickNativeModuleId, "QQuickItem"}}, @@ -5988,48 +6459,144 @@ TEST_F(ProjectStorage, synchronize_types_remove_indirect_alias_declaration) Storage::PropertyDeclarationTraits::IsList)))))); } -TEST_F(ProjectStorage, synchronize_types_add_indirect_alias_declarations_throws_for_wrong_type_name) +TEST_F(ProjectStorage, + synchronize_types_add_indirect_alias_declarations_notifies_unresolved_type_name_for_wrong_type_name) { auto package{createSynchronizationPackageWithIndirectAliases()}; storage.synchronize(package); package.types[2].propertyDeclarations[1].typeName = Storage::Synchronization::ImportedType{ "QQuickItemWrong"}; - ASSERT_THROW(storage.synchronize(SynchronizationPackage{importsSourceId3, - {package.types[2]}, - {sourceId3}, - moduleDependenciesSourceId3, - {sourceId3}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("QQuickItemWrong"), sourceId3)); + + storage.synchronize(SynchronizationPackage{ + importsSourceId3, {package.types[2]}, {sourceId3}, moduleDependenciesSourceId3, {sourceId3}}); } -TEST_F(ProjectStorage, synchronize_types_add_indirect_alias_declarations_throws_for_wrong_property_name) +TEST_F(ProjectStorage, + synchronize_types_add_indirect_alias_declarations_for_wrong_type_name_sets_null_type_id) +{ + auto package{createSynchronizationPackageWithIndirectAliases()}; + storage.synchronize(package); + package.types[2].propertyDeclarations[1].typeName = Storage::Synchronization::ImportedType{ + "QQuickItemWrong"}; + + storage.synchronize(SynchronizationPackage{ + importsSourceId3, {package.types[2]}, {sourceId3}, moduleDependenciesSourceId3, {sourceId3}}); + + auto type = storage.fetchTypeByTypeId(fetchTypeId(sourceId3, "QAliasItem")); + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations(Contains(IsPropertyDeclaration("objects", IsNullTypeId())))); +} + +TEST_F(ProjectStorage, + fixed_synchronize_types_add_indirect_alias_declarations_for_wrong_type_name_sets_type_id) +{ + auto package{createSynchronizationPackageWithIndirectAliases()}; + storage.synchronize(package); + package.types[2].propertyDeclarations[1].typeName = Storage::Synchronization::ImportedType{ + "QQuickItemWrong"}; + storage.synchronize(SynchronizationPackage{ + importsSourceId3, {package.types[2]}, {sourceId3}, moduleDependenciesSourceId3, {sourceId3}}); + package.types[2].propertyDeclarations[1].typeName = Storage::Synchronization::ImportedType{ + "Item"}; + + storage.synchronize(SynchronizationPackage{ + importsSourceId3, {package.types[2]}, {sourceId3}, moduleDependenciesSourceId3, {sourceId3}}); + + auto type = storage.fetchTypeByTypeId(fetchTypeId(sourceId3, "QAliasItem")); + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations(Not(Contains(IsPropertyDeclaration("objects", IsNullTypeId()))))); +} + +TEST_F(ProjectStorage, + synchronize_types_add_indirect_alias_declarations_notifies_error_for_wrong_property_name) { auto package{createSynchronizationPackageWithIndirectAliases()}; storage.synchronize(package); package.types[2].propertyDeclarations[1].aliasPropertyName = "childrenWrong"; - ASSERT_THROW(storage.synchronize(SynchronizationPackage{importsSourceId3, - {package.types[2]}, - {sourceId3}, - moduleDependenciesSourceId3, - {sourceId3}}), - QmlDesigner::PropertyNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, propertyNameDoesNotExists(Eq("childrenWrong.objects"), sourceId3)); + + storage.synchronize( + {importsSourceId3, {package.types[2]}, {sourceId3}, moduleDependenciesSourceId3, {sourceId3}}); } TEST_F(ProjectStorage, - synchronize_types_add_indirect_alias_declarations_throws_for_wrong_property_name_tail) + synchronize_types_add_indirect_alias_declarations_returns_null_type_id_for_wrong_property_name) +{ + auto package{createSynchronizationPackageWithIndirectAliases()}; + storage.synchronize(package); + package.types[2].propertyDeclarations[1].aliasPropertyName = "childrenWrong"; + + storage.synchronize( + {importsSourceId3, {package.types[2]}, {sourceId3}, moduleDependenciesSourceId3, {sourceId3}}); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations(Contains(IsPropertyDeclaration("objects", IsNullTypeId())))); +} + +TEST_F(ProjectStorage, + synchronize_types_updated_indirect_alias_declarations_returns_item_type_id_for_wrong_property_name) +{ + auto package{createSynchronizationPackageWithIndirectAliases()}; + storage.synchronize(package); + package.types[2].propertyDeclarations[1].aliasPropertyName = "childrenWrong"; + storage.synchronize( + {importsSourceId3, {package.types[2]}, {sourceId3}, moduleDependenciesSourceId3, {sourceId3}}); + package.types[2].propertyDeclarations[1].aliasPropertyName = "children"; + + storage.synchronize( + {importsSourceId3 + moduleDependenciesSourceId3, {package.types[2]}, {sourceId3}}); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations( + Contains(IsPropertyDeclaration("objects", fetchTypeId(sourceId2, "QObject"))))); +} + +TEST_F(ProjectStorage, + synchronize_types_add_indirect_alias_declarations_notifies_error_for_wrong_property_name_tail) { auto package{createSynchronizationPackageWithIndirectAliases()}; storage.synchronize(package); package.types[2].propertyDeclarations[1].aliasPropertyNameTail = "objectsWrong"; - ASSERT_THROW(storage.synchronize(SynchronizationPackage{importsSourceId3, - {package.types[2]}, - {sourceId3}, - moduleDependenciesSourceId3, - {sourceId3}}), - QmlDesigner::PropertyNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, propertyNameDoesNotExists(Eq("children.objectsWrong"), sourceId3)); + + storage.synchronize(SynchronizationPackage{ + importsSourceId3, {package.types[2]}, {sourceId3}, moduleDependenciesSourceId3, {sourceId3}}); +} + +TEST_F(ProjectStorage, + synchronize_types_add_indirect_alias_declarations_sets_property_declaration_id_to_null_for_the_wrong_property_name_tail) +{ + auto package{createSynchronizationPackageWithIndirectAliases()}; + storage.synchronize(package); + package.types[2].propertyDeclarations[1].aliasPropertyNameTail = "objectsWrong"; + + storage.synchronize(SynchronizationPackage{ + importsSourceId3, {package.types[2]}, {sourceId3}, moduleDependenciesSourceId3, {sourceId3}}); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations(Contains(IsPropertyDeclaration("objects", IsNullTypeId())))); +} + +TEST_F(ProjectStorage, + synchronize_types_updates_indirect_alias_declarations_fixed_property_declaration_id_for_property_name_tail) +{ + auto package{createSynchronizationPackageWithIndirectAliases()}; + storage.synchronize(package); + package.types[2].propertyDeclarations[1].aliasPropertyNameTail = "objectsWrong"; + storage.synchronize( + {importsSourceId3, {package.types[2]}, {sourceId3}, moduleDependenciesSourceId3, {sourceId3}}); + package.types[2].propertyDeclarations[1].aliasPropertyNameTail = "objects"; + + storage.synchronize( + {importsSourceId3 + moduleDependenciesSourceId3, {package.types[2]}, {sourceId3}}); + + ASSERT_THAT(fetchType(sourceId3, "QAliasItem"), + PropertyDeclarations(Contains( + IsPropertyDeclaration("objects", Eq(fetchTypeId(sourceId2, "QObject")))))); } TEST_F(ProjectStorage, synchronize_types_change_indirect_alias_declaration_type_name) @@ -6841,9 +7408,7 @@ TEST_F(ProjectStorage, synchronize_default_property) storage.synchronize(package); ASSERT_THAT(storage.fetchTypes(), - Contains(AllOf(Field(&Storage::Synchronization::Type::typeName, Eq("QQuickItem")), - Field(&Storage::Synchronization::Type::defaultPropertyName, - Eq("children"))))); + Contains(AllOf(HasTypeName(Eq("QQuickItem")), HasDefaultPropertyName(Eq("children"))))); } TEST_F(ProjectStorage, synchronize_default_property_to_a_different_name) @@ -6856,9 +7421,7 @@ TEST_F(ProjectStorage, synchronize_default_property_to_a_different_name) storage.synchronize(package); ASSERT_THAT(storage.fetchTypes(), - Contains( - AllOf(Field(&Storage::Synchronization::Type::typeName, Eq("QQuickItem")), - Field(&Storage::Synchronization::Type::defaultPropertyName, Eq("data"))))); + Contains(AllOf(HasTypeName(Eq("QQuickItem")), HasDefaultPropertyName(Eq("data"))))); } TEST_F(ProjectStorage, synchronize_to_removed_default_property) @@ -6871,28 +7434,67 @@ TEST_F(ProjectStorage, synchronize_to_removed_default_property) storage.synchronize(package); ASSERT_THAT(storage.fetchTypes(), - Contains( - AllOf(Field(&Storage::Synchronization::Type::typeName, Eq("QQuickItem")), - Field(&Storage::Synchronization::Type::defaultPropertyName, IsEmpty())))); + Contains(AllOf(HasTypeName(Eq("QQuickItem")), HasDefaultPropertyName(IsEmpty())))); } -TEST_F(ProjectStorage, synchronize_default_property_throws_for_missing_default_property) +TEST_F(ProjectStorage, synchronize_default_property_notifies_error_for_missing_default_property) { auto package{createSimpleSynchronizationPackage()}; package.types.front().defaultPropertyName = "child"; - ASSERT_THROW(storage.synchronize(package), QmlDesigner::PropertyNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, missingDefaultProperty(Eq("QQuickItem"), Eq("child"), sourceId1)); + + storage.synchronize(package); +} + +TEST_F(ProjectStorage, gets_null_default_property_id_for_broken_default_property_name) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types.front().defaultPropertyName = "child"; + + storage.synchronize(package); + + ASSERT_THAT(defaultPropertyDeclarationId(sourceId1, "QQuickItem"), IsNullPropertyDeclarationId()); +} + +TEST_F(ProjectStorage, synchronize_default_fixes_default_property_name) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types.front().defaultPropertyName = "child"; + storage.synchronize(package); + package.types.front().defaultPropertyName = "data"; + + storage.synchronize(package); + + ASSERT_THAT(defaultPropertyDeclarationId(sourceId1, "QQuickItem"), + Eq(propertyDeclarationId(sourceId1, "QQuickItem", "data"))); } TEST_F(ProjectStorage, - synchronize_default_property_throws_for_removing_property_without_changing_default_property) + synchronize_default_property_notifies_error_for_removing_property_without_changing_default_property) { auto package{createSimpleSynchronizationPackage()}; package.types.front().defaultPropertyName = "children"; storage.synchronize(package); removeProperty(package, "QQuickItem", "children"); - ASSERT_THROW(storage.synchronize(package), QmlDesigner::PropertyNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, + missingDefaultProperty(Eq("QQuickItem"), Eq("children"), sourceId1)); + + storage.synchronize(package); +} + +TEST_F(ProjectStorage, + synchronize_default_property_has_null_id_for_removing_property_without_changing_default_property) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types.front().defaultPropertyName = "children"; + storage.synchronize(package); + removeProperty(package, "QQuickItem", "children"); + + storage.synchronize(package); + + ASSERT_THAT(defaultPropertyDeclarationId(sourceId1, "QQuickItem"), IsNullPropertyDeclarationId()); } TEST_F(ProjectStorage, synchronize_changes_default_property_and_removes_old_default_property) @@ -6907,9 +7509,7 @@ TEST_F(ProjectStorage, synchronize_changes_default_property_and_removes_old_defa storage.synchronize(package); ASSERT_THAT(storage.fetchTypes(), - Contains( - AllOf(Field(&Storage::Synchronization::Type::typeName, Eq("QQuickItem")), - Field(&Storage::Synchronization::Type::defaultPropertyName, Eq("data"))))); + Contains(AllOf(HasTypeName(Eq("QQuickItem")), HasDefaultPropertyName(Eq("data"))))); } TEST_F(ProjectStorage, synchronize_add_new_default_property_and_removes_old_default_property) @@ -6929,9 +7529,7 @@ TEST_F(ProjectStorage, synchronize_add_new_default_property_and_removes_old_defa storage.synchronize(package); ASSERT_THAT(storage.fetchTypes(), - Contains( - AllOf(Field(&Storage::Synchronization::Type::typeName, Eq("QQuickItem")), - Field(&Storage::Synchronization::Type::defaultPropertyName, Eq("data2"))))); + Contains(AllOf(HasTypeName(Eq("QQuickItem")), HasDefaultPropertyName(Eq("data2"))))); } TEST_F(ProjectStorage, synchronize_default_property_to_the_prototype_property) @@ -6946,9 +7544,7 @@ TEST_F(ProjectStorage, synchronize_default_property_to_the_prototype_property) storage.synchronize(package); ASSERT_THAT(storage.fetchTypes(), - Contains(AllOf(Field(&Storage::Synchronization::Type::typeName, Eq("QQuickItem")), - Field(&Storage::Synchronization::Type::defaultPropertyName, - Eq("children"))))); + Contains(AllOf(HasTypeName(Eq("QQuickItem")), HasDefaultPropertyName(Eq("children"))))); } TEST_F(ProjectStorage, synchronize_default_property_to_the_extension_property) @@ -6964,9 +7560,7 @@ TEST_F(ProjectStorage, synchronize_default_property_to_the_extension_property) storage.synchronize(package); ASSERT_THAT(storage.fetchTypes(), - Contains(AllOf(Field(&Storage::Synchronization::Type::typeName, Eq("QQuickItem")), - Field(&Storage::Synchronization::Type::defaultPropertyName, - Eq("children"))))); + Contains(AllOf(HasTypeName(Eq("QQuickItem")), HasDefaultPropertyName(Eq("children"))))); } TEST_F(ProjectStorage, synchronize_move_the_default_property_to_the_prototype_property) @@ -6982,9 +7576,7 @@ TEST_F(ProjectStorage, synchronize_move_the_default_property_to_the_prototype_pr storage.synchronize(package); ASSERT_THAT(storage.fetchTypes(), - Contains(AllOf(Field(&Storage::Synchronization::Type::typeName, Eq("QQuickItem")), - Field(&Storage::Synchronization::Type::defaultPropertyName, - Eq("children"))))); + Contains(AllOf(HasTypeName(Eq("QQuickItem")), HasDefaultPropertyName(Eq("children"))))); } TEST_F(ProjectStorage, synchronize_move_the_default_property_to_the_extension_property) @@ -7001,9 +7593,7 @@ TEST_F(ProjectStorage, synchronize_move_the_default_property_to_the_extension_pr storage.synchronize(package); ASSERT_THAT(storage.fetchTypes(), - Contains(AllOf(Field(&Storage::Synchronization::Type::typeName, Eq("QQuickItem")), - Field(&Storage::Synchronization::Type::defaultPropertyName, - Eq("children"))))); + Contains(AllOf(HasTypeName(Eq("QQuickItem")), HasDefaultPropertyName(Eq("children"))))); } TEST_F(ProjectStorage, get_type) @@ -7516,8 +8106,7 @@ TEST_F(ProjectStorage, synchronize_document_imports_removes_import_which_makes_p storage.synchronizeDocumentImports({}, sourceId1); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - IsPrototypeId(IsUnresolvedTypeId())); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasPrototypeId(IsUnresolvedTypeId())); } TEST_F(ProjectStorage, synchronize_document_imports_adds_import_which_makes_prototype_resolved) @@ -7530,8 +8119,7 @@ TEST_F(ProjectStorage, synchronize_document_imports_adds_import_which_makes_prot storage.synchronizeDocumentImports(imports, sourceId1); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - IsPrototypeId(fetchTypeId(sourceId2, "QObject"))); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasPrototypeId(fetchTypeId(sourceId2, "QObject"))); } TEST_F(ProjectStorage, get_exported_type_names) @@ -8330,8 +8918,7 @@ TEST_F(ProjectStorage, removed_document_import_changes_prototype_to_unresolved) storage.synchronize(package); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - Field(&Storage::Synchronization::Type::prototypeId, IsUnresolvedTypeId())); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasPrototypeId(IsUnresolvedTypeId())); } TEST_F(ProjectStorage, removed_document_import_changes_extension_to_unresolved) @@ -8347,8 +8934,7 @@ TEST_F(ProjectStorage, removed_document_import_changes_extension_to_unresolved) storage.synchronize(package); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - Field(&Storage::Synchronization::Type::extensionId, IsUnresolvedTypeId())); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasExtensionId(IsUnresolvedTypeId())); } TEST_F(ProjectStorage, added_document_import_fixes_unresolved_prototype) @@ -8363,8 +8949,7 @@ TEST_F(ProjectStorage, added_document_import_fixes_unresolved_prototype) storage.synchronize(package); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - IsPrototypeId(fetchTypeId(sourceId2, "QObject"))); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasPrototypeId(fetchTypeId(sourceId2, "QObject"))); } TEST_F(ProjectStorage, added_document_import_fixes_unresolved_extension) @@ -8379,8 +8964,7 @@ TEST_F(ProjectStorage, added_document_import_fixes_unresolved_extension) storage.synchronize(package); - ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), - IsExtensionId(fetchTypeId(sourceId2, "QObject"))); + ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasExtensionId(fetchTypeId(sourceId2, "QObject"))); } } // namespace diff --git a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp index 771107ece79..8e07782046e 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp @@ -104,9 +104,9 @@ protected: pathCache.sourceId(path3), pathCache.sourceId(path4), pathCache.sourceId(path5)}; - SourceContextIds sourceContextIds = {pathCache.sourceContextId(sourceIds[0]), - pathCache.sourceContextId(sourceIds[2]), - pathCache.sourceContextId(sourceIds[4])}; + SourceContextIds sourceContextIds = {sourceIds[0].contextId(), + sourceIds[2].contextId(), + sourceIds[4].contextId()}; ProjectChunkIds ids{projectChunkId1, projectChunkId2, projectChunkId3}; WatcherEntry watcherEntry1{projectChunkId1, sourceContextIds[0], sourceIds[0]}; WatcherEntry watcherEntry2{projectChunkId2, sourceContextIds[0], sourceIds[0]}; @@ -366,10 +366,9 @@ TEST_F(ProjectStoragePathWatcher, two_notify_file_changes) .WillByDefault(Return(FileStatus{sourceIds[3], 1, 2})); EXPECT_CALL(notifier, - pathsWithIdsChanged(ElementsAre( - IdPaths{projectChunkId1, {SourceId::create(1), SourceId::create(2)}}, - IdPaths{projectChunkId2, - {SourceId::create(1), SourceId::create(2), SourceId::create(4)}}))); + pathsWithIdsChanged( + ElementsAre(IdPaths{projectChunkId1, {sourceIds[0], sourceIds[1]}}, + IdPaths{projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}))); mockQFileSytemWatcher.directoryChanged(sourceContextPath); mockQFileSytemWatcher.directoryChanged(sourceContextPath2); diff --git a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp index e38f05349be..0a072d9fcd1 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp @@ -185,8 +185,11 @@ public: }); firstType.prototype = Storage::Synchronization::ImportedType{"Object"}; + firstType.traits = TypeTraitsKind::Reference; secondType.prototype = Storage::Synchronization::ImportedType{"Object2"}; + secondType.traits = TypeTraitsKind::Reference; thirdType.prototype = Storage::Synchronization::ImportedType{"Object3"}; + thirdType.traits = TypeTraitsKind::Reference; setContent(u"/path/First.qml", qmlDocument1); setContent(u"/path/First2.qml", qmlDocument2); @@ -437,7 +440,7 @@ TEST_F(ProjectStorageUpdater, get_content_for_qml_dir_paths_if_file_status_is_di EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/one/qmldir")))); EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/two/qmldir")))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, @@ -455,7 +458,7 @@ TEST_F(ProjectStorageUpdater, EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/one/qmldir")))); EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/two/qmldir")))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, request_file_status_from_file_system) @@ -464,7 +467,7 @@ TEST_F(ProjectStorageUpdater, request_file_status_from_file_system) EXPECT_CALL(fileSystemMock, fileStatus(Eq(directoryPathSourceId))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, request_file_status_from_file_system_for_subdirectories) @@ -478,7 +481,7 @@ TEST_F(ProjectStorageUpdater, request_file_status_from_file_system_for_subdirect EXPECT_CALL(fileSystemMock, fileStatus(Eq(path2SourceId))); EXPECT_CALL(fileSystemMock, fileStatus(Eq(directoryPathSourceId))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, get_content_for_qml_types) @@ -490,7 +493,7 @@ TEST_F(ProjectStorageUpdater, get_content_for_qml_types) EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes")))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, get_content_for_qml_types_if_project_storage_file_status_is_invalid) @@ -503,7 +506,7 @@ TEST_F(ProjectStorageUpdater, get_content_for_qml_types_if_project_storage_file_ EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes")))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, parse_qml_types) @@ -522,7 +525,7 @@ TEST_F(ProjectStorageUpdater, parse_qml_types) EXPECT_CALL(qmlTypesParserMock, parse(qmltypes2, _, _, Field(&DirectoryInfo::moduleId, exampleCppNativeModuleId))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, parse_qml_types_in_subdirectories) @@ -543,7 +546,7 @@ TEST_F(ProjectStorageUpdater, parse_qml_types_in_subdirectories) EXPECT_CALL(qmlTypesParserMock, parse(qmltypes2, _, _, Field(&DirectoryInfo::moduleId, exampleCppNativeModuleId))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_no_change) @@ -552,7 +555,7 @@ TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_no_change) EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_no_change_in_subdirectory) @@ -569,7 +572,7 @@ TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_no_change_in_subdirectory EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qml_types) @@ -604,7 +607,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_types) Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_subdircectories) @@ -627,7 +630,7 @@ TEST_F(ProjectStorageUpdater, synchronize_subdircectories) UnorderedElementsAre( rootDirectoryPathSourceId, path1SourceId, path2SourceId, path3SourceId))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_subdircectories_even_for_no_changes) @@ -647,7 +650,7 @@ TEST_F(ProjectStorageUpdater, synchronize_subdircectories_even_for_no_changes) Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(path1SourceId, path2SourceId, path3SourceId))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_subdircectories_for_deleted_subdirecties) @@ -675,7 +678,7 @@ TEST_F(ProjectStorageUpdater, synchronize_subdircectories_for_deleted_subdirecti path2SourceId, path3SourceId))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qml_types_throws_if_qmltpes_does_not_exists) @@ -683,7 +686,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_types_throws_if_qmltpes_does_not_e Storage::Import import{qmlModuleId, Storage::Version{2, 3}, qmltypesPathSourceId}; setFilesDontExists({qmltypesPathSourceId}); - ASSERT_THROW(updater.update(directories, {}, {}, {}), QmlDesigner::CannotParseQmlTypesFile); + ASSERT_THROW(updater.update({.directories = directories}), QmlDesigner::CannotParseQmlTypesFile); } TEST_F(ProjectStorageUpdater, synchronize_qml_types_are_empty_if_file_does_not_changed) @@ -696,7 +699,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_types_are_empty_if_file_does_not_c EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, get_content_for_qml_documents) @@ -717,7 +720,7 @@ TEST_F(ProjectStorageUpdater, get_content_for_qml_documents) EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/OldSecond.qml")))); EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/Second.qml")))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, parse_qml_documents) @@ -738,7 +741,7 @@ TEST_F(ProjectStorageUpdater, parse_qml_documents) EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument2, _, _, _)); EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument3, _, _, _)); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, parse_qml_documents_with_non_existing_qml_document_throws) @@ -747,7 +750,8 @@ TEST_F(ProjectStorageUpdater, parse_qml_documents_with_non_existing_qml_document NonexitingType 1.0 NonexitingType.qml)"}; setContent(u"/path/qmldir", qmldir); - ASSERT_THROW(updater.update(directories, {}, {}, {}), QmlDesigner::CannotParseQmlDocumentFile); + ASSERT_THROW(updater.update({.directories = directories}), + QmlDesigner::CannotParseQmlDocumentFile); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents) @@ -820,7 +824,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents) ModuleId{}, FileType::QmlDocument)))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_add_only_qml_document_in_directory) @@ -842,7 +846,7 @@ TEST_F(ProjectStorageUpdater, synchronize_add_only_qml_document_in_directory) UnorderedElementsAre( AllOf(IsStorageType("First.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId1, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -876,7 +880,7 @@ TEST_F(ProjectStorageUpdater, synchronize_add_only_qml_document_in_directory) ModuleId{}, FileType::QmlDocument)))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document) @@ -903,7 +907,7 @@ TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document) UnorderedElementsAre( AllOf(IsStorageType("First.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId1, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -912,7 +916,7 @@ TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document) IsExportedType(pathModuleId, "First", -1, -1)))), AllOf(IsStorageType("First2.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId2, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -940,7 +944,7 @@ TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document) ModuleId{}, FileType::QmlDocument)))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document_in_qmldir_only) @@ -964,7 +968,7 @@ TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document_in_qmldir_only) UnorderedElementsAre( AllOf(IsStorageType("First.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId1, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -972,7 +976,7 @@ TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document_in_qmldir_only) IsExportedType(pathModuleId, "First", -1, -1)))), AllOf(IsStorageType("First2.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId2, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -995,7 +999,7 @@ TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document_in_qmldir_only) ModuleId{}, FileType::QmlDocument)))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_add_qml_document_to_qmldir) @@ -1021,7 +1025,7 @@ TEST_F(ProjectStorageUpdater, synchronize_add_qml_document_to_qmldir) UnorderedElementsAre( AllOf(IsStorageType("First.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId1, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -1029,7 +1033,7 @@ TEST_F(ProjectStorageUpdater, synchronize_add_qml_document_to_qmldir) IsExportedType(pathModuleId, "First", -1, -1)))), AllOf(IsStorageType("First2.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId2, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -1053,7 +1057,7 @@ TEST_F(ProjectStorageUpdater, synchronize_add_qml_document_to_qmldir) ModuleId{}, FileType::QmlDocument)))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_remove_qml_document_from_qmldir) @@ -1077,7 +1081,7 @@ TEST_F(ProjectStorageUpdater, synchronize_remove_qml_document_from_qmldir) UnorderedElementsAre( AllOf(IsStorageType("First.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId1, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -1085,7 +1089,7 @@ TEST_F(ProjectStorageUpdater, synchronize_remove_qml_document_from_qmldir) IsExportedType(pathModuleId, "First", -1, -1)))), AllOf(IsStorageType("First2.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId2, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -1108,7 +1112,7 @@ TEST_F(ProjectStorageUpdater, synchronize_remove_qml_document_from_qmldir) ModuleId{}, FileType::QmlDocument)))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_dont_update_if_up_to_date) @@ -1145,7 +1149,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_dont_update_if_up_to_dat IsExportedType(pathModuleId, "First2", -1, -1)))), AllOf(IsStorageType("Second.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId3, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -1178,7 +1182,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_dont_update_if_up_to_dat ModuleId{}, FileType::QmlDocument)))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_not_changed) @@ -1229,7 +1233,7 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_not_changed) qmlDocumentSourceId2)), Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_not_changed_and_some_updated_files) @@ -1264,7 +1268,7 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_not_changed_and_some UnorderedElementsAre(qmltypesPathSourceId, qmlDocumentSourceId1)), Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_not_changed_and_some_removed_files) @@ -1279,7 +1283,7 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_not_changed_and_some_rem setFilesDontChanged({qmlDirPathSourceId, qmltypes2PathSourceId, qmlDocumentSourceId2}); setFilesRemoved({qmltypesPathSourceId, qmlDocumentSourceId1}); - ASSERT_THROW(updater.update(directories, {}, {}, {}), QmlDesigner::CannotParseQmlTypesFile); + ASSERT_THROW(updater.update({.directories = directories}), QmlDesigner::CannotParseQmlTypesFile); } TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_changed_and_some_removed_files) @@ -1306,7 +1310,7 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_changed_and_some_rem UnorderedElementsAre(AllOf( IsStorageType("First2.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId2, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -1331,7 +1335,7 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_changed_and_some_rem exampleCppNativeModuleId, FileType::QmlTypes)))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, update_qml_types_files_is_empty) @@ -1346,7 +1350,7 @@ TEST_F(ProjectStorageUpdater, update_qml_types_files_is_empty) Field(&SynchronizationPackage::directoryInfos, IsEmpty()), Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, IsEmpty())))); - updater.update({}, {}, {}, {}); + updater.update({}); } TEST_F(ProjectStorageUpdater, update_qml_types_files) @@ -1374,7 +1378,7 @@ TEST_F(ProjectStorageUpdater, update_qml_types_files) Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(qmltypesPathSourceId, qmltypes2PathSourceId))))); - updater.update({}, {"/path/example.qmltypes", "/path/example2.qmltypes"}, {}, {}); + updater.update({.qmlTypesPaths = {"/path/example.qmltypes", "/path/example2.qmltypes"}}); } TEST_F(ProjectStorageUpdater, dont_update_qml_types_files_if_unchanged) @@ -1399,7 +1403,7 @@ TEST_F(ProjectStorageUpdater, dont_update_qml_types_files_if_unchanged) Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(qmltypesPathSourceId))))); - updater.update({}, {"/path/example.qmltypes", "/path/example2.qmltypes"}, {}, {}); + updater.update({.qmlTypesPaths = {"/path/example.qmltypes", "/path/example2.qmltypes"}}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_with_different_version_but_same_type_name_and_file_name) @@ -1442,7 +1446,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_with_different_version_b ModuleId{}, FileType::QmlDocument)))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_with_different_type_name_but_same_version_and_file_name) @@ -1483,7 +1487,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_with_different_type_name ModuleId{}, FileType::QmlDocument)))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, dont_synchronize_selectors) @@ -1501,7 +1505,7 @@ TEST_F(ProjectStorageUpdater, dont_synchronize_selectors) Contains(Field(&Storage::Synchronization::Type::exportedTypes, Contains(IsExportedType(exampleModuleId, "FirstType", 1, 0)))))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_dependencies) @@ -1526,7 +1530,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_dependencies) Field(&SynchronizationPackage::updatedModuleDependencySourceIds, UnorderedElementsAre(qmltypesPathSourceId, qmltypes2PathSourceId))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_dependencies_with_double_entries) @@ -1552,7 +1556,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_dependencies_with_double_entrie Field(&SynchronizationPackage::updatedModuleDependencySourceIds, UnorderedElementsAre(qmltypesPathSourceId, qmltypes2PathSourceId))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_dependencies_with_colliding_imports) @@ -1578,7 +1582,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_dependencies_with_colliding_imp Field(&SynchronizationPackage::updatedModuleDependencySourceIds, UnorderedElementsAre(qmltypesPathSourceId, qmltypes2PathSourceId))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_with_no_dependencies) @@ -1595,7 +1599,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_with_no_dependencies) Field(&SynchronizationPackage::updatedModuleDependencySourceIds, UnorderedElementsAre(qmltypesPathSourceId, qmltypes2PathSourceId))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_imports) @@ -1637,7 +1641,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_imports) Field(&SynchronizationPackage::updatedModuleIds, ElementsAre(exampleModuleId))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_with_no_imports) @@ -1651,7 +1655,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_with_no_imports) Field(&SynchronizationPackage::updatedModuleIds, ElementsAre(exampleModuleId))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_imports_with_double_entries) @@ -1694,7 +1698,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_imports_with_double_entries) Field(&SynchronizationPackage::updatedModuleIds, ElementsAre(exampleModuleId))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_default_imports) @@ -1736,7 +1740,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_default_imports) Field(&SynchronizationPackage::updatedModuleIds, ElementsAre(exampleModuleId))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, do_not_synchronize_qmldir_optional_imports) @@ -1770,7 +1774,7 @@ TEST_F(ProjectStorageUpdater, do_not_synchronize_qmldir_optional_imports) Field(&SynchronizationPackage::updatedModuleIds, ElementsAre(exampleModuleId))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, update_path_watcher_directories) @@ -1780,7 +1784,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_directories) QmlDesigner::SourceType::Directory, {path1SourceId, path2SourceId, path3SourceId}}))); - updater.update(directories3, {}, {}, {}); + updater.update({.directories = directories3}); } TEST_F(ProjectStorageUpdater, update_path_watcher_directory_does_not_exists) @@ -1792,7 +1796,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_directory_does_not_exists) QmlDesigner::SourceType::Directory, {path1SourceId, path3SourceId}}))); - updater.update(directories3, {}, {}, {}); + updater.update({.directories = directories3}); } TEST_F(ProjectStorageUpdater, update_path_watcher_directory_does_not_changed) @@ -1804,7 +1808,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_directory_does_not_changed) QmlDesigner::SourceType::Directory, {path1SourceId, path2SourceId}}))); - updater.update(directories2, {}, {}, {}); + updater.update({.directories = directories2}); } TEST_F(ProjectStorageUpdater, update_path_watcher_directory_removed) @@ -1815,7 +1819,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_directory_removed) updateIdPaths(Contains( IdPaths{projectPartId, QmlDesigner::SourceType::Directory, {path2SourceId}}))); - updater.update(directories2, {}, {}, {}); + updater.update({.directories = directories2}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qmldirs) @@ -1825,7 +1829,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmldirs) QmlDesigner::SourceType::QmlDir, {qmldir1SourceId, qmldir2SourceId, qmldir3SourceId}}))); - updater.update(directories3, {}, {}, {}); + updater.update({.directories = directories3}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_does_not_exists) @@ -1837,7 +1841,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_does_not_exists) QmlDesigner::SourceType::QmlDir, {qmldir1SourceId, qmldir3SourceId}}))); - updater.update(directories3, {}, {}, {}); + updater.update({.directories = directories3}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_does_not_changed) @@ -1849,7 +1853,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_does_not_changed) QmlDesigner::SourceType::QmlDir, {qmldir1SourceId, qmldir2SourceId}}))); - updater.update(directories2, {}, {}, {}); + updater.update({.directories = directories2}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_removed) @@ -1860,7 +1864,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_removed) updateIdPaths(Contains( IdPaths{projectPartId, QmlDesigner::SourceType::QmlDir, {qmldir2SourceId}}))); - updater.update(directories2, {}, {}, {}); + updater.update({.directories = directories2}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qml_files) @@ -1877,7 +1881,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qml_files) QmlDesigner::SourceType::Qml, {firstSourceId, secondSourceId, thirdSourceId}}))); - updater.update(directories2, {}, {}, {}); + updater.update({.directories = directories2}); } TEST_F(ProjectStorageUpdater, update_path_watcher_only_qml_files_dont_changed) @@ -1895,7 +1899,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qml_files_dont_changed) QmlDesigner::SourceType::Qml, {firstSourceId, secondSourceId, thirdSourceId}}))); - updater.update(directories2, {}, {}, {}); + updater.update({.directories = directories2}); } TEST_F(ProjectStorageUpdater, update_path_watcher_only_qml_files_changed) @@ -1913,7 +1917,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qml_files_changed) QmlDesigner::SourceType::Qml, {firstSourceId, secondSourceId, thirdSourceId}}))); - updater.update(directories2, {}, {}, {}); + updater.update({.directories = directories2}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qml_files_and_directories_dont_changed) @@ -1936,7 +1940,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qml_files_and_directories_dont QmlDesigner::SourceType::Qml, {firstSourceId, secondSourceId, thirdSourceId}}))); - updater.update(directories2, {}, {}, {}); + updater.update({.directories = directories2}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qmltypes_files_in_qmldir) @@ -1955,7 +1959,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmltypes_files_in_qmldir) QmlDesigner::SourceType::QmlTypes, {qmltypes1SourceId, qmltypes2SourceId}}))); - updater.update(directories2, {}, {}, {}); + updater.update({.directories = directories2}); } TEST_F(ProjectStorageUpdater, update_path_watcher_only_qmltypes_files_in_qmldir_dont_changed) @@ -1973,7 +1977,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qmltypes_files_in_qmldir_ QmlDesigner::SourceType::QmlTypes, {qmltypes1SourceId, qmltypes2SourceId}}))); - updater.update(directories2, {}, {}, {}); + updater.update({.directories = directories2}); } TEST_F(ProjectStorageUpdater, update_path_watcher_only_qmltypes_files_changed) @@ -1990,7 +1994,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qmltypes_files_changed) QmlDesigner::SourceType::QmlTypes, {qmltypes1SourceId, qmltypes2SourceId}}))); - updater.update(directories2, {}, {}, {}); + updater.update({.directories = directories2}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qmltypes_files_and_directories_dont_changed) @@ -2011,7 +2015,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmltypes_files_and_directories QmlDesigner::SourceType::QmlTypes, {qmltypes1SourceId, qmltypes2SourceId}}))); - updater.update(directories2, {}, {}, {}); + updater.update({.directories = directories2}); } TEST_F(ProjectStorageUpdater, update_path_watcher_builtin_qmltypes_files) @@ -2026,7 +2030,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_builtin_qmltypes_files) QmlDesigner::SourceType::QmlTypes, {qmltypes1SourceId, qmltypes2SourceId}}))); - updater.update({}, {builtinQmltyplesPath1, builtinQmltyplesPath2}, {}, {}); + updater.update({{}, {builtinQmltyplesPath1, builtinQmltyplesPath2}, {}, {}}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir) @@ -2093,7 +2097,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir) ModuleId{}, FileType::QmlDocument)))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_throws_if_qml_document_does_not_exists) @@ -2101,7 +2105,8 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_throws_if setFilesDontExists({qmlDirPathSourceId, qmlDocumentSourceId1}); setFilesAdded({directoryPathSourceId}); - ASSERT_THROW(updater.update(directories, {}, {}, {}), QmlDesigner::CannotParseQmlDocumentFile); + ASSERT_THROW(updater.update({.directories = directories}), + QmlDesigner::CannotParseQmlDocumentFile); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_throws_if_directory_does_not_exists) @@ -2132,7 +2137,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_throws_if UnorderedElementsAre(directoryPathSourceId)), Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_add_qml_document) @@ -2181,7 +2186,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_add_qml_d ModuleId{}, FileType::QmlDocument)))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_removes_qml_document) @@ -2221,7 +2226,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_removes_q ModuleId{}, FileType::QmlDocument)))))); - updater.update(directories, {}, {}, {}); + updater.update({.directories = directories}); } TEST_F(ProjectStorageUpdater, watcher_updates_directories) @@ -2408,7 +2413,7 @@ TEST_F(ProjectStorageUpdater, watcher_watches_directories_after_directory_change setContent(u"/path/qmldir", qmldir); setFilesChanged({directoryPathSourceId}); setFilesDontChanged({qmlDirPathSourceId}); - auto directorySourceContextId = sourcePathCache.sourceContextId(directoryPathSourceId); + auto directorySourceContextId = directoryPathSourceId.contextId(); EXPECT_CALL(patchWatcherMock, updateContextIdPaths( @@ -2521,7 +2526,7 @@ TEST_F(ProjectStorageUpdater, watcher_watches_directories_after_qmldir_changes) FirstType 2.2 First2.qml SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); - auto directorySourceContextId = sourcePathCache.sourceContextId(qmlDirPathSourceId); + auto directorySourceContextId = qmlDirPathSourceId.contextId(); EXPECT_CALL(patchWatcherMock, updateContextIdPaths( @@ -2569,7 +2574,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_add_only_qml_document_in_directory UnorderedElementsAre( AllOf(IsStorageType("First.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId1, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -2630,7 +2635,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removes_qml_document) UnorderedElementsAre( AllOf(IsStorageType("First.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId1, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -2639,7 +2644,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removes_qml_document) IsExportedType(pathModuleId, "First", -1, -1)))), AllOf(IsStorageType("First2.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId2, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -2691,7 +2696,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removes_qml_document_in_qmldir_onl UnorderedElementsAre( AllOf(IsStorageType("First.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId1, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -2699,7 +2704,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removes_qml_document_in_qmldir_onl IsExportedType(pathModuleId, "First", -1, -1)))), AllOf(IsStorageType("First2.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId2, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -2748,7 +2753,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_add_qml_document_to_qm UnorderedElementsAre( AllOf(IsStorageType("First.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId1, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -2756,7 +2761,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_add_qml_document_to_qm IsExportedType(pathModuleId, "First", -1, -1)))), AllOf(IsStorageType("First2.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId2, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -2804,7 +2809,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_remove_qml_document_fr UnorderedElementsAre( AllOf(IsStorageType("First.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId1, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -2812,7 +2817,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_remove_qml_document_fr IsExportedType(pathModuleId, "First", -1, -1)))), AllOf(IsStorageType("First2.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId2, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -2872,7 +2877,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_dont_update_qml_docume IsExportedType(pathModuleId, "First2", -1, -1)))), AllOf(IsStorageType("Second.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId3, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -2942,7 +2947,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qmldirs_dont_update_qml_documents_ IsExportedType(pathModuleId, "First2", -1, -1)))), AllOf(IsStorageType("Second.qml", Storage::Synchronization::ImportedType{}, - TypeTraitsKind::Reference, + TypeTraitsKind::None, qmlDocumentSourceId3, Storage::Synchronization::ChangeLevel::Minimal), Field(&Storage::Synchronization::Type::exportedTypes, @@ -3750,7 +3755,7 @@ TEST_F(ProjectStorageUpdater, update_property_editor_panes) Field(&SynchronizationPackage::updatedPropertyEditorQmlPathSourceIds, ElementsAre(directoryId))))); - updater.update({}, {}, propertyEditorQmlPath, {}); + updater.update({.propertyEditorResourcesPath = propertyEditorQmlPath}); } TEST_F(ProjectStorageUpdater, update_property_editor_specifics) @@ -3782,12 +3787,12 @@ TEST_F(ProjectStorageUpdater, update_property_editor_specifics) Field(&SynchronizationPackage::updatedPropertyEditorQmlPathSourceIds, ElementsAre(qtQuickDirectoryId, controlsDirectoryId))))); - updater.update({}, {}, propertyEditorQmlPath, {}); + updater.update({.propertyEditorResourcesPath = propertyEditorQmlPath}); } TEST_F(ProjectStorageUpdater, update_property_editor_panes_is_empty_if_directory_has_not_changed) { - updater.update({}, {}, propertyEditorQmlPath, {}); + updater.update({{}, {}, propertyEditorQmlPath, {}}); ON_CALL(fileSystemMock, fileStatus(_)).WillByDefault([](SourceId sourceId) { return FileStatus{sourceId, 1, 21}; }); @@ -3797,7 +3802,7 @@ TEST_F(ProjectStorageUpdater, update_property_editor_panes_is_empty_if_directory EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); - updater.update({}, {}, propertyEditorQmlPath, {}); + updater.update({.propertyEditorResourcesPath = propertyEditorQmlPath}); } TEST_F(ProjectStorageUpdater, update_type_annotations) @@ -3833,7 +3838,7 @@ TEST_F(ProjectStorageUpdater, update_type_annotations) Field(&SynchronizationPackage::updatedTypeAnnotationSourceIds, IsSupersetOf({itemSourceId, buttonSourceId}))))); - updater.update({}, {}, {}, {itemLibraryPath}); + updater.update({.typeAnnotationPaths = {itemLibraryPath}}); } TEST_F(ProjectStorageUpdater, update_changed_type_annotation) @@ -3870,7 +3875,7 @@ TEST_F(ProjectStorageUpdater, update_changed_type_annotation) Field(&SynchronizationPackage::updatedTypeAnnotationSourceIds, IsSupersetOf({itemSourceId, buttonSourceId}))))); - updater.update({}, {}, {}, {itemLibraryPath}); + updater.update({.typeAnnotationPaths = {itemLibraryPath}}); } TEST_F(ProjectStorageUpdater, update_type_annotations_removed_meta_info_file) @@ -3897,7 +3902,7 @@ TEST_F(ProjectStorageUpdater, update_type_annotations_removed_meta_info_file) Field(&SynchronizationPackage::updatedTypeAnnotationSourceIds, IsSupersetOf({itemSourceId, buttonSourceId}))))); - updater.update({}, {}, {}, {itemLibraryPath}); + updater.update({.typeAnnotationPaths = {itemLibraryPath}}); } TEST_F(ProjectStorageUpdater, update_type_annotations_removed_directory) @@ -3925,7 +3930,7 @@ TEST_F(ProjectStorageUpdater, update_type_annotations_removed_directory) Field(&SynchronizationPackage::updatedTypeAnnotationSourceIds, IsSupersetOf({buttonSourceId, itemSourceId}))))); - updater.update({}, {}, {}, {itemLibraryPath}); + updater.update({.typeAnnotationPaths = {itemLibraryPath}}); } } // namespace diff --git a/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp b/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp index e135bb27bd3..47f9bfdf86d 100644 --- a/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp @@ -13,12 +13,15 @@ namespace { +#undef signals + namespace Storage = QmlDesigner::Storage; namespace Synchronization = Storage::Synchronization; using QmlDesigner::ModuleId; using QmlDesigner::SourceContextId; using QmlDesigner::SourceId; using QmlDesigner::Storage::ModuleKind; +using Storage::TypeTraits; MATCHER_P(HasPrototype, prototype, std::string(negation ? "isn't " : "is ") + PrintToString(prototype)) { @@ -153,14 +156,16 @@ protected: QmlDesigner::QmlDocumentParser parser{storage, sourcePathCache}; Storage::Imports imports; SourceId qmlFileSourceId{sourcePathCache.sourceId("/path/to/qmlfile.qml")}; - SourceContextId qmlFileSourceContextId{sourcePathCache.sourceContextId(qmlFileSourceId)}; + SourceContextId qmlFileSourceContextId{qmlFileSourceId.contextId()}; Utils::PathString directoryPath{sourcePathCache.sourceContextPath(qmlFileSourceContextId)}; ModuleId directoryModuleId{storage.moduleId(directoryPath, ModuleKind::PathLibrary)}; }; TEST_F(QmlDocumentParser, prototype) { - auto type = parser.parse("Example{}", imports, qmlFileSourceId, directoryPath); + QString component = "Example{}"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type, HasPrototype(Synchronization::ImportedType("Example"))); } @@ -168,10 +173,10 @@ TEST_F(QmlDocumentParser, prototype) TEST_F(QmlDocumentParser, qualified_prototype) { auto exampleModuleId = storage.moduleId("Example", ModuleKind::QmlLibrary); - QString text = R"(import Example 2.1 as Example + QString component = R"(import Example 2.1 as Example Example.Item{})"; - auto type = parser.parse(text, imports, qmlFileSourceId, directoryPath); + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type, HasPrototype(Synchronization::QualifiedImportedType( @@ -181,7 +186,9 @@ TEST_F(QmlDocumentParser, qualified_prototype) TEST_F(QmlDocumentParser, properties) { - auto type = parser.parse(R"(Example{ property int foo })", imports, qmlFileSourceId, directoryPath); + QString component = R"(Example{ property int foo })"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.propertyDeclarations, UnorderedElementsAre(IsPropertyDeclaration("foo", @@ -192,12 +199,10 @@ TEST_F(QmlDocumentParser, properties) TEST_F(QmlDocumentParser, qualified_properties) { auto exampleModuleId = storage.moduleId("Example", ModuleKind::QmlLibrary); + QString component = R"(import Example 2.1 as Example + Item{ property Example.Foo foo})"; - auto type = parser.parse(R"(import Example 2.1 as Example - Item{ property Example.Foo foo})", - imports, - qmlFileSourceId, - directoryPath); + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.propertyDeclarations, UnorderedElementsAre(IsPropertyDeclaration( @@ -211,11 +216,10 @@ TEST_F(QmlDocumentParser, qualified_properties) TEST_F(QmlDocumentParser, enumeration_in_properties) { - auto type = parser.parse(R"(import Example 2.1 as Example - Item{ property Enumeration.Foo foo})", - imports, - qmlFileSourceId, - directoryPath); + QString component = R"(import Example 2.1 as Example + Item{ property Enumeration.Foo foo})"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.propertyDeclarations, UnorderedElementsAre( @@ -227,12 +231,10 @@ TEST_F(QmlDocumentParser, enumeration_in_properties) TEST_F(QmlDocumentParser, qualified_enumeration_in_properties) { auto exampleModuleId = storage.moduleId("Example", ModuleKind::QmlLibrary); + QString component = R"(import Example 2.1 as Example + Item{ property Example.Enumeration.Foo foo})"; - auto type = parser.parse(R"(import Example 2.1 as Example - Item{ property Example.Enumeration.Foo foo})", - imports, - qmlFileSourceId, - directoryPath); + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.propertyDeclarations, UnorderedElementsAre(IsPropertyDeclaration( @@ -249,13 +251,11 @@ TEST_F(QmlDocumentParser, imports) ModuleId fooDirectoryModuleId = storage.moduleId("/path/foo", ModuleKind::PathLibrary); ModuleId qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary); ModuleId qtQuickModuleId = storage.moduleId("QtQuick", ModuleKind::QmlLibrary); + QString component = R"(import QtQuick + import "../foo" + Example{})"; - auto type = parser.parse(R"(import QtQuick - import "../foo" - Example{})", - imports, - qmlFileSourceId, - directoryPath); + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(imports, UnorderedElementsAre( @@ -270,13 +270,11 @@ TEST_F(QmlDocumentParser, imports_with_version) ModuleId fooDirectoryModuleId = storage.moduleId("/path/foo", ModuleKind::PathLibrary); ModuleId qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary); ModuleId qtQuickModuleId = storage.moduleId("QtQuick", ModuleKind::QmlLibrary); + QString component = R"(import QtQuick 2.1 + import "../foo" + Example{})"; - auto type = parser.parse(R"(import QtQuick 2.1 - import "../foo" - Example{})", - imports, - qmlFileSourceId, - directoryPath); + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(imports, UnorderedElementsAre( @@ -290,14 +288,12 @@ TEST_F(QmlDocumentParser, imports_with_explict_directory) { ModuleId qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary); ModuleId qtQuickModuleId = storage.moduleId("QtQuick", ModuleKind::QmlLibrary); + QString component = R"(import QtQuick + import "../to" + import "." + Example{})"; - auto type = parser.parse(R"(import QtQuick - import "../to" - import "." - Example{})", - imports, - qmlFileSourceId, - directoryPath); + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT( imports, @@ -308,11 +304,9 @@ TEST_F(QmlDocumentParser, imports_with_explict_directory) TEST_F(QmlDocumentParser, functions) { - auto type = parser.parse( - "Example{\n function someScript(x, y) {}\n function otherFunction() {}\n}", - imports, - qmlFileSourceId, - directoryPath); + QString component = "Example{\n function someScript(x, y) {}\n function otherFunction() {}\n}"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.functionDeclarations, UnorderedElementsAre( @@ -325,6 +319,8 @@ TEST_F(QmlDocumentParser, functions) TEST_F(QmlDocumentParser, signals) { + QString component = "Example{\n signal someSignal(int x, real y)\n signal signal2()\n}"; + auto type = parser.parse("Example{\n signal someSignal(int x, real y)\n signal signal2()\n}", imports, qmlFileSourceId, @@ -341,11 +337,11 @@ TEST_F(QmlDocumentParser, signals) TEST_F(QmlDocumentParser, enumeration) { - auto type = parser.parse("Example{\n enum Color{red, green, blue=10, white}\n enum " - "State{On,Off}\n}", - imports, - qmlFileSourceId, - directoryPath); + QString component = R"(Example{ + enum Color{red, green, blue=10, white} + enum State{On,Off}})"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.enumerationDeclarations, UnorderedElementsAre( @@ -366,18 +362,16 @@ TEST_F(QmlDocumentParser, DISABLED_duplicate_imports_are_removed) ModuleId qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary); ModuleId qtQmlModuleId = storage.moduleId("QtQml", ModuleKind::QmlLibrary); ModuleId qtQuickModuleId = storage.moduleId("QtQuick", ModuleKind::QmlLibrary); - - auto type = parser.parse(R"(import QtQuick - import "../foo" - import QtQuick - import "../foo" - import "/path/foo" - import "." + QString component = R"(import QtQuick + import "../foo" + import QtQuick + import "../foo" + import "/path/foo" + import "." - Example{})", - imports, - qmlFileSourceId, - directoryPath); + Example{})"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(imports, UnorderedElementsAre( @@ -390,15 +384,14 @@ TEST_F(QmlDocumentParser, DISABLED_duplicate_imports_are_removed) TEST_F(QmlDocumentParser, alias_item_properties) { - auto type = parser.parse(R"(Example{ - property alias delegate: foo - Item { - id: foo - } - })", - imports, - qmlFileSourceId, - directoryPath); + QString component = R"(Example{ + property alias delegate: foo + Item { + id: foo + } + })"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.propertyDeclarations, UnorderedElementsAre(IsPropertyDeclaration("delegate", @@ -408,15 +401,14 @@ TEST_F(QmlDocumentParser, alias_item_properties) TEST_F(QmlDocumentParser, alias_properties) { - auto type = parser.parse(R"(Example{ - property alias text: foo.text2 - Item { - id: foo - } - })", - imports, - qmlFileSourceId, - directoryPath); + QString component = R"(Example{ + property alias text: foo.text2 + Item { + id: foo + } + })"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.propertyDeclarations, UnorderedElementsAre( @@ -428,15 +420,14 @@ TEST_F(QmlDocumentParser, alias_properties) TEST_F(QmlDocumentParser, indirect_alias_properties) { - auto type = parser.parse(R"(Example{ - property alias textSize: foo.text.size - Item { - id: foo - } - })", - imports, - qmlFileSourceId, - directoryPath); + QString component = R"(Example{ + property alias textSize: foo.text.size + Item { + id: foo + } + })"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.propertyDeclarations, UnorderedElementsAre( @@ -449,27 +440,25 @@ TEST_F(QmlDocumentParser, indirect_alias_properties) TEST_F(QmlDocumentParser, invalid_alias_properties_are_skipped) { - auto type = parser.parse(R"(Example{ - property alias textSize: foo2.text.size - Item { - id: foo - } - })", - imports, - qmlFileSourceId, - directoryPath); + QString component = R"(Example{ + property alias textSize: foo2.text.size + Item { + id: foo + } + })"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.propertyDeclarations, IsEmpty()); } TEST_F(QmlDocumentParser, list_property) { - auto type = parser.parse(R"(Item{ - property list foos - })", - imports, - qmlFileSourceId, - directoryPath); + QString component = R"(Item{ + property list foos + })"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.propertyDeclarations, UnorderedElementsAre( @@ -480,17 +469,16 @@ TEST_F(QmlDocumentParser, list_property) TEST_F(QmlDocumentParser, alias_on_list_property) { - auto type = parser.parse(R"(Item{ - property alias foos: foo.foos + QString component = R"(Item{ + property alias foos: foo.foos - Item { - id: foo - property list foos - } - })", - imports, - qmlFileSourceId, - directoryPath); + Item { + id: foo + property list foos + } + })"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.propertyDeclarations, UnorderedElementsAre( @@ -502,13 +490,12 @@ TEST_F(QmlDocumentParser, alias_on_list_property) TEST_F(QmlDocumentParser, qualified_list_property) { auto exampleModuleId = storage.moduleId("Example", ModuleKind::QmlLibrary); - auto type = parser.parse(R"(import Example 2.1 as Example - Item{ - property list foos - })", - imports, - qmlFileSourceId, - directoryPath); + QString component = R"(import Example 2.1 as Example + Item{ + property list foos + })"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.propertyDeclarations, UnorderedElementsAre(IsPropertyDeclaration( @@ -522,14 +509,36 @@ TEST_F(QmlDocumentParser, qualified_list_property) TEST_F(QmlDocumentParser, default_property) { - auto type = parser.parse(R"(import Example 2.1 as Example - Item{ - default property list foos - })", - imports, - qmlFileSourceId, - directoryPath); + QString component = R"(import Example 2.1 as Example + Item{ + default property list foos + })"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); ASSERT_THAT(type.defaultPropertyName, Eq("foos")); } + +TEST_F(QmlDocumentParser, has_file_component_trait) +{ + QString component = R"(import Example + Item{ + })"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); + + ASSERT_TRUE(type.traits.isFileComponent); +} + +TEST_F(QmlDocumentParser, has_is_reference_trait) +{ + QString component = R"(import Example + Item{ + })"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); + + ASSERT_THAT(type.traits.kind, QmlDesigner::Storage::TypeTraitsKind::Reference); +} + } // namespace diff --git a/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp b/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp index e75f7bf3a90..8b55eca7d3a 100644 --- a/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp @@ -184,7 +184,7 @@ protected: qmltypesFileSourceId, qtQmlNativeModuleId, Synchronization::FileType::QmlTypes}; - SourceContextId qmltypesFileSourceContextId{sourcePathCache.sourceContextId(qmltypesFileSourceId)}; + SourceContextId qmltypesFileSourceContextId{qmltypesFileSourceId.contextId()}; }; TEST_F(QmlTypesParser, imports) diff --git a/tests/unit/tests/unittests/projectstorage/sourcepathcache-test.cpp b/tests/unit/tests/unittests/projectstorage/sourcepathcache-test.cpp index fdc757c2c05..7e2fdd17696 100644 --- a/tests/unit/tests/unittests/projectstorage/sourcepathcache-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/sourcepathcache-test.cpp @@ -13,48 +13,44 @@ namespace { using QmlDesigner::SourceContextId; using QmlDesigner::SourceId; using QmlDesigner::SourceIds; +using QmlDesigner::SourceNameId; using Cache = QmlDesigner::SourcePathCache>; using NFP = QmlDesigner::SourcePath; +using QmlDesigner::Cache::SourceName; using QmlDesigner::SourcePathView; using QmlDesigner::SourcePathViews; -using QmlDesigner::Cache::SourceNameAndSourceContextId; class SourcePathCache : public testing::Test { protected: SourcePathCache() { - ON_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))) - .WillByDefault(Return(SourceContextId::create(5))); - ON_CALL(storageMock, fetchSourceContextId(Eq("/path2/to"))) - .WillByDefault(Return(SourceContextId::create(6))); - ON_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))) - .WillByDefault(Return(SourceId::create(42))); - ON_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file2.cpp"))) - .WillByDefault(Return(SourceId::create(63))); - ON_CALL(storageMock, fetchSourceId(SourceContextId::create(6), Eq("file.cpp"))) - .WillByDefault(Return(SourceId::create(72))); - ON_CALL(storageMock, fetchSourceContextPath(SourceContextId::create(5))) + ON_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).WillByDefault(Return(sourceContextId5)); + ON_CALL(storageMock, fetchSourceContextId(Eq("/path2/to"))).WillByDefault(Return(sourceContextId6)); + ON_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))).WillByDefault(Return(sourceNameId42)); + ON_CALL(storageMock, fetchSourceNameId(Eq("file2.cpp"))).WillByDefault(Return(sourceNameId63)); + ON_CALL(storageMock, fetchSourceContextPath(sourceContextId5)) .WillByDefault(Return(Utils::PathString("/path/to"))); - ON_CALL(storageMock, fetchSourceNameAndSourceContextId(SourceId::create(42))) - .WillByDefault( - Return(SourceNameAndSourceContextId("file.cpp", SourceContextId::create(5)))); - ON_CALL(storageMockFilled, fetchAllSources()) - .WillByDefault(Return(std::vector({ - {"file.cpp", SourceContextId::create(6), SourceId::create(72)}, - {"file2.cpp", SourceContextId::create(5), SourceId::create(63)}, - {"file.cpp", SourceContextId::create(5), SourceId::create(42)}, - }))); + ON_CALL(storageMock, fetchSourceName(sourceNameId42)).WillByDefault(Return("file.cpp")); + ON_CALL(storageMockFilled, fetchAllSourceNames()) + .WillByDefault(Return(std::vector( + {{"file.cpp", sourceNameId42}, {"file2.cpp", sourceNameId63}}))); ON_CALL(storageMockFilled, fetchAllSourceContexts()) .WillByDefault(Return(std::vector( - {{"/path2/to", SourceContextId::create(6)}, {"/path/to", SourceContextId::create(5)}}))); + {{"/path2/to", sourceContextId6}, {"/path/to", sourceContextId5}}))); ON_CALL(storageMockFilled, fetchSourceContextId(Eq("/path/to"))) - .WillByDefault(Return(SourceContextId::create(5))); - ON_CALL(storageMockFilled, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))) - .WillByDefault(Return(SourceId::create(42))); + .WillByDefault(Return(sourceContextId5)); + ON_CALL(storageMockFilled, fetchSourceNameId(Eq("file.cpp"))).WillByDefault(Return(sourceNameId42)); } protected: + SourceNameId sourceNameId42 = SourceNameId::create(42); + SourceNameId sourceNameId63 = SourceNameId::create(63); + SourceContextId sourceContextId5 = SourceContextId::create(5); + SourceContextId sourceContextId6 = SourceContextId::create(6); + SourceId sourceId542 = SourceId::create(sourceNameId42, sourceContextId5); + SourceId sourceId563 = SourceId::create(sourceNameId63, sourceContextId5); + SourceId sourceId642 = SourceId::create(sourceNameId42, sourceContextId6); NiceMock storageMock; Cache cache{storageMock}; NiceMock storageMockFilled; @@ -70,7 +66,7 @@ TEST_F(SourcePathCache, source_id_with_out_any_entry_call_source_context_id) TEST_F(SourcePathCache, source_id_with_out_any_entry_calls) { - EXPECT_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))); + EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))); cache.sourceId(SourcePathView("/path/to/file.cpp")); } @@ -79,7 +75,7 @@ TEST_F(SourcePathCache, source_id_of_source_id_with_out_any_entry) { auto sourceId = cache.sourceId(SourcePathView("/path/to/file.cpp")); - ASSERT_THAT(sourceId, SourceId::create(42)); + ASSERT_THAT(sourceId, sourceId542); } TEST_F(SourcePathCache, source_id_with_source_context_id_and_source_name) @@ -88,7 +84,7 @@ TEST_F(SourcePathCache, source_id_with_source_context_id_and_source_name) auto sourceId = cache.sourceId(sourceContextId, "file.cpp"_sv); - ASSERT_THAT(sourceId, SourceId::create(42)); + ASSERT_THAT(sourceId, sourceId542); } TEST_F(SourcePathCache, if_entry_exists_dont_call_in_strorage) @@ -96,7 +92,7 @@ TEST_F(SourcePathCache, if_entry_exists_dont_call_in_strorage) cache.sourceId(SourcePathView("/path/to/file.cpp")); EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0); - EXPECT_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))).Times(0); + EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))).Times(0); cache.sourceId(SourcePathView("/path/to/file.cpp")); } @@ -106,7 +102,7 @@ TEST_F(SourcePathCache, if_directory_entry_exists_dont_call_fetch_source_context cache.sourceId(SourcePathView("/path/to/file2.cpp")); EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0); - EXPECT_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))); + EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))); cache.sourceId(SourcePathView("/path/to/file.cpp")); } @@ -117,7 +113,7 @@ TEST_F(SourcePathCache, get_source_id_with_cached_value) auto sourceId = cache.sourceId(SourcePathView("/path/to/file.cpp")); - ASSERT_THAT(sourceId, SourceId::create(42)); + ASSERT_THAT(sourceId, sourceId542); } TEST_F(SourcePathCache, get_source_id_with_source_context_id_cached) @@ -126,7 +122,7 @@ TEST_F(SourcePathCache, get_source_id_with_source_context_id_cached) auto sourceId = cache.sourceId(SourcePathView("/path/to/file2.cpp")); - ASSERT_THAT(sourceId, SourceId::create(63)); + ASSERT_THAT(sourceId, sourceId563); } TEST_F(SourcePathCache, throw_for_getting_a_file_path_with_an_invalid_id) @@ -147,9 +143,7 @@ TEST_F(SourcePathCache, get_a_file_path) TEST_F(SourcePathCache, get_a_file_path_with_cached_source_id) { - SourceId sourceId{SourceId::create(42)}; - - auto sourcePath = cache.sourcePath(sourceId); + auto sourcePath = cache.sourcePath(sourceId542); ASSERT_THAT(sourcePath, Eq(SourcePathView{"/path/to/file.cpp"})); } @@ -199,7 +193,7 @@ TEST_F(SourcePathCache, source_context_id) { auto id = cache.sourceContextId(Utils::SmallString("/path/to")); - ASSERT_THAT(id, Eq(SourceContextId::create(5))); + ASSERT_THAT(id, Eq(sourceContextId5)); } TEST_F(SourcePathCache, source_context_id_is_already_in_cache) @@ -248,7 +242,7 @@ TEST_F(SourcePathCache, throw_for_getting_a_directory_path_with_an_invalid_id) TEST_F(SourcePathCache, get_a_directory_path) { - SourceContextId sourceContextId{SourceContextId::create(5)}; + SourceContextId sourceContextId{sourceContextId5}; auto sourceContextPath = cache.sourceContextPath(sourceContextId); @@ -257,7 +251,7 @@ TEST_F(SourcePathCache, get_a_directory_path) TEST_F(SourcePathCache, get_a_directory_path_with_cached_source_context_id) { - SourceContextId sourceContextId{SourceContextId::create(5)}; + SourceContextId sourceContextId{sourceContextId5}; cache.sourceContextPath(sourceContextId); auto sourceContextPath = cache.sourceContextPath(sourceContextId); @@ -267,65 +261,40 @@ TEST_F(SourcePathCache, get_a_directory_path_with_cached_source_context_id) TEST_F(SourcePathCache, directory_path_calls_fetch_directory_path) { - EXPECT_CALL(storageMock, fetchSourceContextPath(Eq(SourceContextId::create(5)))); + EXPECT_CALL(storageMock, fetchSourceContextPath(Eq(sourceContextId5))); - cache.sourceContextPath(SourceContextId::create(5)); + cache.sourceContextPath(sourceContextId5); } TEST_F(SourcePathCache, second_directory_path_calls_not_fetch_directory_path) { - cache.sourceContextPath(SourceContextId::create(5)); + cache.sourceContextPath(sourceContextId5); EXPECT_CALL(storageMock, fetchSourceContextPath(_)).Times(0); - cache.sourceContextPath(SourceContextId::create(5)); + cache.sourceContextPath(sourceContextId5); } -TEST_F(SourcePathCache, throw_for_getting_a_source_context_id_with_an_invalid_source_id) +TEST_F(SourcePathCache, fetch_source_context_from_source_id) { - SourceId sourceId; + auto sourceContextId = sourceId542.contextId(); - ASSERT_THROW(cache.sourceContextId(sourceId), QmlDesigner::NoSourcePathForInvalidSourceId); -} - -TEST_F(SourcePathCache, fetch_source_context_id_by_source_id) -{ - auto sourceContextId = cache.sourceContextId(SourceId::create(42)); - - ASSERT_THAT(sourceContextId, Eq(SourceContextId::create(5))); -} - -TEST_F(SourcePathCache, fetch_source_context_id_by_source_id_cached) -{ - cache.sourceContextId(SourceId::create(42)); - - auto sourceContextId = cache.sourceContextId(SourceId::create(42)); - - ASSERT_THAT(sourceContextId, Eq(SourceContextId::create(5))); -} - -TEST_F(SourcePathCache, fetch_file_path_after_fetching_source_context_id_by_source_id) -{ - cache.sourceContextId(SourceId::create(42)); - - auto sourcePath = cache.sourcePath(SourceId::create(42)); - - ASSERT_THAT(sourcePath, Eq("/path/to/file.cpp")); + ASSERT_THAT(sourceContextId, Eq(sourceContextId5)); } TEST_F(SourcePathCache, fetch_source_context_id_after_fetching_file_path_by_source_id) { - cache.sourcePath(SourceId::create(42)); + cache.sourcePath(sourceId542); - auto sourceContextId = cache.sourceContextId(SourceId::create(42)); + auto sourceContextId = sourceId542.contextId(); - ASSERT_THAT(sourceContextId, Eq(SourceContextId::create(5))); + ASSERT_THAT(sourceContextId, Eq(sourceContextId5)); } TEST_F(SourcePathCache, fetch_all_source_contexts_and_sources_at_creation) { EXPECT_CALL(storageMock, fetchAllSourceContexts()); - EXPECT_CALL(storageMock, fetchAllSources()); + EXPECT_CALL(storageMock, fetchAllSourceNames()); Cache cache{storageMock}; } @@ -336,23 +305,23 @@ TEST_F(SourcePathCache, get_file_id_in_filled_cache) auto id = cacheFilled.sourceId("/path2/to/file.cpp"); - ASSERT_THAT(id, Eq(SourceId::create(72))); + ASSERT_THAT(id, Eq(sourceId642)); } TEST_F(SourcePathCache, get_source_context_id_in_filled_cache) { Cache cacheFilled{storageMockFilled}; - auto id = cacheFilled.sourceContextId(SourceId::create(42)); + auto id = sourceId542.contextId(); - ASSERT_THAT(id, Eq(SourceContextId::create(5))); + ASSERT_THAT(id, Eq(sourceContextId5)); } TEST_F(SourcePathCache, get_directory_path_in_filled_cache) { Cache cacheFilled{storageMockFilled}; - auto path = cacheFilled.sourceContextPath(SourceContextId::create(5)); + auto path = cacheFilled.sourceContextPath(sourceContextId5); ASSERT_THAT(path, Eq("/path/to")); } @@ -361,7 +330,7 @@ TEST_F(SourcePathCache, get_file_path_in_filled_cache) { Cache cacheFilled{storageMockFilled}; - auto path = cacheFilled.sourcePath(SourceId::create(42)); + auto path = cacheFilled.sourcePath(sourceId542); ASSERT_THAT(path, Eq("/path/to/file.cpp")); } @@ -372,7 +341,7 @@ TEST_F(SourcePathCache, get_file_id_in_after_populate_if_empty) auto id = cacheNotFilled.sourceId("/path2/to/file.cpp"); - ASSERT_THAT(id, Eq(SourceId::create(72))); + ASSERT_THAT(id, Eq(sourceId642)); } TEST_F(SourcePathCache, dont_populate_if_not_empty) @@ -380,25 +349,16 @@ TEST_F(SourcePathCache, dont_populate_if_not_empty) cacheNotFilled.sourceId("/path/to/file.cpp"); EXPECT_CALL(storageMockFilled, fetchAllSourceContexts()).Times(0); - EXPECT_CALL(storageMockFilled, fetchAllSources()).Times(0); + EXPECT_CALL(storageMockFilled, fetchAllSourceNames()).Times(0); cacheNotFilled.populateIfEmpty(); } -TEST_F(SourcePathCache, get_source_context_id_after_populate_if_empty) -{ - cacheNotFilled.populateIfEmpty(); - - auto id = cacheNotFilled.sourceContextId(SourceId::create(42)); - - ASSERT_THAT(id, Eq(SourceContextId::create(5))); -} - TEST_F(SourcePathCache, get_directory_path_after_populate_if_empty) { cacheNotFilled.populateIfEmpty(); - auto path = cacheNotFilled.sourceContextPath(SourceContextId::create(5)); + auto path = cacheNotFilled.sourceContextPath(sourceContextId5); ASSERT_THAT(path, Eq("/path/to")); } @@ -407,7 +367,7 @@ TEST_F(SourcePathCache, get_file_path_after_populate_if_empty) { cacheNotFilled.populateIfEmpty(); - auto path = cacheNotFilled.sourcePath(SourceId::create(42)); + auto path = cacheNotFilled.sourcePath(sourceId542); ASSERT_THAT(path, Eq("/path/to/file.cpp")); } @@ -421,17 +381,18 @@ TEST_F(SourcePathCache, source_context_and_source_id_with_out_any_entry_call_sou TEST_F(SourcePathCache, source_context_and_source_id_with_out_any_entry_calls) { - EXPECT_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))); + EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))); cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp")); } TEST_F(SourcePathCache, source_context_and_source_id_of_source_id_with_out_any_entry) { - auto sourceContextAndSourceId = cache.sourceContextAndSourceId( - SourcePathView("/path/to/file.cpp")); + SourcePathView path("/path/to/file.cpp"); - ASSERT_THAT(sourceContextAndSourceId, Pair(SourceContextId::create(5), SourceId::create(42))); + auto sourceId = cache.sourceId(path); + + ASSERT_THAT(sourceId.contextId(), sourceContextId5); } TEST_F(SourcePathCache, source_context_and_source_id_if_entry_exists_dont_call_in_strorage) @@ -439,7 +400,7 @@ TEST_F(SourcePathCache, source_context_and_source_id_if_entry_exists_dont_call_i cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp")); EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0); - EXPECT_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))).Times(0); + EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))).Times(0); cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp")); } @@ -450,7 +411,7 @@ TEST_F(SourcePathCache, cache.sourceContextAndSourceId(SourcePathView("/path/to/file2.cpp")); EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0); - EXPECT_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))); + EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))); cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp")); } @@ -461,7 +422,7 @@ TEST_F(SourcePathCache, source_context_and_source_id_get_source_id_with_cached_v auto sourceId = cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp")); - ASSERT_THAT(sourceId, Pair(SourceContextId::create(5), SourceId::create(42))); + ASSERT_THAT(sourceId, Pair(sourceContextId5, sourceId542)); } TEST_F(SourcePathCache, get_source_context_and_source_id_with_source_context_id_cached) @@ -471,7 +432,7 @@ TEST_F(SourcePathCache, get_source_context_and_source_id_with_source_context_id_ auto sourceContextAndSourceId = cache.sourceContextAndSourceId( SourcePathView("/path/to/file2.cpp")); - ASSERT_THAT(sourceContextAndSourceId, Pair(SourceContextId::create(5), SourceId::create(63))); + ASSERT_THAT(sourceContextAndSourceId, Pair(sourceContextId5, sourceId563)); } TEST_F(SourcePathCache, get_source_context_and_source_id_file_names_are_unique_for_every_directory) diff --git a/tests/unit/tests/unittests/projectstorage/storagecache-test.cpp b/tests/unit/tests/unittests/projectstorage/storagecache-test.cpp index c95ea23a676..d9c8383ad9f 100644 --- a/tests/unit/tests/unittests/projectstorage/storagecache-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/storagecache-test.cpp @@ -214,10 +214,10 @@ TYPED_TEST(StorageCache, populate_with_empty_vector) TYPED_TEST(StorageCache, is_not_empty_after_populate_with_some_entries) { - typename TypeParam::CacheEntries entries{{this->filePath1.clone(), this->id1}, - {this->filePath2.clone(), this->id4}, - {this->filePath3.clone(), this->id3}, - {this->filePath4.clone(), SourceContextId::create(5)}}; + typename TypeParam::CacheEntries entries{{this->filePath1, this->id1}, + {this->filePath2, this->id4}, + {this->filePath3, this->id3}, + {this->filePath4, SourceContextId::create(5)}}; ON_CALL(this->mockStorage, fetchAllSourceContexts()).WillByDefault(Return(entries)); this->cache.uncheckedPopulate(); @@ -227,10 +227,10 @@ TYPED_TEST(StorageCache, is_not_empty_after_populate_with_some_entries) TYPED_TEST(StorageCache, get_entry_after_populate_with_some_entries) { - typename TypeParam::CacheEntries entries{{this->filePath1.clone(), this->id1}, - {this->filePath2.clone(), this->id2}, - {this->filePath3.clone(), SourceContextId::create(7)}, - {this->filePath4.clone(), this->id4}}; + typename TypeParam::CacheEntries entries{{this->filePath1, this->id1}, + {this->filePath2, this->id2}, + {this->filePath3, SourceContextId::create(7)}, + {this->filePath4, this->id4}}; ON_CALL(this->mockStorage, fetchAllSourceContexts()).WillByDefault(Return(entries)); this->cache.uncheckedPopulate(); @@ -241,10 +241,10 @@ TYPED_TEST(StorageCache, get_entry_after_populate_with_some_entries) TYPED_TEST(StorageCache, entries_have_unique_ids) { - typename TypeParam::CacheEntries entries{{this->filePath1.clone(), this->id1}, - {this->filePath2.clone(), this->id2}, - {this->filePath3.clone(), this->id3}, - {this->filePath4.clone(), this->id3}}; + typename TypeParam::CacheEntries entries{{this->filePath1, this->id1}, + {this->filePath2, this->id2}, + {this->filePath3, this->id3}, + {this->filePath4, this->id3}}; ON_CALL(this->mockStorage, fetchAllSourceContexts()).WillByDefault(Return(entries)); ASSERT_THROW(this->cache.populate(), StorageCacheException); @@ -252,10 +252,10 @@ TYPED_TEST(StorageCache, entries_have_unique_ids) TYPED_TEST(StorageCache, multiple_entries) { - typename TypeParam::CacheEntries entries{{this->filePath1.clone(), this->id1}, - {this->filePath1.clone(), this->id2}, - {this->filePath3.clone(), this->id3}, - {this->filePath4.clone(), this->id4}}; + typename TypeParam::CacheEntries entries{{this->filePath1, this->id1}, + {this->filePath1, this->id2}, + {this->filePath3, this->id3}, + {this->filePath4, this->id4}}; ON_CALL(this->mockStorage, fetchAllSourceContexts()).WillByDefault(Return(entries)); ASSERT_THROW(this->cache.populate(), StorageCacheException); diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/README.md b/tests/unit/tests/unittests/qmlprojectmanager/data/README.md index c73ef285904..afb4db417f5 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/README.md +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/README.md @@ -38,6 +38,9 @@ that QDS and QUL are aligned on the qmlproject format and that new features in Q qmlproject files for MCU projects. The test set will be tested in the Qt for MCUs repositories to make sure both the original and the converted qmlprojects build correctly. +The test set also includes some dummy qmlproject files to test that the converter correctly picks up +qmlproject modules in the same way Qt for MCUs does. + The qmlproject files in the test set aim to cover all the possible contents of a Qt for MCUs qmlproject, but since new features are added with every release, it is not guaranteed to be exhaustive. diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.qmltojson b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.qmltojson index e362cdf8860..d6e453fbfb1 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.qmltojson +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.qmltojson @@ -70,17 +70,26 @@ "files": [ ], "filters": [ + "*.bmp", + "*.dae", + "*.gif", + "*.hdr", + "*.ico", "*.jpeg", "*.jpg", - "*.png", - "*.svg", - "*.hdr", "*.ktx", - "*.bmp", - "*.ttf", + "*.pbm", + "*.pgm", + "*.png", + "*.ppm", + "*.svg", + "*.svgz", + "*.tif", "*.tiff", + "*.ttf", "*.webp", - "*.gif" + "*.xbm", + "*.xpm" ], "mcuProperties": { }, @@ -93,17 +102,26 @@ "files": [ ], "filters": [ + "*.bmp", + "*.dae", + "*.gif", + "*.hdr", + "*.ico", "*.jpeg", "*.jpg", - "*.png", - "*.svg", - "*.hdr", "*.ktx", - "*.bmp", - "*.ttf", + "*.pbm", + "*.pgm", + "*.png", + "*.ppm", + "*.svg", + "*.svgz", + "*.tif", "*.tiff", + "*.ttf", "*.webp", - "*.gif" + "*.xbm", + "*.xpm" ], "mcuProperties": { }, @@ -260,6 +278,8 @@ }, "otherProperties": { }, + "qmlprojectDependencies": [ + ], "runConfig": { "fileSelectors": [ ], diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.qmltojson b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.qmltojson index 80eaf6fefa3..da44366174b 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.qmltojson +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.qmltojson @@ -40,17 +40,26 @@ "files": [ ], "filters": [ + "*.bmp", + "*.dae", + "*.gif", + "*.hdr", + "*.ico", "*.jpeg", "*.jpg", - "*.png", - "*.svg", - "*.hdr", "*.ktx", - "*.bmp", - "*.ttf", + "*.pbm", + "*.pgm", + "*.png", + "*.ppm", + "*.svg", + "*.svgz", + "*.tif", "*.tiff", + "*.ttf", "*.webp", - "*.gif" + "*.xbm", + "*.xpm" ], "mcuProperties": { }, @@ -113,6 +122,8 @@ }, "otherProperties": { }, + "qmlprojectDependencies": [ + ], "runConfig": { "fileSelectors": [ "WXGA", diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.qmltojson b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.qmltojson index e362cdf8860..d6e453fbfb1 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.qmltojson +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.qmltojson @@ -70,17 +70,26 @@ "files": [ ], "filters": [ + "*.bmp", + "*.dae", + "*.gif", + "*.hdr", + "*.ico", "*.jpeg", "*.jpg", - "*.png", - "*.svg", - "*.hdr", "*.ktx", - "*.bmp", - "*.ttf", + "*.pbm", + "*.pgm", + "*.png", + "*.ppm", + "*.svg", + "*.svgz", + "*.tif", "*.tiff", + "*.ttf", "*.webp", - "*.gif" + "*.xbm", + "*.xpm" ], "mcuProperties": { }, @@ -93,17 +102,26 @@ "files": [ ], "filters": [ + "*.bmp", + "*.dae", + "*.gif", + "*.hdr", + "*.ico", "*.jpeg", "*.jpg", - "*.png", - "*.svg", - "*.hdr", "*.ktx", - "*.bmp", - "*.ttf", + "*.pbm", + "*.pgm", + "*.png", + "*.ppm", + "*.svg", + "*.svgz", + "*.tif", "*.tiff", + "*.ttf", "*.webp", - "*.gif" + "*.xbm", + "*.xpm" ], "mcuProperties": { }, @@ -260,6 +278,8 @@ }, "otherProperties": { }, + "qmlprojectDependencies": [ + ], "runConfig": { "fileSelectors": [ ], diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/mcu-modules/from_importpath/imported_module.qmlproject b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/mcu-modules/from_importpath/imported_module.qmlproject new file mode 100644 index 00000000000..237aa1dbc5d --- /dev/null +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/mcu-modules/from_importpath/imported_module.qmlproject @@ -0,0 +1,7 @@ +import QmlProject 1.3 + +Project { + MCU.Module { + uri: "from_importpath" + } +} diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/mcu-modules/from_importpath/mismatched_uri.qmlproject b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/mcu-modules/from_importpath/mismatched_uri.qmlproject new file mode 100644 index 00000000000..abd5f88245b --- /dev/null +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/mcu-modules/from_importpath/mismatched_uri.qmlproject @@ -0,0 +1,9 @@ +import QmlProject 1.3 + +// This qmlproject file will not be picked up from the import path "mcu-modules" +// since the URI doesn't match a relative path to the importPath +Project { + MCU.Module { + uri: "SomeModule" + } +} diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/mcu-modules/module.qmlproject b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/mcu-modules/module.qmlproject new file mode 100644 index 00000000000..fc9bcde9038 --- /dev/null +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/mcu-modules/module.qmlproject @@ -0,0 +1,8 @@ +import QmlProject 1.3 + +// This file will be picked up as an MCU module from importPaths +Project { + MCU.Module { + uri: "MyModule" + } +} diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/mcu-modules/no_module.qmlproject b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/mcu-modules/no_module.qmlproject new file mode 100644 index 00000000000..4b766c067a0 --- /dev/null +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/mcu-modules/no_module.qmlproject @@ -0,0 +1,5 @@ +import QmlProject 1.3 + +// This file will NOT be picked up as an MCU module from importPaths +Project { +} diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.jsontoqml b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.jsontoqml index 04911c40f89..0b5989a7719 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.jsontoqml +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.jsontoqml @@ -8,7 +8,7 @@ Project { targetDirectory: "/opt/UntitledProject13" enableCMakeGeneration: false widgetApp: true - importPaths: [ "imports","asset_imports" ] + importPaths: [ "imports","asset_imports","mcu-modules" ] qdsVersion: "4.0" quickVersion: "6.2" @@ -81,6 +81,10 @@ Project { MCU.qulModules: ["Controls","Timeline"] } + ModuleFiles { + directory: "../test-set-mcu-2" + } + FontFiles { files: [ "fonts/RobotoFonts.fmp" diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.qmlproject b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.qmlproject index 1b5b10ec18b..a6ea8113db8 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.qmlproject +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.qmlproject @@ -11,7 +11,7 @@ Project { mainFile: "Main.qml" supportedLanguages: ["no"] primaryLanguage: "en" - importPaths: [ "imports", "asset_imports" ] + importPaths: [ "imports", "asset_imports", "mcu-modules"] idBasedTranslations: true projectRootPath: ".." // END of common properties @@ -84,6 +84,10 @@ Project { ] } + ModuleFiles { + directory: "../test-set-mcu-2" + } + FontFiles { files: [ "fonts/RobotoFonts.fmp" diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.qmltojson b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.qmltojson index 634623c9cf2..557bcb80fb1 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.qmltojson +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.qmltojson @@ -43,17 +43,26 @@ "files": [ ], "filters": [ + "*.bmp", + "*.dae", + "*.gif", + "*.hdr", + "*.ico", "*.jpeg", "*.jpg", - "*.png", - "*.svg", - "*.hdr", "*.ktx", - "*.bmp", - "*.ttf", + "*.pbm", + "*.pgm", + "*.png", + "*.ppm", + "*.svg", + "*.svgz", + "*.tif", "*.tiff", + "*.ttf", "*.webp", - "*.gif" + "*.xbm", + "*.xpm" ], "mcuProperties": { }, @@ -108,6 +117,18 @@ }, "type": "Module" }, + { + "directory": "../test-set-mcu-2", + "files": [ + ], + "filters": [ + ], + "mcuProperties": { + }, + "otherProperties": { + }, + "type": "Module" + }, { "directory": "", "files": [ @@ -180,7 +201,8 @@ "fileVersion": 1, "importPaths": [ "imports", - "asset_imports" + "asset_imports", + "mcu-modules" ], "language": { "multiLanguageSupport": true, @@ -213,6 +235,12 @@ "idBasedTranslations": true, "projectRootPath": ".." }, + "qmlprojectDependencies": [ + "../test-set-mcu-2/testfile.qmlproject", + "mcu-modules/from_importpath/imported_module.qmlproject", + "mcu-modules/module.qmlproject", + "qmlproject/module/module.qmlproject" + ], "runConfig": { "fileSelectors": [ ], diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-2/testfile.qmltojson b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-2/testfile.qmltojson index 0ef011b615c..693a2a989e9 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-2/testfile.qmltojson +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-2/testfile.qmltojson @@ -46,6 +46,8 @@ "otherProperties": { "projectRootPath": "../.." }, + "qmlprojectDependencies": [ + ], "runConfig": { "fileSelectors": [ ] diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/mcu_project_with_modules.qmlproject b/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/mcu_project_with_modules.qmlproject new file mode 100644 index 00000000000..08f99b98e80 --- /dev/null +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/mcu_project_with_modules.qmlproject @@ -0,0 +1,15 @@ +import QmlProject 1.3 + +Project { + importPaths: [ "../converter/test-set-mcu-1/mcu-modules" ] + + mainFile: "Main.qml" + + ModuleFiles { + files: [ + "file1.qmlproject", + "file2.qmlproject" + ] + directory: "../converter/test-set-mcu-2" + } +} diff --git a/tests/unit/tests/unittests/qmlprojectmanager/projectitem-test.cpp b/tests/unit/tests/unittests/qmlprojectmanager/projectitem-test.cpp index 1e1d7d1189c..f3088a56bee 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/projectitem-test.cpp +++ b/tests/unit/tests/unittests/qmlprojectmanager/projectitem-test.cpp @@ -35,6 +35,11 @@ protected: Utils::FilePath::fromString(localTestDataDir + "/file-filters/MaterialBundle.qmlproject"), true); + + projectItemMcuWithModules = std::make_unique( + Utils::FilePath::fromString(localTestDataDir + + "/getter-setter/mcu_project_with_modules.qmlproject"), + true); } static void TearDownTestSuite() @@ -43,6 +48,7 @@ protected: projectItemWithQdsPrefix.reset(); projectItemWithoutQdsPrefix.reset(); projectItemFileFilters.reset(); + projectItemMcuWithModules.reset(); } protected: @@ -54,6 +60,7 @@ protected: localTestDataDir + "/getter-setter/empty.qmlproject"), true); inline static std::unique_ptr projectItemFileFilters; + inline static std::unique_ptr projectItemMcuWithModules; }; auto createAbsoluteFilePaths(const QStringList &fileList) @@ -159,7 +166,6 @@ TEST_F(QmlProjectItem, get_with_qds_prefix_supported_languages) TEST_F(QmlProjectItem, get_with_qds_prefix_primary_language) { auto primaryLanguage = projectItemWithQdsPrefix->primaryLanguage(); - ; ASSERT_THAT(primaryLanguage, Eq("en")); } @@ -311,7 +317,6 @@ TEST_F(QmlProjectItem, get_without_qds_prefix_supported_languages) TEST_F(QmlProjectItem, get_without_qds_prefix_primary_language) { auto primaryLanguage = projectItemWithoutQdsPrefix->primaryLanguage(); - ; ASSERT_THAT(primaryLanguage, Eq("en")); } @@ -600,7 +605,6 @@ TEST_F(QmlProjectItem, set_primary_language) projectItemSetters->setPrimaryLanguage("testing"); auto primaryLanguage = projectItemSetters->primaryLanguage(); - ; ASSERT_THAT(primaryLanguage, Eq("testing")); } @@ -656,8 +660,8 @@ TEST_F(QmlProjectItem, add_environment) { projectItemSetters->addToEnviroment("testing", "testing"); auto envs = projectItemSetters->environment(); - Utils::EnvironmentItems expectedEnvs; + expectedEnvs.push_back({"testing", "testing"}); ASSERT_EQ(envs, expectedEnvs); @@ -745,4 +749,24 @@ TEST_F(QmlProjectItem, not_matches_file) ASSERT_FALSE(fileFound); } +TEST_F(QmlProjectItem, qmlproject_modules) +{ + auto qmlProjectModules = projectItemMcuWithModules->qmlProjectModules(); + + ASSERT_THAT( + qmlProjectModules, + UnorderedElementsAre( + "file1.qmlproject", + "file2.qmlproject", + "../converter/test-set-mcu-1/mcu-modules/from_importpath/imported_module.qmlproject", + "../converter/test-set-mcu-2/testfile.qmlproject")); +} + +TEST_F(QmlProjectItem, no_qmlproject_modules) +{ + auto qmlProjectModules = projectItemEmpty->qmlProjectModules(); + + ASSERT_THAT(qmlProjectModules, IsEmpty()); +} + } // namespace diff --git a/tests/unit/tests/unittests/sqlite/createtablesqlstatementbuilder-test.cpp b/tests/unit/tests/unittests/sqlite/createtablesqlstatementbuilder-test.cpp index 8dcf71c2746..278238c57a6 100644 --- a/tests/unit/tests/unittests/sqlite/createtablesqlstatementbuilder-test.cpp +++ b/tests/unit/tests/unittests/sqlite/createtablesqlstatementbuilder-test.cpp @@ -24,7 +24,7 @@ using Sqlite::Unique; class CreateTableSqlStatementBuilder : public ::testing::Test { protected: - using Columns = ::Sqlite::Columns; + using Columns = ::Sqlite::StableReferenceColumns; using Builder = Sqlite::CreateTableSqlStatementBuilder; void bindValues() { @@ -554,7 +554,7 @@ TEST_F(CreateTableSqlStatementBuilder, blob_column_type_string_conversion) class CreateStrictTableSqlStatementBuilder : public ::testing::Test { protected: - using Columns = ::Sqlite::StrictColumns; + using Columns = ::Sqlite::StableReferenceStrictColumns; void bindValues() { diff --git a/tests/unit/tests/unittests/sqlite/sqlitestatement-test.cpp b/tests/unit/tests/unittests/sqlite/sqlitestatement-test.cpp index 24b20176eaa..41e1d988c1c 100644 --- a/tests/unit/tests/unittests/sqlite/sqlitestatement-test.cpp +++ b/tests/unit/tests/unittests/sqlite/sqlitestatement-test.cpp @@ -33,10 +33,13 @@ using Sqlite::ReadWriteStatement; using Sqlite::Value; using Sqlite::WriteStatement; -enum class BasicIdEnumeration { TestId }; +enum class BasicIdEnumeration { TestId, TestId2 }; using TestLongLongId = Sqlite::BasicId; using TestIntId = Sqlite::BasicId; +using TestIntId2 = Sqlite::BasicId; + +using CompoundId = Sqlite::CompoundBasicId; template bool compareValue(SqliteTestStatement<2, 1> &statement, Type value, int column) @@ -255,6 +258,19 @@ TEST_F(SqliteStatement, bind_invalid_int_id_to_null) ASSERT_THAT(readStatement.fetchType(0), Sqlite::Type::Null); } +TEST_F(SqliteStatement, bind_invalid_compound_id_to_null) +{ + CompoundId id; + SqliteTestStatement<0, 1> statement("INSERT INTO test VALUES ('id', 323, ?)", database); + + statement.bind(1, id); + statement.next(); + + SqliteTestStatement<1, 1> readStatement("SELECT value FROM test WHERE name='id'", database); + readStatement.next(); + ASSERT_THAT(readStatement.fetchType(0), Sqlite::Type::Null); +} + TEST_F(SqliteStatement, bind_int_id) { TestIntId id{TestIntId::create(42)}; @@ -269,6 +285,20 @@ TEST_F(SqliteStatement, bind_int_id) ASSERT_THAT(readStatement.fetchIntValue(0), 42); } +TEST_F(SqliteStatement, bind_compound_id) +{ + CompoundId id = CompoundId::create(42); + SqliteTestStatement<0, 1> statement("INSERT INTO test VALUES ('id', 323, ?)", database); + + statement.bind(1, id); + statement.next(); + + SqliteTestStatement<1, 1> readStatement("SELECT value FROM test WHERE name='id'", database); + readStatement.next(); + ASSERT_THAT(readStatement.fetchType(0), Sqlite::Type::Integer); + ASSERT_THAT(readStatement.fetchIntValue(0), 42); +} + TEST_F(SqliteStatement, bind_special_state_id) { enum class SpecialIdState { Unresolved = -1 }; @@ -1271,6 +1301,30 @@ TEST_F(SqliteStatement, get_single_int_id) ASSERT_THAT(value.internalId(), Eq(42)); } +TEST_F(SqliteStatement, get_single_invalid_compound_id) +{ + CompoundId id; + WriteStatement<1>("INSERT INTO test VALUES ('id', 323, ?)", database).write(id); + ReadStatement<1, 0> statement("SELECT value FROM test WHERE name='id'", database); + + auto value = statement.value(); + + ASSERT_FALSE(value.isValid()); +} + +TEST_F(SqliteStatement, get_single_compound_id) +{ + TestIntId testId = TestIntId::create(42); + TestIntId2 testId2 = TestIntId2::create(23); + CompoundId id = CompoundId::create(testId, testId2); + WriteStatement<1>("INSERT INTO test VALUES ('id', 323, ?)", database).write(id); + ReadStatement<1, 0> statement("SELECT value FROM test WHERE name='id'", database); + + auto value = statement.value(); + + ASSERT_THAT(value, Eq(id)); +} + TEST_F(SqliteStatement, get_value_calls_reset) { struct Value diff --git a/tests/unit/tests/unittests/sqlite/sqlitetable-test.cpp b/tests/unit/tests/unittests/sqlite/sqlitetable-test.cpp index e1b0427f3c7..ca6187743b1 100644 --- a/tests/unit/tests/unittests/sqlite/sqlitetable-test.cpp +++ b/tests/unit/tests/unittests/sqlite/sqlitetable-test.cpp @@ -40,7 +40,7 @@ TEST_F(SqliteTable, column_is_added_to_table) TEST_F(SqliteTable, set_table_name) { - table.setName(tableName.clone()); + table.setName(tableName); ASSERT_THAT(table.name(), tableName); } @@ -54,7 +54,7 @@ TEST_F(SqliteTable, set_use_without_rowid) TEST_F(SqliteTable, add_index) { - table.setName(tableName.clone()); + table.setName(tableName); auto &column = table.addColumn("name"); auto &column2 = table.addColumn("value"); @@ -67,7 +67,7 @@ TEST_F(SqliteTable, add_index) TEST_F(SqliteTable, initialize_table) { - table.setName(tableName.clone()); + table.setName(tableName); table.setUseIfNotExists(true); table.setUseTemporaryTable(true); table.setUseWithoutRowId(true); @@ -84,7 +84,7 @@ TEST_F(SqliteTable, initialize_table) TEST_F(SqliteTable, initialize_table_with_index) { InSequence sequence; - table.setName(tableName.clone()); + table.setName(tableName); auto &column = table.addColumn("name"); auto &column2 = table.addColumn("value"); table.addIndex({column}); @@ -104,7 +104,7 @@ TEST_F(SqliteTable, initialize_table_with_index) TEST_F(SqliteTable, initialize_table_with_unique_index) { InSequence sequence; - table.setName(tableName.clone()); + table.setName(tableName); auto &column = table.addColumn("name"); auto &column2 = table.addColumn("value"); table.addUniqueIndex({column}); @@ -302,7 +302,7 @@ TEST_F(SqliteTable, add_foreign_key_column_with_column_and_not_null) TEST_F(SqliteTable, add_primary_table_contraint) { - table.setName(tableName.clone()); + table.setName(tableName); const auto &idColumn = table.addColumn("id"); const auto &nameColumn = table.addColumn("name"); table.addPrimaryKeyContraint({idColumn, nameColumn}); @@ -331,7 +331,7 @@ TEST_F(StrictSqliteTable, column_is_added_to_table) TEST_F(StrictSqliteTable, set_table_name) { - table.setName(tableName.clone()); + table.setName(tableName); ASSERT_THAT(table.name(), tableName); } @@ -345,7 +345,7 @@ TEST_F(StrictSqliteTable, set_use_without_rowid) TEST_F(StrictSqliteTable, add_index) { - table.setName(tableName.clone()); + table.setName(tableName); auto &column = table.addColumn("name"); auto &column2 = table.addColumn("value"); @@ -358,7 +358,7 @@ TEST_F(StrictSqliteTable, add_index) TEST_F(StrictSqliteTable, initialize_table) { - table.setName(tableName.clone()); + table.setName(tableName); table.setUseIfNotExists(true); table.setUseTemporaryTable(true); table.setUseWithoutRowId(true); @@ -375,7 +375,7 @@ TEST_F(StrictSqliteTable, initialize_table) TEST_F(StrictSqliteTable, initialize_table_with_index) { InSequence sequence; - table.setName(tableName.clone()); + table.setName(tableName); auto &column = table.addColumn("name"); auto &column2 = table.addColumn("value"); table.addIndex({column}); @@ -395,7 +395,7 @@ TEST_F(StrictSqliteTable, initialize_table_with_index) TEST_F(StrictSqliteTable, initialize_table_with_unique_index) { InSequence sequence; - table.setName(tableName.clone()); + table.setName(tableName); auto &column = table.addColumn("name"); auto &column2 = table.addColumn("value"); table.addUniqueIndex({column}); @@ -599,7 +599,7 @@ TEST_F(StrictSqliteTable, add_foreign_key_column_with_column_and_not_null) TEST_F(StrictSqliteTable, add_primary_table_contraint) { - table.setName(tableName.clone()); + table.setName(tableName); const auto &idColumn = table.addColumn("id"); const auto &nameColumn = table.addColumn("name"); table.addPrimaryKeyContraint({idColumn, nameColumn}); diff --git a/tests/unit/tests/unittests/utils/smallstring-test.cpp b/tests/unit/tests/unittests/utils/smallstring-test.cpp index 71090f8760a..6b5af085ba7 100644 --- a/tests/unit/tests/unittests/utils/smallstring-test.cpp +++ b/tests/unit/tests/unittests/utils/smallstring-test.cpp @@ -11,35 +11,54 @@ #include -using Utils::PathString; -using Utils::SmallString; +namespace { + using Utils::SmallStringLiteral; using Utils::SmallStringView; static_assert(32 == sizeof(Utils::BasicSmallString<31>)); -static_assert(64 == sizeof(Utils::BasicSmallString<63>)); -static_assert(192 == sizeof(Utils::BasicSmallString<190>)); +static_assert(80 == sizeof(Utils::BasicSmallString<64>)); +static_assert(192 == sizeof(Utils::BasicSmallString<176>)); static_assert(16 == alignof(Utils::BasicSmallString<31>)); -static_assert(16 == alignof(Utils::BasicSmallString<63>)); -static_assert(16 == alignof(Utils::BasicSmallString<190>)); +static_assert(16 == alignof(Utils::BasicSmallString<64>)); +static_assert(16 == alignof(Utils::BasicSmallString<192>)); -TEST(SmallString, basic_string_equal) +template +class SmallString : public testing::Test { - ASSERT_THAT(SmallString("text"), Eq(SmallString("text"))); +public: + using String = StringType; +}; + +using StringTypes = ::testing::Types, Utils::BasicSmallString<64>, Utils::PathString>; +TYPED_TEST_SUITE(SmallString, StringTypes); + +TYPED_TEST(SmallString, basic_string_equal) +{ + using SmallString = typename TestFixture::String; + SmallString text("text"); + + ASSERT_THAT(text, Eq(SmallString("text"))); } -TEST(SmallString, basic_small_string_unequal) +TYPED_TEST(SmallString, basic_small_string_unequal) { - ASSERT_THAT(SmallString("text"), Ne(SmallString("other text"))); + using SmallString = typename TestFixture::String; + SmallString text("text"); + + ASSERT_THAT(text, Ne(SmallString("other text"))); } -TEST(SmallString, null_small_string_is_equal_to_empty_small_string) +TYPED_TEST(SmallString, null_small_string_is_equal_to_empty_small_string) { - ASSERT_THAT(SmallString(), Eq(SmallString(""))); + using SmallString = typename TestFixture::String; + SmallString defaultString; + + ASSERT_THAT(defaultString, Eq(SmallString(""))); } -TEST(SmallString, short_small_string_literal_is_short_small_string) +TYPED_TEST(SmallString, short_small_string_literal_is_short_small_string) { // constexpr SmallStringLiteral shortText("short string"); @@ -47,15 +66,17 @@ TEST(SmallString, short_small_string_literal_is_short_small_string) ASSERT_TRUE(shortText.isShortString()); } -TEST(SmallString, short_small_string_is_short_small_string) +TYPED_TEST(SmallString, short_small_string_is_short_small_string) { + using SmallString = typename TestFixture::String; SmallString shortText("short string"); ASSERT_TRUE(shortText.isShortString()); } -TEST(SmallString, create_from_c_string_iterators) +TYPED_TEST(SmallString, create_from_c_string_iterators) { + using SmallString = typename TestFixture::String; char sourceText[] = "this is very very very very very much text"; SmallString text(sourceText, &sourceText[sizeof(sourceText) - 1]); @@ -63,8 +84,9 @@ TEST(SmallString, create_from_c_string_iterators) ASSERT_THAT(text, SmallString("this is very very very very very much text")); } -TEST(SmallString, create_from_q_byte_array_iterators) +TYPED_TEST(SmallString, create_from_q_byte_array_iterators) { + using SmallString = typename TestFixture::String; QByteArray sourceText = "this is very very very very very much text"; SmallString text(sourceText.begin(), sourceText.end()); @@ -72,8 +94,9 @@ TEST(SmallString, create_from_q_byte_array_iterators) ASSERT_THAT(text, SmallString("this is very very very very very much text")); } -TEST(SmallString, create_from_small_string_iterators) +TYPED_TEST(SmallString, create_from_small_string_iterators) { + using SmallString = typename TestFixture::String; SmallString sourceText = "this is very very very very very much text"; SmallString text(sourceText.begin(), sourceText.end()); @@ -81,8 +104,9 @@ TEST(SmallString, create_from_small_string_iterators) ASSERT_THAT(text, SmallString("this is very very very very very much text")); } -TEST(SmallString, create_from_string_view) +TYPED_TEST(SmallString, create_from_string_view) { + using SmallString = typename TestFixture::String; SmallStringView sourceText = "this is very very very very very much text"; SmallString text(sourceText); @@ -90,80 +114,64 @@ TEST(SmallString, create_from_string_view) ASSERT_THAT(text, SmallString("this is very very very very very much text")); } -TEST(SmallString, short_small_string_is_reference) +TYPED_TEST(SmallString, short_small_string_is_reference) { - SmallString longText("very very very very very long text"); + Utils::SmallString longText("very very very very very long text"); ASSERT_TRUE(longText.isReadOnlyReference()); } -TEST(SmallString, small_string_contructor_is_not_reference) +TYPED_TEST(SmallString, small_string_contructor_is_not_reference) { + using SmallString = typename TestFixture::String; const char *shortCSmallString = "short string"; auto shortText = SmallString(shortCSmallString); ASSERT_TRUE(shortText.isShortString()); } -TEST(SmallString, short_small_string_is_not_reference) +TYPED_TEST(SmallString, short_small_string_is_not_reference) { + using SmallString = typename TestFixture::String; const char *shortCSmallString = "short string"; auto shortText = SmallString::fromUtf8(shortCSmallString); ASSERT_FALSE(shortText.isReadOnlyReference()); } -TEST(SmallString, long_small_string_construtor_is_allocated) +TYPED_TEST(SmallString, long_small_string_construtor_is_allocated) { const char *longCSmallString = "very very very very very long text"; - auto longText = SmallString(longCSmallString); + auto longText = Utils::SmallString(longCSmallString); ASSERT_TRUE(longText.hasAllocatedMemory()); } -TEST(SmallString, maximum_short_small_string) +TYPED_TEST(SmallString, maximum_short_small_string) { + using SmallString = typename TestFixture::String; SmallString maximumShortText("very very very very short text", 30); ASSERT_THAT(maximumShortText, StrEq("very very very very short text")); } -TEST(SmallString, long_const_expression_small_string_is_reference) +TYPED_TEST(SmallString, long_const_expression_small_string_is_reference) { - SmallString longText("very very very very very very very very very very very long string"); + using SmallString = typename TestFixture::String; + SmallString longText( + "very very very very very very very very very very very long string very very very very " + "very very very very very very very long string very very very very very very very very " + "very very very long string very very very very very very very very very very very long " + "string very very very very very very very very very very very long string very very very " + "very very very very very very very very long string very very very very very very very " + "very very very very long string"); ASSERT_TRUE(longText.isReadOnlyReference()); } -TEST(SmallString, clone_short_small_string) -{ - SmallString shortText("short string"); - - auto clonedText = shortText.clone(); - - ASSERT_THAT(clonedText, Eq("short string")); -} - -TEST(SmallString, clone_long_small_string) -{ - SmallString longText = SmallString::fromUtf8("very very very very very very very very very very very long string"); - - auto clonedText = longText.clone(); - - ASSERT_THAT(clonedText, Eq("very very very very very very very very very very very long string")); -} - -TEST(SmallString, cloned_long_small_string_data_pointer_is_different) -{ - SmallString longText = SmallString::fromUtf8("very very very very very very very very very very very long string"); - - auto clonedText = longText.clone(); - - ASSERT_THAT(clonedText.data(), Ne(longText.data())); -} - -TEST(SmallString, copy_short_const_expression_small_string_is_short_small_string) +TYPED_TEST(SmallString, copy_short_const_expression_small_string_is_short_small_string) { + using SmallString = typename TestFixture::String; SmallString shortText("short string"); auto shortTextCopy = shortText; @@ -171,35 +179,50 @@ TEST(SmallString, copy_short_const_expression_small_string_is_short_small_string ASSERT_TRUE(shortTextCopy.isShortString()); } -TEST(SmallString, copy_long_const_expression_small_string_is_long_small_string) +TYPED_TEST(SmallString, copy_long_const_expression_small_string_is_long_small_string) { - SmallString longText("very very very very very very very very very very very long string"); + using SmallString = typename TestFixture::String; + SmallString longText( + "very very very very very very very very very very very long string very very very very " + "very very very very very very very long string very very very very very very very very " + "very very very long string very very very very very very very very very very very long " + "string very very very very very very very very very very very long string very very very " + "very very very very very very very very long string very very very very very very very " + "very very very very long string"); auto longTextCopy = longText; ASSERT_FALSE(longTextCopy.isShortString()); } -TEST(SmallString, short_path_string_is_short_string) +TYPED_TEST(SmallString, short_path_string_is_short_string) { const char *rawText = "very very very very very very very very very very very long path which fits in the short memory"; - PathString text(rawText); + Utils::PathString text(rawText); ASSERT_TRUE(text.isShortString()); } -TEST(SmallString, small_string_from_character_array_is_reference) +TYPED_TEST(SmallString, small_string_from_character_array_is_reference) { - const char longCString[] = "very very very very very very very very very very very long string"; + using SmallString = typename TestFixture::String; + const char longCString[] + = "very very very very very very very very very very very long string very very very very " + "very very very very very very very long string very very very very very very very very " + "very very very long string very very very very very very very very very very very long " + "string very very very very very very very very very very very long string very very " + "very very very very very very very very very long string very very very very very very " + "very very very very very long string"; SmallString longString(longCString); ASSERT_TRUE(longString.isReadOnlyReference()); } -TEST(SmallString, small_string_from_character_pointer_is_not_reference) +TYPED_TEST(SmallString, small_string_from_character_pointer_is_not_reference) { + using SmallString = typename TestFixture::String; const char *longCString = "very very very very very very very very very very very long string"; SmallString longString = SmallString::fromUtf8(longCString); @@ -207,9 +230,16 @@ TEST(SmallString, small_string_from_character_pointer_is_not_reference) ASSERT_FALSE(longString.isReadOnlyReference()); } -TEST(SmallString, copy_string_from_reference) +TYPED_TEST(SmallString, copy_string_from_reference) { - SmallString longText("very very very very very very very very very very very long string"); + using SmallString = typename TestFixture::String; + SmallString longText( + "very very very very very very very very very very very long string very very very very " + "very very very very very very very long string very very very very very very very very " + "very very very long string very very very very very very very very very very very long " + "string very very very very very very very very very very very long string very very " + "very very very very very very very very very long string very very very very very very " + "very very very very very long string"); SmallString longTextCopy; longTextCopy = longText; @@ -217,66 +247,68 @@ TEST(SmallString, copy_string_from_reference) ASSERT_TRUE(longTextCopy.isReadOnlyReference()); } -TEST(SmallString, small_string_literal_short_small_string_data_access) +TYPED_TEST(SmallString, small_string_literal_short_small_string_data_access) { - SmallStringLiteral literalText("very very very very very very very very very very very long string"); + SmallStringLiteral literalText( + "very very very very very very very very very very very long string"); ASSERT_THAT(literalText, StrEq("very very very very very very very very very very very long string")); } -TEST(SmallString, small_string_literal_long_small_string_data_access) +TYPED_TEST(SmallString, small_string_literal_long_small_string_data_access) { SmallStringLiteral literalText("short string"); ASSERT_THAT(literalText, StrEq("short string")); } -TEST(SmallString, reference_data_access) +TYPED_TEST(SmallString, reference_data_access) { + using SmallString = typename TestFixture::String; + SmallString literalText("short string"); ASSERT_THAT(literalText, StrEq("short string")); } -TEST(SmallString, short_data_access) +TYPED_TEST(SmallString, short_data_access) { + using SmallString = typename TestFixture::String; const char *shortCString = "short string"; auto shortText = SmallString::fromUtf8(shortCString); ASSERT_THAT(shortText, StrEq("short string")); } -TEST(SmallString, long_data_access) +TYPED_TEST(SmallString, long_data_access) { + using SmallString = typename TestFixture::String; const char *longCString = "very very very very very very very very very very very long string"; auto longText = SmallString::fromUtf8(longCString); ASSERT_THAT(longText, StrEq(longCString)); } -TEST(SmallString, long_small_string_has_short_small_string_size_zero) +TYPED_TEST(SmallString, small_string_begin_is_equal_end_for_empty_small_string) { - auto longText = SmallString::fromUtf8("very very very very very very very very very very very long string"); + using SmallString = typename TestFixture::String; - ASSERT_THAT(longText.shortStringSize(), 0); -} - -TEST(SmallString, small_string_begin_is_equal_end_for_empty_small_string) -{ SmallString text; ASSERT_THAT(text.begin(), Eq(text.end())); } -TEST(SmallString, small_string_begin_is_not_equal_end_for_non_empty_small_string) +TYPED_TEST(SmallString, small_string_begin_is_not_equal_end_for_non_empty_small_string) { + using SmallString = typename TestFixture::String; SmallString text("x"); ASSERT_THAT(text.begin(), Ne(text.end())); } -TEST(SmallString, small_string_begin_plus_one_is_equal_end_for_small_string_width_size_one) +TYPED_TEST(SmallString, small_string_begin_plus_one_is_equal_end_for_small_string_width_size_one) { + using SmallString = typename TestFixture::String; SmallString text("x"); auto beginPlusOne = text.begin() + std::size_t(1); @@ -284,22 +316,27 @@ TEST(SmallString, small_string_begin_plus_one_is_equal_end_for_small_string_widt ASSERT_THAT(beginPlusOne, Eq(text.end())); } -TEST(SmallString, small_string_r_begin_is_equal_r_end_for_empty_small_string) +TYPED_TEST(SmallString, small_string_r_begin_is_equal_r_end_for_empty_small_string) { + using SmallString = typename TestFixture::String; + SmallString text; ASSERT_THAT(text.rbegin(), Eq(text.rend())); } -TEST(SmallString, small_string_r_begin_is_not_equal_r_end_for_non_empty_small_string) +TYPED_TEST(SmallString, small_string_r_begin_is_not_equal_r_end_for_non_empty_small_string) { + using SmallString = typename TestFixture::String; + SmallString text("x"); ASSERT_THAT(text.rbegin(), Ne(text.rend())); } -TEST(SmallString, small_string_r_begin_plus_one_is_equal_r_end_for_small_string_width_size_one) +TYPED_TEST(SmallString, small_string_r_begin_plus_one_is_equal_r_end_for_small_string_width_size_one) { + using SmallString = typename TestFixture::String; SmallString text("x"); auto beginPlusOne = text.rbegin() + 1l; @@ -307,22 +344,26 @@ TEST(SmallString, small_string_r_begin_plus_one_is_equal_r_end_for_small_string_ ASSERT_THAT(beginPlusOne, Eq(text.rend())); } -TEST(SmallString, small_string_const_r_begin_is_equal_r_end_for_empty_small_string) +TYPED_TEST(SmallString, small_string_const_r_begin_is_equal_r_end_for_empty_small_string) { + using SmallString = typename TestFixture::String; const SmallString text; ASSERT_THAT(text.rbegin(), Eq(text.rend())); } -TEST(SmallString, small_string_const_r_begin_is_not_equal_r_end_for_non_empty_small_string) +TYPED_TEST(SmallString, small_string_const_r_begin_is_not_equal_r_end_for_non_empty_small_string) { + using SmallString = typename TestFixture::String; const SmallString text("x"); ASSERT_THAT(text.rbegin(), Ne(text.rend())); } -TEST(SmallString, small_string_small_string_const_r_begin_plus_one_is_equal_r_end_for_small_string_width_size_one) +TYPED_TEST(SmallString, + small_string_small_string_const_r_begin_plus_one_is_equal_r_end_for_small_string_width_size_one) { + using SmallString = typename TestFixture::String; const SmallString text("x"); auto beginPlusOne = text.rbegin() + 1l; @@ -330,8 +371,9 @@ TEST(SmallString, small_string_small_string_const_r_begin_plus_one_is_equal_r_en ASSERT_THAT(beginPlusOne, Eq(text.rend())); } -TEST(SmallString, small_string_distance_between_begin_and_end_is_zero_for_empty_text) +TYPED_TEST(SmallString, small_string_distance_between_begin_and_end_is_zero_for_empty_text) { + using SmallString = typename TestFixture::String; SmallString text(""); auto distance = std::distance(text.begin(), text.end()); @@ -339,8 +381,9 @@ TEST(SmallString, small_string_distance_between_begin_and_end_is_zero_for_empty_ ASSERT_THAT(distance, 0); } -TEST(SmallString, small_string_distance_between_begin_and_end_is_one_for_one_sign) +TYPED_TEST(SmallString, small_string_distance_between_begin_and_end_is_one_for_one_sign) { + using SmallString = typename TestFixture::String; SmallString text("x"); auto distance = std::distance(text.begin(), text.end()); @@ -348,8 +391,9 @@ TEST(SmallString, small_string_distance_between_begin_and_end_is_one_for_one_sig ASSERT_THAT(distance, 1); } -TEST(SmallString, small_string_distance_between_r_begin_and_r_end_is_zero_for_empty_text) +TYPED_TEST(SmallString, small_string_distance_between_r_begin_and_r_end_is_zero_for_empty_text) { + using SmallString = typename TestFixture::String; SmallString text(""); auto distance = std::distance(text.rbegin(), text.rend()); @@ -357,8 +401,9 @@ TEST(SmallString, small_string_distance_between_r_begin_and_r_end_is_zero_for_em ASSERT_THAT(distance, 0); } -TEST(SmallString, small_string_distance_between_r_begin_and_r_end_is_one_for_one_sign) +TYPED_TEST(SmallString, small_string_distance_between_r_begin_and_r_end_is_one_for_one_sign) { + using SmallString = typename TestFixture::String; SmallString text("x"); auto distance = std::distance(text.rbegin(), text.rend()); @@ -366,8 +411,9 @@ TEST(SmallString, small_string_distance_between_r_begin_and_r_end_is_one_for_one ASSERT_THAT(distance, 1); } -TEST(SmallString, small_string_begin_points_to_x) +TYPED_TEST(SmallString, small_string_begin_points_to_x) { + using SmallString = typename TestFixture::String; SmallString text("x"); auto sign = *text.begin(); @@ -375,8 +421,9 @@ TEST(SmallString, small_string_begin_points_to_x) ASSERT_THAT(sign, 'x'); } -TEST(SmallString, small_string_r_begin_points_to_x) +TYPED_TEST(SmallString, small_string_r_begin_points_to_x) { + using SmallString = typename TestFixture::String; SmallString text("x"); auto sign = *text.rbegin(); @@ -384,8 +431,9 @@ TEST(SmallString, small_string_r_begin_points_to_x) ASSERT_THAT(sign, 'x'); } -TEST(SmallString, const_small_string_begin_points_to_x) +TYPED_TEST(SmallString, const_small_string_begin_points_to_x) { + using SmallString = typename TestFixture::String; const SmallString text("x"); auto sign = *text.begin(); @@ -393,8 +441,9 @@ TEST(SmallString, const_small_string_begin_points_to_x) ASSERT_THAT(sign, 'x'); } -TEST(SmallString, const_small_string_r_begin_points_to_x) +TYPED_TEST(SmallString, const_small_string_r_begin_points_to_x) { + using SmallString = typename TestFixture::String; const SmallString text("x"); auto sign = *text.rbegin(); @@ -402,21 +451,21 @@ TEST(SmallString, const_small_string_r_begin_points_to_x) ASSERT_THAT(sign, 'x'); } -TEST(SmallString, small_string_view_begin_is_equal_end_for_empty_small_string) +TYPED_TEST(SmallString, small_string_view_begin_is_equal_end_for_empty_small_string) { SmallStringView text{""}; ASSERT_THAT(text.begin(), Eq(text.end())); } -TEST(SmallString, small_string_view_begin_is_not_equal_end_for_non_empty_small_string) +TYPED_TEST(SmallString, small_string_view_begin_is_not_equal_end_for_non_empty_small_string) { SmallStringView text("x"); ASSERT_THAT(text.begin(), Ne(text.end())); } -TEST(SmallString, small_string_view_begin_plus_one_is_equal_end_for_small_string_width_size_one) +TYPED_TEST(SmallString, small_string_view_begin_plus_one_is_equal_end_for_small_string_width_size_one) { SmallStringView text("x"); @@ -425,21 +474,22 @@ TEST(SmallString, small_string_view_begin_plus_one_is_equal_end_for_small_string ASSERT_THAT(beginPlusOne, Eq(text.end())); } -TEST(SmallString, small_string_view_r_begin_is_equal_r_end_for_empty_small_string) +TYPED_TEST(SmallString, small_string_view_r_begin_is_equal_r_end_for_empty_small_string) { SmallStringView text{""}; ASSERT_THAT(text.rbegin(), Eq(text.rend())); } -TEST(SmallString, small_string_view_r_begin_is_not_equal_r_end_for_non_empty_small_string) +TYPED_TEST(SmallString, small_string_view_r_begin_is_not_equal_r_end_for_non_empty_small_string) { SmallStringView text("x"); ASSERT_THAT(text.rbegin(), Ne(text.rend())); } -TEST(SmallString, small_string_view_r_begin_plus_one_is_equal_r_end_for_small_string_width_size_one) +TYPED_TEST(SmallString, + small_string_view_r_begin_plus_one_is_equal_r_end_for_small_string_width_size_one) { SmallStringView text("x"); @@ -448,21 +498,22 @@ TEST(SmallString, small_string_view_r_begin_plus_one_is_equal_r_end_for_small_st ASSERT_THAT(beginPlusOne, Eq(text.rend())); } -TEST(SmallString, small_string_view_const_r_begin_is_equal_r_end_for_empty_small_string) +TYPED_TEST(SmallString, small_string_view_const_r_begin_is_equal_r_end_for_empty_small_string) { const SmallStringView text{""}; ASSERT_THAT(text.rbegin(), Eq(text.rend())); } -TEST(SmallString, small_string_view_const_r_begin_is_not_equal_r_end_for_non_empty_small_string) +TYPED_TEST(SmallString, small_string_view_const_r_begin_is_not_equal_r_end_for_non_empty_small_string) { const SmallStringView text("x"); ASSERT_THAT(text.rbegin(), Ne(text.rend())); } -TEST(SmallString, small_string_view_const_r_begin_plus_one_is_equal_r_end_for_small_string_width_size_one) +TYPED_TEST(SmallString, + small_string_view_const_r_begin_plus_one_is_equal_r_end_for_small_string_width_size_one) { const SmallStringView text("x"); @@ -471,7 +522,7 @@ TEST(SmallString, small_string_view_const_r_begin_plus_one_is_equal_r_end_for_sm ASSERT_THAT(beginPlusOne, Eq(text.rend())); } -TEST(SmallString, small_string_view_distance_between_begin_and_end_is_zero_for_empty_text) +TYPED_TEST(SmallString, small_string_view_distance_between_begin_and_end_is_zero_for_empty_text) { SmallStringView text(""); @@ -480,7 +531,7 @@ TEST(SmallString, small_string_view_distance_between_begin_and_end_is_zero_for_e ASSERT_THAT(distance, 0); } -TEST(SmallString, small_string_view_distance_between_begin_and_end_is_one_for_one_sign) +TYPED_TEST(SmallString, small_string_view_distance_between_begin_and_end_is_one_for_one_sign) { SmallStringView text("x"); @@ -489,7 +540,7 @@ TEST(SmallString, small_string_view_distance_between_begin_and_end_is_one_for_on ASSERT_THAT(distance, 1); } -TEST(SmallString, small_string_view_distance_between_r_begin_and_r_end_is_zero_for_empty_text) +TYPED_TEST(SmallString, small_string_view_distance_between_r_begin_and_r_end_is_zero_for_empty_text) { SmallStringView text(""); @@ -498,7 +549,7 @@ TEST(SmallString, small_string_view_distance_between_r_begin_and_r_end_is_zero_f ASSERT_THAT(distance, 0); } -TEST(SmallString, small_string_view_distance_between_r_begin_and_r_end_is_one_for_one_sign) +TYPED_TEST(SmallString, small_string_view_distance_between_r_begin_and_r_end_is_one_for_one_sign) { SmallStringView text("x"); @@ -507,7 +558,7 @@ TEST(SmallString, small_string_view_distance_between_r_begin_and_r_end_is_one_fo ASSERT_THAT(distance, 1); } -TEST(SmallString, const_small_string_view_distance_between_begin_and_end_is_zero_for_empty_text) +TYPED_TEST(SmallString, const_small_string_view_distance_between_begin_and_end_is_zero_for_empty_text) { const SmallStringView text(""); @@ -516,7 +567,7 @@ TEST(SmallString, const_small_string_view_distance_between_begin_and_end_is_zero ASSERT_THAT(distance, 0); } -TEST(SmallString, const_small_string_view_distance_between_begin_and_end_is_one_for_one_sign) +TYPED_TEST(SmallString, const_small_string_view_distance_between_begin_and_end_is_one_for_one_sign) { const SmallStringView text("x"); @@ -525,7 +576,8 @@ TEST(SmallString, const_small_string_view_distance_between_begin_and_end_is_one_ ASSERT_THAT(distance, 1); } -TEST(SmallString, const_small_string_view_distance_between_r_begin_and_r_end_is_zero_for_empty_text) +TYPED_TEST(SmallString, + const_small_string_view_distance_between_r_begin_and_r_end_is_zero_for_empty_text) { const SmallStringView text(""); @@ -534,7 +586,7 @@ TEST(SmallString, const_small_string_view_distance_between_r_begin_and_r_end_is_ ASSERT_THAT(distance, 0); } -TEST(SmallString, const_small_string_view_distance_between_r_begin_and_r_end_is_one_for_one_sign) +TYPED_TEST(SmallString, const_small_string_view_distance_between_r_begin_and_r_end_is_one_for_one_sign) { const SmallStringView text("x"); @@ -543,7 +595,7 @@ TEST(SmallString, const_small_string_view_distance_between_r_begin_and_r_end_is_ ASSERT_THAT(distance, 1); } -TEST(SmallString, small_string_view_begin_points_to_x) +TYPED_TEST(SmallString, small_string_view_begin_points_to_x) { SmallStringView text("x"); @@ -552,7 +604,7 @@ TEST(SmallString, small_string_view_begin_points_to_x) ASSERT_THAT(sign, 'x'); } -TEST(SmallString, small_string_view_r_begin_points_to_x) +TYPED_TEST(SmallString, small_string_view_r_begin_points_to_x) { SmallStringView text("x"); @@ -561,7 +613,7 @@ TEST(SmallString, small_string_view_r_begin_points_to_x) ASSERT_THAT(sign, 'x'); } -TEST(SmallString, const_small_string_view_begin_points_to_x) +TYPED_TEST(SmallString, const_small_string_view_begin_points_to_x) { const SmallStringView text("x"); @@ -570,7 +622,7 @@ TEST(SmallString, const_small_string_view_begin_points_to_x) ASSERT_THAT(sign, 'x'); } -TEST(SmallString, const_small_string_view_r_begin_points_to_x) +TYPED_TEST(SmallString, const_small_string_view_r_begin_points_to_x) { const SmallStringView text("x"); @@ -579,7 +631,7 @@ TEST(SmallString, const_small_string_view_r_begin_points_to_x) ASSERT_THAT(sign, 'x'); } -TEST(SmallString, small_string_literal_view_r_begin_points_to_x) +TYPED_TEST(SmallString, small_string_literal_view_r_begin_points_to_x) { SmallStringLiteral text("x"); @@ -588,7 +640,7 @@ TEST(SmallString, small_string_literal_view_r_begin_points_to_x) ASSERT_THAT(sign, 'x'); } -TEST(SmallString, const_small_string_literal_view_r_begin_points_to_x) +TYPED_TEST(SmallString, const_small_string_literal_view_r_begin_points_to_x) { const SmallStringLiteral text("x"); @@ -597,8 +649,9 @@ TEST(SmallString, const_small_string_literal_view_r_begin_points_to_x) ASSERT_THAT(sign, 'x'); } -TEST(SmallString, constructor_standard_string) +TYPED_TEST(SmallString, constructor_standard_string) { + using SmallString = typename TestFixture::String; std::string stdStringText = "short string"; auto text = SmallString(stdStringText); @@ -606,8 +659,9 @@ TEST(SmallString, constructor_standard_string) ASSERT_THAT(text, SmallString("short string")); } -TEST(SmallString, to_q_string) +TYPED_TEST(SmallString, to_q_string) { + using SmallString = typename TestFixture::String; SmallString text("short string"); auto qStringText = text; @@ -644,17 +698,27 @@ protected: INSTANTIATE_TEST_SUITE_P(SmallString, FromQString, testing::Range(0, 10000, 300)); -TEST_P(FromQString, from_qstring) +TEST_P(FromQString, small_string_from_qstring) { const QString qStringText = exampleString(size); - auto text = SmallString(qStringText); + auto text = Utils::SmallString(qStringText); ASSERT_THAT(text, qStringText.toStdString()); } -TEST(SmallString, from_q_byte_array) +TEST_P(FromQString, path_string_from_qstring) { + const QString qStringText = exampleString(size); + + auto text = Utils::PathString(qStringText); + + ASSERT_THAT(text, qStringText.toStdString()); +} + +TYPED_TEST(SmallString, from_q_byte_array) +{ + using SmallString = typename TestFixture::String; QByteArray qByteArray = QByteArrayLiteral("short string"); auto text = SmallString::fromQByteArray(qByteArray); @@ -662,8 +726,9 @@ TEST(SmallString, from_q_byte_array) ASSERT_THAT(text, SmallString("short string")); } -TEST(SmallString, mid_one_parameter) +TYPED_TEST(SmallString, mid_one_parameter) { + using SmallString = typename TestFixture::String; SmallString text("some text"); auto midString = text.mid(5); @@ -671,8 +736,9 @@ TEST(SmallString, mid_one_parameter) ASSERT_THAT(midString, Eq(SmallString("text"))); } -TEST(SmallString, mid_two_parameter) +TYPED_TEST(SmallString, mid_two_parameter) { + using SmallString = typename TestFixture::String; SmallString text("some text and more"); auto midString = text.mid(5, 4); @@ -680,7 +746,7 @@ TEST(SmallString, mid_two_parameter) ASSERT_THAT(midString, Eq(SmallString("text"))); } -TEST(SmallString, small_string_view_mid_one_parameter) +TYPED_TEST(SmallString, small_string_view_mid_one_parameter) { SmallStringView text("some text"); @@ -689,7 +755,7 @@ TEST(SmallString, small_string_view_mid_one_parameter) ASSERT_THAT(midString, Eq(SmallStringView("text"))); } -TEST(SmallString, small_string_view_mid_two_parameter) +TYPED_TEST(SmallString, small_string_view_mid_two_parameter) { SmallStringView text("some text and more"); @@ -698,8 +764,9 @@ TEST(SmallString, small_string_view_mid_two_parameter) ASSERT_THAT(midString, Eq(SmallStringView("text"))); } -TEST(SmallString, size_of_empty_stringl) +TYPED_TEST(SmallString, size_of_empty_stringl) { + using SmallString = typename TestFixture::String; SmallString emptyString; auto size = emptyString.size(); @@ -707,7 +774,7 @@ TEST(SmallString, size_of_empty_stringl) ASSERT_THAT(size, 0); } -TEST(SmallString, size_short_small_string_literal) +TYPED_TEST(SmallString, size_short_small_string_literal) { SmallStringLiteral shortText("text"); @@ -716,7 +783,7 @@ TEST(SmallString, size_short_small_string_literal) ASSERT_THAT(size, 4); } -TEST(SmallString, size_long_small_string_literal) +TYPED_TEST(SmallString, size_long_small_string_literal) { auto longText = SmallStringLiteral("very very very very very very very very very very very long string"); @@ -725,8 +792,9 @@ TEST(SmallString, size_long_small_string_literal) ASSERT_THAT(size, 66); } -TEST(SmallString, size_reference) +TYPED_TEST(SmallString, size_reference) { + using SmallString = typename TestFixture::String; SmallString shortText("text"); auto size = shortText.size(); @@ -734,8 +802,9 @@ TEST(SmallString, size_reference) ASSERT_THAT(size, 4); } -TEST(SmallString, size_short_small_string) +TYPED_TEST(SmallString, size_short_small_string) { + using SmallString = typename TestFixture::String; SmallString shortText("text", 4); auto size = shortText.size(); @@ -743,8 +812,9 @@ TEST(SmallString, size_short_small_string) ASSERT_THAT(size, 4); } -TEST(SmallString, size_short_path_string) +TYPED_TEST(SmallString, size_short_path_string) { + using SmallString = typename TestFixture::String; SmallString shortPath("very very very very very very very very very very very long path which fits in the short memory"); auto size = shortPath.size(); @@ -752,8 +822,9 @@ TEST(SmallString, size_short_path_string) ASSERT_THAT(size, 95); } -TEST(SmallString, size_long_small_string) +TYPED_TEST(SmallString, size_long_small_string) { + using SmallString = typename TestFixture::String; auto longText = SmallString::fromUtf8("very very very very very very very very very very very long string"); auto size = longText.size(); @@ -761,77 +832,85 @@ TEST(SmallString, size_long_small_string) ASSERT_THAT(size, 66); } -TEST(SmallString, capacity_reference) +TYPED_TEST(SmallString, capacity_reference) { - SmallString shortText("very very very very very very very long string"); + Utils::SmallString shortText("very very very very very very very long string"); auto capacity = shortText.capacity(); ASSERT_THAT(capacity, 0); } -TEST(SmallString, capacity_short_small_string) +TYPED_TEST(SmallString, capacity_short_small_string) { + using SmallString = typename TestFixture::String; SmallString shortText("text", 4); auto capacity = shortText.capacity(); - ASSERT_THAT(capacity, 31); + ASSERT_THAT(capacity, SmallString::Capacity); } -TEST(SmallString, capacity_long_small_string) +TYPED_TEST(SmallString, capacity_long_small_string) { + using SmallString = typename TestFixture::String; auto longText = SmallString::fromUtf8("very very very very very very very very very very very long string"); auto capacity = longText.capacity(); - ASSERT_THAT(capacity, 66); + ASSERT_THAT(capacity, Ge(66)); } -TEST(SmallString, fits_not_in_capacity_because_null_small_string_is_a_short_small_string) +TYPED_TEST(SmallString, fits_not_in_capacity_because_null_small_string_is_a_short_small_string) { + using SmallString = typename TestFixture::String; SmallString text; ASSERT_FALSE(text.fitsNotInCapacity(30)); } -TEST(SmallString, fits_not_in_capacity_because_it_is_reference) +TYPED_TEST(SmallString, fits_not_in_capacity_because_it_is_reference) { - SmallString text("very very very very very very very long string"); + Utils::SmallString text("very very very very very very very long string"); ASSERT_TRUE(text.fitsNotInCapacity(1)); } -TEST(SmallString, fits_in_short_small_string_capacity) +TYPED_TEST(SmallString, fits_in_short_small_string_capacity) { + using SmallString = typename TestFixture::String; SmallString text("text", 4); - ASSERT_FALSE(text.fitsNotInCapacity(30)); + ASSERT_FALSE(text.fitsNotInCapacity(SmallString::Capacity)); } -TEST(SmallString, fits_in_not_short_small_string_capacity) +TYPED_TEST(SmallString, fits_in_not_short_small_string_capacity) { + using SmallString = typename TestFixture::String; SmallString text("text", 4); - ASSERT_TRUE(text.fitsNotInCapacity(32)); + ASSERT_TRUE(text.fitsNotInCapacity(SmallString::Capacity + 1)); } -TEST(SmallString, fits_in_long_small_string_capacity) +TYPED_TEST(SmallString, fits_in_long_small_string_capacity) { + using SmallString = typename TestFixture::String; SmallString text = SmallString::fromUtf8("very very very very very very long string"); ASSERT_FALSE(text.fitsNotInCapacity(33)) << text.capacity(); } -TEST(SmallString, fits_not_in_long_small_string_capacity) +TYPED_TEST(SmallString, fits_not_in_small_string_capacity) { - SmallString text = SmallString::fromUtf8("very very very very very very long string"); + using SmallString = typename TestFixture::String; + SmallString text = SmallString::fromUtf8("very very very very long string"); - ASSERT_TRUE(text.fitsNotInCapacity(65)) << text.capacity(); + ASSERT_TRUE(text.fitsNotInCapacity(SmallString::Capacity + 1)) << text.capacity(); } -TEST(SmallString, append_null_small_string) +TYPED_TEST(SmallString, append_null_small_string) { + using SmallString = typename TestFixture::String; SmallString text("text"); text += SmallString(); @@ -839,8 +918,9 @@ TEST(SmallString, append_null_small_string) ASSERT_THAT(text, SmallString("text")); } -TEST(SmallString, append_null_q_string) +TYPED_TEST(SmallString, append_null_q_string) { + using SmallString = typename TestFixture::String; SmallString text("text"); text += QString(); @@ -848,8 +928,9 @@ TEST(SmallString, append_null_q_string) ASSERT_THAT(text, SmallString("text")); } -TEST(SmallString, append_empty_small_string) +TYPED_TEST(SmallString, append_empty_small_string) { + using SmallString = typename TestFixture::String; SmallString text("text"); text += SmallString(""); @@ -857,8 +938,9 @@ TEST(SmallString, append_empty_small_string) ASSERT_THAT(text, SmallString("text")); } -TEST(SmallString, append_empty_q_string) +TYPED_TEST(SmallString, append_empty_q_string) { + using SmallString = typename TestFixture::String; SmallString text("text"); text += QString(""); @@ -866,8 +948,9 @@ TEST(SmallString, append_empty_q_string) ASSERT_THAT(text, SmallString("text")); } -TEST(SmallString, append_short_small_string) +TYPED_TEST(SmallString, append_short_small_string) { + using SmallString = typename TestFixture::String; SmallString text("some "); text += SmallString("text"); @@ -875,8 +958,9 @@ TEST(SmallString, append_short_small_string) ASSERT_THAT(text, SmallString("some text")); } -TEST(SmallString, append_short_q_string) +TYPED_TEST(SmallString, append_short_q_string) { + using SmallString = typename TestFixture::String; SmallString text("some "); text += QString("text"); @@ -884,8 +968,9 @@ TEST(SmallString, append_short_q_string) ASSERT_THAT(text, SmallString("some text")); } -TEST(SmallString, append_long_small_string_to_short_small_string) +TYPED_TEST(SmallString, append_long_small_string_to_short_small_string) { + using SmallString = typename TestFixture::String; SmallString text("some "); text += SmallString("very very very very very long string"); @@ -893,8 +978,9 @@ TEST(SmallString, append_long_small_string_to_short_small_string) ASSERT_THAT(text, SmallString("some very very very very very long string")); } -TEST(SmallString, append_long_q_string_to_short_small_string) +TYPED_TEST(SmallString, append_long_q_string_to_short_small_string) { + using SmallString = typename TestFixture::String; SmallString text("some "); text += QString("very very very very very long string"); @@ -902,8 +988,9 @@ TEST(SmallString, append_long_q_string_to_short_small_string) ASSERT_THAT(text, SmallString("some very very very very very long string")); } -TEST(SmallString, append_long_small_string) +TYPED_TEST(SmallString, append_long_small_string) { + using SmallString = typename TestFixture::String; SmallString longText("some very very very very very very very very very very very long string"); longText += SmallString(" text"); @@ -911,8 +998,9 @@ TEST(SmallString, append_long_small_string) ASSERT_THAT(longText, SmallString("some very very very very very very very very very very very long string text")); } -TEST(SmallString, append_long_q_string) +TYPED_TEST(SmallString, append_long_q_string) { + using SmallString = typename TestFixture::String; SmallString longText("some very very very very very very very very very very very long string"); longText += QString(" text"); @@ -923,8 +1011,9 @@ TEST(SmallString, append_long_q_string) "some very very very very very very very very very very very long string text")); } -TEST(SmallString, append_initializer_list) +TYPED_TEST(SmallString, append_initializer_list) { + using SmallString = typename TestFixture::String; SmallString text("some text"); text += {" and", " some", " other", " text"}; @@ -932,8 +1021,9 @@ TEST(SmallString, append_initializer_list) ASSERT_THAT(text, Eq("some text and some other text")); } -TEST(SmallString, append_empty_initializer_list) +TYPED_TEST(SmallString, append_empty_initializer_list) { + using SmallString = typename TestFixture::String; SmallString text("some text"); text += {}; @@ -941,8 +1031,9 @@ TEST(SmallString, append_empty_initializer_list) ASSERT_THAT(text, Eq("some text")); } -TEST(SmallString, append_int) +TYPED_TEST(SmallString, append_int) { + using SmallString = typename TestFixture::String; SmallString text("some text"); text += 123; @@ -950,8 +1041,9 @@ TEST(SmallString, append_int) ASSERT_THAT(text, Eq("some text123")); } -TEST(SmallString, append_float) +TYPED_TEST(SmallString, append_float) { + using SmallString = typename TestFixture::String; SmallString text("some text"); text += 123.456; @@ -959,8 +1051,9 @@ TEST(SmallString, append_float) ASSERT_THAT(text, Eq("some text123.456")); } -TEST(SmallString, append_character) +TYPED_TEST(SmallString, append_character) { + using SmallString = typename TestFixture::String; SmallString text("some text"); text += 'x'; @@ -968,15 +1061,17 @@ TEST(SmallString, append_character) ASSERT_THAT(text, Eq("some textx")); } -TEST(SmallString, to_byte_array) +TYPED_TEST(SmallString, to_byte_array) { + using SmallString = typename TestFixture::String; SmallString text("some text"); ASSERT_THAT(text.toQByteArray(), QByteArrayLiteral("some text")); } -TEST(SmallString, contains) +TYPED_TEST(SmallString, contains) { + using SmallString = typename TestFixture::String; SmallString text("some text"); ASSERT_TRUE(text.contains(SmallString("text"))); @@ -984,8 +1079,9 @@ TEST(SmallString, contains) ASSERT_TRUE(text.contains('x')); } -TEST(SmallString, not_contains) +TYPED_TEST(SmallString, not_contains) { + using SmallString = typename TestFixture::String; SmallString text("some text"); ASSERT_FALSE(text.contains(SmallString("textTwo"))); @@ -993,80 +1089,90 @@ TEST(SmallString, not_contains) ASSERT_FALSE(text.contains('q')); } -TEST(SmallString, equal_small_string_operator) +TYPED_TEST(SmallString, equal_small_string_operator) { + using SmallString = typename TestFixture::String; ASSERT_TRUE(SmallString() == SmallString("")); ASSERT_FALSE(SmallString() == SmallString("text")); ASSERT_TRUE(SmallString("text") == SmallString("text")); ASSERT_FALSE(SmallString("text") == SmallString("text2")); } -TEST(SmallString, equal_small_string_operator_with_difference_class_sizes) +TYPED_TEST(SmallString, equal_small_string_operator_with_difference_class_sizes) { - ASSERT_TRUE(SmallString() == PathString("")); - ASSERT_FALSE(SmallString() == PathString("text")); - ASSERT_TRUE(SmallString("text") == PathString("text")); - ASSERT_FALSE(SmallString("text") == PathString("text2")); + using SmallString = typename TestFixture::String; + ASSERT_TRUE(SmallString() == Utils::PathString("")); + ASSERT_FALSE(SmallString() == Utils::PathString("text")); + ASSERT_TRUE(SmallString("text") == Utils::PathString("text")); + ASSERT_FALSE(SmallString("text") == Utils::PathString("text2")); } -TEST(SmallString, equal_c_string_array_operator) +TYPED_TEST(SmallString, equal_c_string_array_operator) { + using SmallString = typename TestFixture::String; ASSERT_TRUE(SmallString() == ""); ASSERT_FALSE(SmallString() == "text"); ASSERT_TRUE(SmallString("text") == "text"); ASSERT_FALSE(SmallString("text") == "text2"); } -TEST(SmallString, equal_c_string_pointer_operator) +TYPED_TEST(SmallString, equal_c_string_pointer_operator) { + using SmallString = typename TestFixture::String; ASSERT_TRUE(SmallString("text") == std::string("text").data()); ASSERT_FALSE(SmallString("text") == std::string("text2").data()); } -TEST(SmallString, equal_small_string_view_operator) +TYPED_TEST(SmallString, equal_small_string_view_operator) { + using SmallString = typename TestFixture::String; ASSERT_TRUE(SmallString("text") == SmallStringView("text")); ASSERT_FALSE(SmallString("text") == SmallStringView("text2")); } -TEST(SmallString, equal_small_string_views_operator) +TYPED_TEST(SmallString, equal_small_string_views_operator) { ASSERT_TRUE(SmallStringView("text") == SmallStringView("text")); ASSERT_FALSE(SmallStringView("text") == SmallStringView("text2")); } -TEST(SmallString, unequal_operator) +TYPED_TEST(SmallString, unequal_operator) { + using SmallString = typename TestFixture::String; ASSERT_FALSE(SmallString("text") != SmallString("text")); ASSERT_TRUE(SmallString("text") != SmallString("text2")); } -TEST(SmallString, unequal_c_string_array_operator) +TYPED_TEST(SmallString, unequal_c_string_array_operator) { + using SmallString = typename TestFixture::String; ASSERT_FALSE(SmallString("text") != "text"); ASSERT_TRUE(SmallString("text") != "text2"); } -TEST(SmallString, unequal_c_string_pointer_operator) +TYPED_TEST(SmallString, unequal_c_string_pointer_operator) { + using SmallString = typename TestFixture::String; ASSERT_FALSE(SmallString("text") != std::string("text").data()); ASSERT_TRUE(SmallString("text") != std::string("text2").data()); } -TEST(SmallString, unequal_small_string_view_array_operator) +TYPED_TEST(SmallString, unequal_small_string_view_array_operator) { + using SmallString = typename TestFixture::String; ASSERT_FALSE(SmallString("text") != SmallStringView("text")); ASSERT_TRUE(SmallString("text") != SmallStringView("text2")); } -TEST(SmallString, unequal_small_string_views_array_operator) +TYPED_TEST(SmallString, unequal_small_string_views_array_operator) { ASSERT_FALSE(SmallStringView("text") != SmallStringView("text")); ASSERT_TRUE(SmallStringView("text") != SmallStringView("text2")); } -TEST(SmallString, smaller_operator) +TYPED_TEST(SmallString, smaller_operator) { + using SmallString = typename TestFixture::String; ASSERT_TRUE(SmallString() < SmallString("text")); ASSERT_TRUE(SmallString("some") < SmallString("text")); ASSERT_TRUE(SmallString("text") < SmallString("texta")); @@ -1075,8 +1181,9 @@ TEST(SmallString, smaller_operator) ASSERT_FALSE(SmallString("text") < SmallString("text")); } -TEST(SmallString, smaller_operator_with_string_view_right) +TYPED_TEST(SmallString, smaller_operator_with_string_view_right) { + using SmallString = typename TestFixture::String; ASSERT_TRUE(SmallString() < SmallStringView("text")); ASSERT_TRUE(SmallString("some") < SmallStringView("text")); ASSERT_TRUE(SmallString("text") < SmallStringView("texta")); @@ -1085,8 +1192,9 @@ TEST(SmallString, smaller_operator_with_string_view_right) ASSERT_FALSE(SmallString("text") < SmallStringView("text")); } -TEST(SmallString, smaller_operator_with_string_view_left) +TYPED_TEST(SmallString, smaller_operator_with_string_view_left) { + using SmallString = typename TestFixture::String; ASSERT_TRUE(SmallStringView("") < SmallString("text")); ASSERT_TRUE(SmallStringView("some") < SmallString("text")); ASSERT_TRUE(SmallStringView("text") < SmallString("texta")); @@ -1095,44 +1203,48 @@ TEST(SmallString, smaller_operator_with_string_view_left) ASSERT_FALSE(SmallStringView("text") < SmallString("text")); } -TEST(SmallString, smaller_operator_for_difference_class_sizes) +TYPED_TEST(SmallString, smaller_operator_for_difference_class_sizes) { - ASSERT_TRUE(SmallString() < PathString("text")); - ASSERT_TRUE(SmallString("some") < PathString("text")); - ASSERT_TRUE(SmallString("text") < PathString("texta")); - ASSERT_FALSE(SmallString("texta") < PathString("text")); - ASSERT_FALSE(SmallString("text") < PathString("some")); - ASSERT_FALSE(SmallString("text") < PathString("text")); + using SmallString = typename TestFixture::String; + ASSERT_TRUE(SmallString() < Utils::PathString("text")); + ASSERT_TRUE(SmallString("some") < Utils::PathString("text")); + ASSERT_TRUE(SmallString("text") < Utils::PathString("texta")); + ASSERT_FALSE(SmallString("texta") < Utils::PathString("text")); + ASSERT_FALSE(SmallString("text") < Utils::PathString("some")); + ASSERT_FALSE(SmallString("text") < Utils::PathString("text")); } -TEST(SmallString, is_empty) +TYPED_TEST(SmallString, is_empty) { + using SmallString = typename TestFixture::String; ASSERT_FALSE(SmallString("text").isEmpty()); ASSERT_TRUE(SmallString("").isEmpty()); ASSERT_TRUE(SmallString().isEmpty()); } -TEST(SmallString, string_view_is_empty) +TYPED_TEST(SmallString, string_view_is_empty) { ASSERT_FALSE(SmallStringView("text").isEmpty()); ASSERT_TRUE(SmallStringView("").isEmpty()); } -TEST(SmallString, string_view_empty) +TYPED_TEST(SmallString, string_view_empty) { ASSERT_FALSE(SmallStringView("text").empty()); ASSERT_TRUE(SmallStringView("").empty()); } -TEST(SmallString, has_content) +TYPED_TEST(SmallString, has_content) { + using SmallString = typename TestFixture::String; ASSERT_TRUE(SmallString("text").hasContent()); ASSERT_FALSE(SmallString("").hasContent()); ASSERT_FALSE(SmallString().hasContent()); } -TEST(SmallString, clear) +TYPED_TEST(SmallString, clear) { + using SmallString = typename TestFixture::String; SmallString text("text"); text.clear(); @@ -1140,44 +1252,49 @@ TEST(SmallString, clear) ASSERT_TRUE(text.isEmpty()); } -TEST(SmallString, no_occurrences_for_empty_text) +TYPED_TEST(SmallString, no_occurrences_for_empty_text) { + using SmallString = typename TestFixture::String; SmallString text; - auto occurrences = text.countOccurrence("text"); + auto occurrences = text.count("text"); ASSERT_THAT(occurrences, 0); } -TEST(SmallString, no_occurrences_in_text) +TYPED_TEST(SmallString, no_occurrences_in_text) { + using SmallString = typename TestFixture::String; SmallString text("here is some text, here is some text, here is some text"); - auto occurrences = text.countOccurrence("texts"); + auto occurrences = text.count("texts"); ASSERT_THAT(occurrences, 0); } -TEST(SmallString, some_occurrences) +TYPED_TEST(SmallString, some_occurrences) { + using SmallString = typename TestFixture::String; SmallString text("here is some text, here is some text, here is some text"); - auto occurrences = text.countOccurrence("text"); + auto occurrences = text.count("text"); ASSERT_THAT(occurrences, 3); } -TEST(SmallString, some_more_occurrences) +TYPED_TEST(SmallString, some_more_occurrences) { + using SmallString = typename TestFixture::String; SmallString text("texttexttext"); - auto occurrences = text.countOccurrence("text"); + auto occurrences = text.count("text"); ASSERT_THAT(occurrences, 3); } -TEST(SmallString, replace_with_character) +TYPED_TEST(SmallString, replace_with_character) { + using SmallString = typename TestFixture::String; SmallString text("here is some text, here is some text, here is some text"); text.replace('s', 'x'); @@ -1185,8 +1302,9 @@ TEST(SmallString, replace_with_character) ASSERT_THAT(text, SmallString("here ix xome text, here ix xome text, here ix xome text")); } -TEST(SmallString, replace_with_equal_sized_text) +TYPED_TEST(SmallString, replace_with_equal_sized_text) { + using SmallString = typename TestFixture::String; SmallString text("here is some text"); text.replace("some", "much"); @@ -1194,8 +1312,9 @@ TEST(SmallString, replace_with_equal_sized_text) ASSERT_THAT(text, SmallString("here is much text")); } -TEST(SmallString, replace_with_equal_sized_text_on_empty_text) +TYPED_TEST(SmallString, replace_with_equal_sized_text_on_empty_text) { + using SmallString = typename TestFixture::String; SmallString text; text.replace("some", "much"); @@ -1203,8 +1322,9 @@ TEST(SmallString, replace_with_equal_sized_text_on_empty_text) ASSERT_THAT(text, SmallString()); } -TEST(SmallString, replace_with_shorter_text) +TYPED_TEST(SmallString, replace_with_shorter_text) { + using SmallString = typename TestFixture::String; SmallString text("here is some text"); text.replace("some", "any"); @@ -1212,8 +1332,9 @@ TEST(SmallString, replace_with_shorter_text) ASSERT_THAT(text, SmallString("here is any text")); } -TEST(SmallString, replace_with_shorter_text_on_empty_text) +TYPED_TEST(SmallString, replace_with_shorter_text_on_empty_text) { + using SmallString = typename TestFixture::String; SmallString text; text.replace("some", "any"); @@ -1221,8 +1342,9 @@ TEST(SmallString, replace_with_shorter_text_on_empty_text) ASSERT_THAT(text, SmallString()); } -TEST(SmallString, replace_with_longer_text) +TYPED_TEST(SmallString, replace_with_longer_text) { + using SmallString = typename TestFixture::String; SmallString text("here is some text"); text.replace("some", "much more"); @@ -1230,8 +1352,9 @@ TEST(SmallString, replace_with_longer_text) ASSERT_THAT(text, SmallString("here is much more text")); } -TEST(SmallString, replace_with_longer_text_on_empty_text) +TYPED_TEST(SmallString, replace_with_longer_text_on_empty_text) { + using SmallString = typename TestFixture::String; SmallString text; text.replace("some", "much more"); @@ -1239,8 +1362,9 @@ TEST(SmallString, replace_with_longer_text_on_empty_text) ASSERT_THAT(text, SmallString()); } -TEST(SmallString, replace_short_small_string_with_longer_text) +TYPED_TEST(SmallString, replace_short_small_string_with_longer_text) { + using SmallString = typename TestFixture::String; SmallString text = SmallString::fromUtf8("here is some text"); text.replace("some", "much more"); @@ -1248,8 +1372,9 @@ TEST(SmallString, replace_short_small_string_with_longer_text) ASSERT_THAT(text, SmallString("here is much more text")); } -TEST(SmallString, replace_long_small_string_with_longer_text) +TYPED_TEST(SmallString, replace_long_small_string_with_longer_text) { + using SmallString = typename TestFixture::String; SmallString text = SmallString::fromUtf8("some very very very very very very very very very very very long string"); text.replace("long", "much much much much much much much much much much much much much much much much much much more"); @@ -1257,8 +1382,9 @@ TEST(SmallString, replace_long_small_string_with_longer_text) ASSERT_THAT(text, "some very very very very very very very very very very very much much much much much much much much much much much much much much much much much much more string"); } -TEST(SmallString, multiple_replace_small_string_with_longer_text) +TYPED_TEST(SmallString, multiple_replace_small_string_with_longer_text) { + using SmallString = typename TestFixture::String; SmallString text = SmallString("here is some text with some longer text"); text.replace("some", "much more"); @@ -1266,8 +1392,9 @@ TEST(SmallString, multiple_replace_small_string_with_longer_text) ASSERT_THAT(text, SmallString("here is much more text with much more longer text")); } -TEST(SmallString, multiple_replace_small_string_with_shorter_text) +TYPED_TEST(SmallString, multiple_replace_small_string_with_shorter_text) { + using SmallString = typename TestFixture::String; SmallString text = SmallString("here is some text with some longer text"); text.replace("some", "a"); @@ -1275,8 +1402,9 @@ TEST(SmallString, multiple_replace_small_string_with_shorter_text) ASSERT_THAT(text, SmallString("here is a text with a longer text")); } -TEST(SmallString, dont_replace_replaced_text) +TYPED_TEST(SmallString, dont_replace_replaced_text) { + using SmallString = typename TestFixture::String; SmallString text("here is some foo text"); text.replace("foo", "foofoo"); @@ -1284,26 +1412,40 @@ TEST(SmallString, dont_replace_replaced_text) ASSERT_THAT(text, SmallString("here is some foofoo text")); } -TEST(SmallString, dont_reserve_if_nothing_is_replaced_for_longer_replacement_text) +TYPED_TEST(SmallString, dont_reserve_if_nothing_is_replaced_for_longer_replacement_text) { - SmallString text("here is some text with some longer text"); + using SmallString = typename TestFixture::String; + SmallString text( + "here is some text with some longer text here is some text with some longer texthere is " + "some text with some longer texthere is some text with some longer texthere is some text " + "with some longer texthere is some text with some longer texthere is some text with some " + "longer texthere is some text with some longer texthere is some text with some longer " + "texthere is some text with some longer text"); text.replace("bar", "foofoo"); ASSERT_TRUE(text.isReadOnlyReference()); } -TEST(SmallString, dont_reserve_if_nothing_is_replaced_for_shorter_replacement_text) +TYPED_TEST(SmallString, dont_reserve_if_nothing_is_replaced_for_shorter_replacement_text) { - SmallString text("here is some text with some longer text"); + using SmallString = typename TestFixture::String; + SmallString text( + "here is some text with some longer text here is some text with some longer texthere is " + "some text with some longer texthere is some text with some longer texthere is some text " + "with some longer texthere is some text with some longer texthere is some text with some " + "longer texthere is some text with some longer texthere is some text with some longer " + "texthere is some text with some longer text"); text.replace("foofoo", "bar"); ASSERT_TRUE(text.isReadOnlyReference()); } -TEST(SmallString, starts_with) +TYPED_TEST(SmallString, starts_with) { + using SmallString = typename TestFixture::String; + SmallString text("$column"); ASSERT_FALSE(text.startsWith("$columnxxx")); @@ -1314,7 +1456,7 @@ TEST(SmallString, starts_with) ASSERT_FALSE(text.startsWith('@')); } -TEST(SmallString, starts_with_string_view) +TYPED_TEST(SmallString, starts_with_string_view) { SmallStringView text("$column"); @@ -1326,9 +1468,11 @@ TEST(SmallString, starts_with_string_view) ASSERT_FALSE(text.startsWith('@')); } -TEST(SmallString, starts_with_qstringview) +TYPED_TEST(SmallString, starts_with_qstringview) { + using SmallString = typename TestFixture::String; using namespace Qt::StringLiterals; + SmallString text("$column"); ASSERT_FALSE(text.startsWith(u"$columnxxx"_s)); @@ -1339,8 +1483,10 @@ TEST(SmallString, starts_with_qstringview) ASSERT_FALSE(text.startsWith(u"@"_s)); } -TEST(SmallString, ends_with) +TYPED_TEST(SmallString, ends_with) { + using SmallString = typename TestFixture::String; + SmallString text("/my/path"); ASSERT_TRUE(text.endsWith("/my/path")); @@ -1350,7 +1496,7 @@ TEST(SmallString, ends_with) ASSERT_FALSE(text.endsWith('x')); } -TEST(SmallString, ends_with_string_view) +TYPED_TEST(SmallString, ends_with_string_view) { SmallStringView text("/my/path"); @@ -1359,25 +1505,29 @@ TEST(SmallString, ends_with_string_view) ASSERT_FALSE(text.endsWith("paths")); } -TEST(SmallString, ends_with_small_string) +TYPED_TEST(SmallString, ends_with_small_string) { + using SmallString = typename TestFixture::String; + SmallString text("/my/path"); ASSERT_TRUE(text.endsWith(SmallString("path"))); ASSERT_TRUE(text.endsWith('h')); } -TEST(SmallString, reserve_smaller_than_short_string_capacity) +TYPED_TEST(SmallString, reserve_smaller_than_short_string_capacity) { + using SmallString = typename TestFixture::String; SmallString text("text"); text.reserve(2); - ASSERT_THAT(text.capacity(), 31); + ASSERT_THAT(text.capacity(), SmallString::Capacity); } -TEST(SmallString, reserve_smaller_than_short_string_capacity_is_short_string) +TYPED_TEST(SmallString, reserve_smaller_than_short_string_capacity_is_short_string) { + using SmallString = typename TestFixture::String; SmallString text("text"); text.reserve(2); @@ -1385,44 +1535,39 @@ TEST(SmallString, reserve_smaller_than_short_string_capacity_is_short_string) ASSERT_TRUE(text.isShortString()); } -TEST(SmallString, reserve_smaller_than_reference) +TYPED_TEST(SmallString, reserve_bigger_than_short_string_capacity) { + using SmallString = typename TestFixture::String; SmallString text("some very very very very very very very very very very very long string"); - text.reserve(35); + text.reserve(SmallString::Capacity + 1); - ASSERT_THAT(text.capacity(), 71); + ASSERT_THAT(text.capacity(), Ge(SmallString::Capacity + 1)); } -TEST(SmallString, reserve_bigger_than_short_string_capacity) +TYPED_TEST(SmallString, reserve_smaller_than_reference) { + using SmallString = typename TestFixture::String; SmallString text("text"); text.reserve(10); - ASSERT_THAT(text.capacity(), 31); + ASSERT_THAT(text.capacity(), SmallString::Capacity); } -TEST(SmallString, reserve_bigger_than_reference) +TYPED_TEST(SmallString, reserve_bigger_than_reference) { + using SmallString = typename TestFixture::String; SmallString text("some very very very very very very very very very very very long string"); - text.reserve(35); + text.reserve(SmallString::Capacity + 1); - ASSERT_THAT(text.capacity(), 71); + ASSERT_THAT(text.capacity(), Ge(SmallString::Capacity + 1)); } -TEST(SmallString, reserve_much_bigger_than_short_string_capacity) -{ - SmallString text("text"); - - text.reserve(100); - - ASSERT_THAT(text.capacity(), 100); -} - -TEST(SmallString, text_is_copied_after_reserve_from_short_to_long_string) +TYPED_TEST(SmallString, text_is_copied_after_reserve_from_short_to_long_string) { + using SmallString = typename TestFixture::String; SmallString text("text"); text.reserve(100); @@ -1430,8 +1575,9 @@ TEST(SmallString, text_is_copied_after_reserve_from_short_to_long_string) ASSERT_THAT(text, "text"); } -TEST(SmallString, text_is_copied_after_reserve_reference_to_long_string) +TYPED_TEST(SmallString, text_is_copied_after_reserve_reference_to_long_string) { + using SmallString = typename TestFixture::String; SmallString text("some very very very very very very very very very very very long string"); text.reserve(100); @@ -1439,35 +1585,30 @@ TEST(SmallString, text_is_copied_after_reserve_reference_to_long_string) ASSERT_THAT(text, "some very very very very very very very very very very very long string"); } -TEST(SmallString, reserve_smaller_than_short_small_string) +TYPED_TEST(SmallString, reserve_smaller_than_short_string) { + using SmallString = typename TestFixture::String; SmallString text = SmallString::fromUtf8("text"); text.reserve(10); - ASSERT_THAT(text.capacity(), 31); + ASSERT_THAT(text.capacity(), SmallString::Capacity); } -TEST(SmallString, reserve_bigger_than_short_small_string) +TYPED_TEST(SmallString, reserve_bigger_than_short_string) { + using SmallString = typename TestFixture::String; SmallString text = SmallString::fromUtf8("text"); - text.reserve(100); + text.reserve(SmallString::Capacity + 1); - ASSERT_THAT(text.capacity(), 100); + ASSERT_THAT(text.capacity(), Ge(SmallString::Capacity + 1)); } -TEST(SmallString, reserve_bigger_than_long_small_string) +TYPED_TEST(SmallString, optimal_heap_cache_line_for_size) { - SmallString text = SmallString::fromUtf8("some very very very very very very very very very very very long string"); + using SmallString = typename TestFixture::String; - text.reserve(100); - - ASSERT_THAT(text.capacity(), 100); -} - -TEST(SmallString, optimal_heap_cache_line_for_size) -{ ASSERT_THAT(SmallString::optimalHeapCapacity(64), 64); ASSERT_THAT(SmallString::optimalHeapCapacity(65), 128); ASSERT_THAT(SmallString::optimalHeapCapacity(127), 128); @@ -1485,9 +1626,9 @@ TEST(SmallString, optimal_heap_cache_line_for_size) ASSERT_THAT(SmallString::optimalHeapCapacity(4097), 4160); } -TEST(SmallString, optimal_capacity_for_size) +TYPED_TEST(SmallString, optimal_capacity_for_size) { - SmallString text; + Utils::SmallString text; ASSERT_THAT(text.optimalCapacity(0), 0); ASSERT_THAT(text.optimalCapacity(31), 31); @@ -1497,8 +1638,9 @@ TEST(SmallString, optimal_capacity_for_size) ASSERT_THAT(text.optimalCapacity(129), 192); } -TEST(SmallString, data_stream_data) +TYPED_TEST(SmallString, data_stream_data) { + using SmallString = typename TestFixture::String; SmallString inputText("foo"); QByteArray byteArray; QDataStream out(&byteArray, QIODevice::ReadWrite); @@ -1508,8 +1650,9 @@ TEST(SmallString, data_stream_data) ASSERT_TRUE(byteArray.endsWith("foo")); } -TEST(SmallString, read_data_stream_size) +TYPED_TEST(SmallString, read_data_stream_size) { + using SmallString = typename TestFixture::String; SmallString outputText("foo"); QByteArray byteArray; quint32 size; @@ -1524,8 +1667,9 @@ TEST(SmallString, read_data_stream_size) ASSERT_THAT(size, 3); } -TEST(SmallString, read_data_stream_data) +TYPED_TEST(SmallString, read_data_stream_data) { + using SmallString = typename TestFixture::String; SmallString outputText("foo"); QByteArray byteArray; SmallString outputString; @@ -1540,8 +1684,9 @@ TEST(SmallString, read_data_stream_data) ASSERT_THAT(outputString, SmallString("foo")); } -TEST(SmallString, short_small_string_copy_constuctor) +TYPED_TEST(SmallString, short_small_string_copy_constuctor) { + using SmallString = typename TestFixture::String; SmallString text("text"); auto copy = text; @@ -1549,8 +1694,9 @@ TEST(SmallString, short_small_string_copy_constuctor) ASSERT_THAT(copy, text); } -TEST(SmallString, long_small_string_copy_constuctor) +TYPED_TEST(SmallString, long_small_string_copy_constuctor) { + using SmallString = typename TestFixture::String; SmallString text("this is a very very very very long text"); auto copy = text; @@ -1558,8 +1704,9 @@ TEST(SmallString, long_small_string_copy_constuctor) ASSERT_THAT(copy, text); } -TEST(SmallString, short_small_string_move_constuctor) +TYPED_TEST(SmallString, short_small_string_move_constuctor) { + using SmallString = typename TestFixture::String; SmallString text("text"); auto copy = std::move(text); @@ -1567,8 +1714,9 @@ TEST(SmallString, short_small_string_move_constuctor) ASSERT_THAT(copy, SmallString("text")); } -TEST(SmallString, long_small_string_move_constuctor) +TYPED_TEST(SmallString, long_small_string_move_constuctor) { + using SmallString = typename TestFixture::String; SmallString text("this is a very very very very long text"); auto copy = std::move(text); @@ -1576,18 +1724,20 @@ TEST(SmallString, long_small_string_move_constuctor) ASSERT_THAT(copy, SmallString("this is a very very very very long text")); } -TEST(SmallString, short_path_string_move_constuctor) +TYPED_TEST(SmallString, short_path_string_move_constuctor) { - PathString text("text"); + using SmallString = typename TestFixture::String; + SmallString text("text"); auto copy = std::move(text); ASSERT_THAT(copy, SmallString("text")); } -TEST(SmallString, long_path_string_move_constuctor) +TYPED_TEST(SmallString, long_path_string_move_constuctor) { - PathString text( + using SmallString = typename TestFixture::String; + SmallString text( "this is a very very very very very very very very very very very very very very very very " "very very very very very very very very very very very very very very very very very very " "very very very very very very very very very very very very very very long text"); @@ -1596,7 +1746,7 @@ TEST(SmallString, long_path_string_move_constuctor) ASSERT_THAT( copy, - PathString( + SmallString( "this is a very very very very very very very very very very very very very very very " "very very very very very very very very very very very very very very very very very " "very very very very very very very very very very very very very very very very long " @@ -1608,8 +1758,9 @@ QT_WARNING_DISABLE_GCC("-Wpragmas") QT_WARNING_DISABLE_GCC("-Wself-move") QT_WARNING_DISABLE_CLANG("-Wself-move") -TEST(SmallString, short_small_string_move_constuctor_to_self) +TYPED_TEST(SmallString, short_small_string_move_constuctor_to_self) { + using SmallString = typename TestFixture::String; SmallString text("text"); text = std::move(text); @@ -1617,8 +1768,9 @@ TEST(SmallString, short_small_string_move_constuctor_to_self) ASSERT_THAT(text, SmallString("text")); } -TEST(SmallString, long_small_string_move_constuctor_to_self) +TYPED_TEST(SmallString, long_small_string_move_constuctor_to_self) { + using SmallString = typename TestFixture::String; SmallString text("this is a very very very very long text"); text = std::move(text); @@ -1626,18 +1778,20 @@ TEST(SmallString, long_small_string_move_constuctor_to_self) ASSERT_THAT(text, SmallString("this is a very very very very long text")); } -TEST(SmallString, short_path_string_move_constuctor_to_self) +TYPED_TEST(SmallString, short_path_string_move_constuctor_to_self) { - PathString text("text"); + using SmallString = typename TestFixture::String; + SmallString text("text"); text = std::move(text); ASSERT_THAT(text, SmallString("text")); } -TEST(SmallString, long_path_string_move_constuctor_to_self) +TYPED_TEST(SmallString, long_path_string_move_constuctor_to_self) { - PathString text( + using SmallString = typename TestFixture::String; + SmallString text( "this is a very very very very very very very very very very very very very very very very " "very very very very very very very very very very very very very very very very very very " "very very very very very very very very very very very very very very long text"); @@ -1646,7 +1800,7 @@ TEST(SmallString, long_path_string_move_constuctor_to_self) ASSERT_THAT( text, - PathString( + SmallString( "this is a very very very very very very very very very very very very very very very " "very very very very very very very very very very very very very very very very very " "very very very very very very very very very very very very very very very very long " @@ -1655,8 +1809,9 @@ TEST(SmallString, long_path_string_move_constuctor_to_self) QT_WARNING_POP -TEST(SmallString, short_small_string_copy_assignment) +TYPED_TEST(SmallString, short_small_string_copy_assignment) { + using SmallString = typename TestFixture::String; SmallString text("text"); SmallString copy("more text"); @@ -1665,8 +1820,9 @@ TEST(SmallString, short_small_string_copy_assignment) ASSERT_THAT(copy, text); } -TEST(SmallString, long_small_string_copy_assignment) +TYPED_TEST(SmallString, long_small_string_copy_assignment) { + using SmallString = typename TestFixture::String; SmallString text("this is a very very very very long text"); SmallString copy("more text"); @@ -1680,8 +1836,9 @@ TEST(SmallString, long_small_string_copy_assignment) #pragma clang diagnostic ignored "-Wself-assign-overloaded" #endif -TEST(SmallString, long_small_string_copy_self_assignment) +TYPED_TEST(SmallString, long_small_string_copy_self_assignment) { + using SmallString = typename TestFixture::String; SmallString text("this is a very very very very long text"); text = text; @@ -1693,8 +1850,9 @@ TEST(SmallString, long_small_string_copy_self_assignment) #pragma clang diagnostic pop #endif -TEST(SmallString, short_small_string_move_assignment) +TYPED_TEST(SmallString, short_small_string_move_assignment) { + using SmallString = typename TestFixture::String; SmallString text("text"); SmallString copy("more text"); @@ -1703,8 +1861,9 @@ TEST(SmallString, short_small_string_move_assignment) ASSERT_THAT(copy, SmallString("text")); } -TEST(SmallString, long_small_string_move_assignment) +TYPED_TEST(SmallString, long_small_string_move_assignment) { + using SmallString = typename TestFixture::String; SmallString text("this is a very very very very long text"); SmallString copy("more text"); @@ -1713,37 +1872,40 @@ TEST(SmallString, long_small_string_move_assignment) ASSERT_THAT(copy, SmallString("this is a very very very very long text")); } -TEST(SmallString, short_path_string_move_assignment) +TYPED_TEST(SmallString, short_path_string_move_assignment) { - PathString text("text"); - PathString copy("more text"); + using SmallString = typename TestFixture::String; + SmallString text("text"); + SmallString copy("more text"); copy = std::move(text); ASSERT_THAT(copy, SmallString("text")); } -TEST(SmallString, long_path_string_move_assignment) +TYPED_TEST(SmallString, long_path_string_move_assignment) { - PathString text( + using SmallString = typename TestFixture::String; + SmallString text( "this is a very very very very very very very very very very very very very very very very " "very very very very very very very very very very very very very very very very very very " "very very very very very very very very very very very very very very long text"); - PathString copy("more text"); + SmallString copy("more text"); copy = std::move(text); ASSERT_THAT( copy, - PathString( + SmallString( "this is a very very very very very very very very very very very very very very very " "very very very very very very very very very very very very very very very very very " "very very very very very very very very very very very very very very very very long " "text")); } -TEST(SmallString, short_small_string_take) +TYPED_TEST(SmallString, short_small_string_take) { + using SmallString = typename TestFixture::String; SmallString text("text"); SmallString copy("more text"); @@ -1753,8 +1915,9 @@ TEST(SmallString, short_small_string_take) ASSERT_THAT(copy, SmallString("text")); } -TEST(SmallString, long_small_string_take) +TYPED_TEST(SmallString, long_small_string_take) { + using SmallString = typename TestFixture::String; SmallString text("this is a very very very very long text"); SmallString copy("more text"); @@ -1764,8 +1927,9 @@ TEST(SmallString, long_small_string_take) ASSERT_THAT(copy, SmallString("this is a very very very very long text")); } -TEST(SmallString, replace_by_position_shorter_with_longer_text) +TYPED_TEST(SmallString, replace_by_position_shorter_with_longer_text) { + using SmallString = typename TestFixture::String; SmallString text("this is a very very very very long text"); text.replace(8, 1, "some"); @@ -1773,8 +1937,9 @@ TEST(SmallString, replace_by_position_shorter_with_longer_text) ASSERT_THAT(text, SmallString("this is some very very very very long text")); } -TEST(SmallString, replace_by_position_longer_with_short_text) +TYPED_TEST(SmallString, replace_by_position_longer_with_short_text) { + using SmallString = typename TestFixture::String; SmallString text("this is some very very very very long text"); text.replace(8, 4, "a"); @@ -1782,8 +1947,9 @@ TEST(SmallString, replace_by_position_longer_with_short_text) ASSERT_THAT(text, SmallString("this is a very very very very long text")); } -TEST(SmallString, replace_by_position_equal_sized_texts) +TYPED_TEST(SmallString, replace_by_position_equal_sized_texts) { + using SmallString = typename TestFixture::String; SmallString text("this is very very very very very long text"); text.replace(33, 4, "much"); @@ -1791,8 +1957,9 @@ TEST(SmallString, replace_by_position_equal_sized_texts) ASSERT_THAT(text, SmallString("this is very very very very very much text")); } -TEST(SmallString, compare_text_with_different_line_endings) +TYPED_TEST(SmallString, compare_text_with_different_line_endings) { + using SmallString = typename TestFixture::String; SmallString unixText("some \ntext"); SmallString windowsText("some \n\rtext"); @@ -1801,8 +1968,9 @@ TEST(SmallString, compare_text_with_different_line_endings) ASSERT_THAT(unixText, convertedText); } -TEST(SmallString, const_subscript_operator) +TYPED_TEST(SmallString, const_subscript_operator) { + using SmallString = typename TestFixture::String; const SmallString text{"some text"}; auto &&sign = text[5]; @@ -1810,8 +1978,9 @@ TEST(SmallString, const_subscript_operator) ASSERT_THAT(sign, 't'); } -TEST(SmallString, non_const_subscript_operator) +TYPED_TEST(SmallString, non_const_subscript_operator) { + using SmallString = typename TestFixture::String; SmallString text{"some text"}; auto &&sign = text[5]; @@ -1819,8 +1988,9 @@ TEST(SmallString, non_const_subscript_operator) ASSERT_THAT(sign, 't'); } -TEST(SmallString, manipulate_const_subscript_operator) +TYPED_TEST(SmallString, manipulate_const_subscript_operator) { + using SmallString = typename TestFixture::String; const SmallString text{"some text"}; auto &&sign = text[5]; @@ -1829,8 +1999,9 @@ TEST(SmallString, manipulate_const_subscript_operator) ASSERT_THAT(text, SmallString{"some text"}); } -TEST(SmallString, manipulate_non_const_subscript_operator) +TYPED_TEST(SmallString, manipulate_non_const_subscript_operator) { + using SmallString = typename TestFixture::String; char rawText[] = "some text"; SmallString text{rawText}; auto &&sign = text[5]; @@ -1840,36 +2011,41 @@ TEST(SmallString, manipulate_non_const_subscript_operator) ASSERT_THAT(text, SmallString{"some qext"}); } -TEST(SmallString, empty_initializer_list_content) +TYPED_TEST(SmallString, empty_initializer_list_content) { + using SmallString = typename TestFixture::String; SmallString text = {}; ASSERT_THAT(text, SmallString()); } -TEST(SmallString, empty_initializer_list_size) +TYPED_TEST(SmallString, empty_initializer_list_size) { + using SmallString = typename TestFixture::String; SmallString text = {}; ASSERT_THAT(text, SizeIs(0)); } -TEST(SmallString, initializer_list_content) +TYPED_TEST(SmallString, initializer_list_content) { + using SmallString = typename TestFixture::String; auto text = SmallString::join({"some", " ", "text"}); ASSERT_THAT(text, SmallString("some text")); } -TEST(SmallString, initializer_list_size) +TYPED_TEST(SmallString, initializer_list_size) { + using SmallString = typename TestFixture::String; auto text = SmallString::join({"some", " ", "text"}); ASSERT_THAT(text, SizeIs(9)); } -TEST(SmallString, number_to_string) +TYPED_TEST(SmallString, number_to_string) { + using SmallString = typename TestFixture::String; ASSERT_THAT(SmallString::number(-0), "0"); ASSERT_THAT(SmallString::number(1), "1"); ASSERT_THAT(SmallString::number(-1), "-1"); @@ -1883,7 +2059,7 @@ TEST(SmallString, number_to_string) ASSERT_THAT(SmallString::number(-1.2f), "-1.2"); } -TEST(SmallString, string_view_plus_operator) +TYPED_TEST(SmallString, string_view_plus_operator) { SmallStringView text = "text"; @@ -1892,7 +2068,7 @@ TEST(SmallString, string_view_plus_operator) ASSERT_THAT(result, "text and more text"); } -TEST(SmallString, string_view_plus_operator_reverse_order) +TYPED_TEST(SmallString, string_view_plus_operator_reverse_order) { SmallStringView text = " and more text"; @@ -1901,8 +2077,9 @@ TEST(SmallString, string_view_plus_operator_reverse_order) ASSERT_THAT(result, "text and more text"); } -TEST(SmallString, string_plus_operator) +TYPED_TEST(SmallString, string_plus_operator) { + using SmallString = typename TestFixture::String; SmallString text = "text"; auto result = text + " and more text"; @@ -1910,8 +2087,9 @@ TEST(SmallString, string_plus_operator) ASSERT_THAT(result, "text and more text"); } -TEST(SmallString, string_plus_operator_reverse_order) +TYPED_TEST(SmallString, string_plus_operator_reverse_order) { + using SmallString = typename TestFixture::String; SmallString text = " and more text"; auto result = "text" + text; @@ -1919,23 +2097,23 @@ TEST(SmallString, string_plus_operator_reverse_order) ASSERT_THAT(result, "text and more text"); } -TEST(SmallString, short_string_capacity) +TYPED_TEST(SmallString, short_string_capacity) { - ASSERT_THAT(SmallString().shortStringCapacity(), 31); - ASSERT_THAT(PathString().shortStringCapacity(), 190); + ASSERT_THAT(Utils::SmallString().shortStringCapacity(), 31); + ASSERT_THAT(Utils::PathString().shortStringCapacity(), 176); } -TEST(SmallString, to_view) +TYPED_TEST(SmallString, to_view) { + using SmallString = typename TestFixture::String; SmallString text = "text"; auto view = text.toStringView(); ASSERT_THAT(view, "text"); - } -TEST(SmallString, compare) +TYPED_TEST(SmallString, compare) { const char longText[] = "textfoo"; @@ -1948,3 +2126,5 @@ TEST(SmallString, compare) ASSERT_THAT(Utils::compare("textx", "texta"), Gt(0)); ASSERT_THAT(Utils::compare("texta", "textx"), Le(0)); } + +} // namespace diff --git a/tests/unit/tests/utils/googletest.h b/tests/unit/tests/utils/googletest.h index 7da860f7ffa..2692eecece3 100644 --- a/tests/unit/tests/utils/googletest.h +++ b/tests/unit/tests/utils/googletest.h @@ -9,10 +9,12 @@ #include "conditionally-disabled-tests.h" -#include "../printers/gtest-creator-printing.h" -#include "../printers/gtest-qt-printing.h" #include "../printers/gtest-std-printing.h" +#include "../printers/gtest-qt-printing.h" + +#include "../printers/gtest-creator-printing.h" + #include "../utils/google-using-declarations.h" #include "../matchers/unittest-matchers.h"