Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libCOMBINE: allow a COMBINE archive to be initialised using some file contents #320

Open
wants to merge 117 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
284cfe0
CMake: some minor cleaning up.
agarny May 29, 2024
f97f2c7
libCOMBINE: use a version that allows to initialise a COMBINE archive…
agarny May 29, 2024
13041dd
CMake: show the output of configuring and building a third-party pack…
agarny May 29, 2024
d4ce6ad
COMBINE support: initialise a COMBINE archive using a file contents r…
agarny May 29, 2024
1993a09
Added modp_b64 as an external project.
agarny May 29, 2024
1373e11
extern: added a small README.rst file.
agarny May 29, 2024
08e37d0
CMake: improved the way we build clcachewrapper.
agarny May 29, 2024
30c7117
clcachewrapper: some minor cleaning up.
agarny May 30, 2024
347a258
CMake: added a small base64 encoder.
agarny May 30, 2024
4f7ccb0
Python: make the contents of a file a property.
agarny May 30, 2024
dbcd3f0
Tests: added a test for a virtual COMBINE archive.
agarny May 30, 2024
f900bc9
libCOMBINE: new binaries.
agarny Jun 4, 2024
687faeb
Account for our new libCOMBINE binaries.
agarny Jun 4, 2024
142ecc1
Test page: use LightningChart 4.2.1.
agarny Jun 4, 2024
8f3562a
Test page: output to the console the computing and plotting times.
agarny Jun 4, 2024
61d56cd
File: some minor cleaning up.
agarny Jun 4, 2024
af66fc9
Compiler: some minor cleaning up.
agarny Jun 4, 2024
6d8ad22
FileManager: implemented pimpl.
agarny Jun 4, 2024
d3aa1de
Tests: some minor cleaning up.
agarny Jun 4, 2024
96fbfdd
modp_b64: some minor cleaning up.
agarny Jun 4, 2024
5766aeb
Merge branch 'master' into issue214
agarny Jun 5, 2024
0620c39
Tests: some minor cleaning up.
agarny Jun 5, 2024
66e9d56
SedDocument: can now create using a SED-ML file and a COMBINE archive.
agarny Jun 5, 2024
5903bf6
Tests: enabled some tests now that we can recognise COMBINE archives.
agarny Jun 5, 2024
b361a88
Python: formatting.
agarny Jun 5, 2024
2ec02ed
Make code coverage happy again.
agarny Jun 5, 2024
56b4657
Make Clang-Tidy happy.
agarny Jun 5, 2024
34bf315
SedDocument: some minor cleaning up.
agarny Jun 6, 2024
7a5687d
FileManager: print managed files.
agarny Jun 6, 2024
9f4bc2c
CombineArchive: extract and keep track of the contained files.
agarny Jun 6, 2024
7bc5f49
Windows: improved UTF-8 support.
agarny Jun 6, 2024
4adf474
Merge branch 'master' into issue214.
agarny Jun 10, 2024
e2f95d8
Tests: some minor cleaning up.
agarny Jun 11, 2024
5322307
CMake: by default, enable unit testing for our JavaScript and Python …
agarny Jun 11, 2024
9e65bd9
Compiler: some minor cleaning up.
agarny Jun 11, 2024
ab26446
SedDocument: added a test to run a COMBINE archive.
agarny Jun 10, 2024
471beaa
JavaScript tests: fixed memory leaks.
agarny Jun 11, 2024
a6252d7
Test page: improved memory management.
agarny Jun 11, 2024
839fc37
Tests: updated our COMBINE archives.
agarny Jun 12, 2024
515177c
Tests: added more COMBINE archive related tests.
agarny Jun 12, 2024
17927a7
Tests: added a SED-ML related test with an absolute or a remote CellM…
agarny Jun 12, 2024
aa32e62
Python tests: some minor cleaning up.
agarny Jun 12, 2024
20d228d
Test page: recognise COMBINE archives.
agarny Jun 12, 2024
eec6902
Test page: improved memory management.
agarny Jun 12, 2024
53d962c
SedDocument tests: some minor cleaning up.
agarny Jun 13, 2024
a506ae4
SedDocument tests: renamed our run tests to instance tests.
agarny Jun 13, 2024
75c10a2
SedDocument tests: added a test to confirm that we correctly instanti…
agarny Jun 13, 2024
d15e727
SedDocument: retrieve the simulations of a SED-ML file.
agarny Jun 13, 2024
6333399
SedDocument: renamed createInstance() to instantiate().
agarny Jun 13, 2024
ee1aaa9
SedDocument: reorganised the way we initialise a SedDocument object.
agarny Jun 13, 2024
b75f6d9
SedFile: properly set the id of a model when populating a SedDocument…
agarny Jun 13, 2024
c2cd59f
Documentation.
agarny Jun 17, 2024
80c04d3
CMake: improved our memory checks.
agarny Jun 17, 2024
cd50fb9
FileManager: only use headers where actually needed.
agarny Jun 15, 2024
a66e480
FileManager: moved it to our API.
agarny Jun 15, 2024
27e986e
Merge branch 'master' into issue214.
agarny Jun 17, 2024
fc34e99
Merge branch 'master' into issue214.
agarny Jun 17, 2024
bf1d270
SedDocument: retrieve the algorithm of a simulation from a SED-ML file.
agarny Jun 18, 2024
8f4f37d
File: can now extract child files, if any/relevant.
agarny Jun 20, 2024
82aa117
SedDocument: create a default document if a SED-ML contains only one …
agarny Jun 21, 2024
93e7faa
Merge branch 'master' into issue214.
agarny Jun 21, 2024
23382fd
Merge branch 'master' into issue214.
agarny Jun 22, 2024
84554e8
Test page: added a favicon.ico file.
agarny Jun 22, 2024
cd7228c
Test page: some minor cleaning up.
agarny Jun 22, 2024
6767fb6
Test page: only show the simulation UI when we have a known file.
agarny Jun 22, 2024
e3e17b1
Test page: list files.
agarny Jun 22, 2024
1ea163d
FileManager: some minor cleaning up.
agarny Jun 23, 2024
efc4fbc
Pimpl: some consistency.
agarny Jun 23, 2024
2137e25
API: added an xxxCount() method to different classes.
agarny Jun 23, 2024
a0ceda7
Python: whenever possible, use def_property_readonly() rather than de…
agarny Jun 23, 2024
140369f
Pimpl: some consistency.
agarny Jun 24, 2024
4833785
Spell check.
agarny Jun 24, 2024
c0290eb
GHA: GitHub Actions' Windows runner has been fixed, so don't need our…
agarny Jun 24, 2024
9f326a9
API: slight improvement to our documentation.
agarny Jun 24, 2024
3293fe3
SedInstance tests: re-enabled a check now that we can run a COMBINE a…
agarny Jun 24, 2024
7301a27
FileManager: allow to manually manage/unmanage a file.
agarny Jun 24, 2024
c8f5163
FileManager: added a reset() method.
agarny Jun 24, 2024
07e8473
GHA
agarny Jun 24, 2024
1c860f5
Test page: reset the file manager using the reset button.
agarny Jun 24, 2024
dd57e53
Tests: slight update to our cellml_1_x.omex file.
agarny Jun 25, 2024
73b2369
Python tests: some minor cleaning up.
agarny Jun 25, 2024
9058982
FileManager: improved the reset() method.
agarny Jun 25, 2024
3ef3f3f
JavaScript tests: make use of the resourcePath() method.
agarny Jun 25, 2024
2da16cf
Test page: make it work with SED-ML files and COMBINE archives.
agarny Jun 25, 2024
557ac70
SedmlFile: properly initialise mLocation.
agarny Jun 25, 2024
4835dc2
JavaScript: some minor cleaning up.
agarny Jun 27, 2024
d848267
CellML/SED-ML: make sure that we don't try to read a file that is eff…
agarny Jun 27, 2024
094eba5
Utils: make sure to follow location when trying to donwload a file.
agarny Jun 30, 2024
d97a4af
SedmlFile: properly initialise mLocation.
agarny Jun 29, 2024
9eed30c
SedModel: added a method to retrieve the file that is associated with…
agarny Jun 29, 2024
91da598
Use a forward slash rather than a full point to join a component name…
agarny Jul 2, 2024
b9d7d01
SedInstance: add a way to specify initial conditions.
agarny Jul 2, 2024
4b4dc66
Utils: properly determine the canonical version of a file name.
agarny Jul 3, 2024
caa5b4f
libCellML: upgraded to commit 4966bad1.
agarny Jul 3, 2024
e93d2e7
File: retrieve a child file using a relative path.
agarny Jul 4, 2024
4795fa1
JavaScript: embed the WASM in the JavaScript file.
agarny Jul 18, 2024
79a1ce0
libCellML: upgraded to commit 707e211.
agarny Sep 18, 2024
4a02afe
Test page: use our local copy of font-awesome.
agarny Sep 20, 2024
128b8f0
Merge branch 'main' into issue214.
agarny Sep 23, 2024
19c0edd
Merge branch 'main' into issue214.
agarny Nov 12, 2024
4528de2
Merge branch 'main' into issue214.
agarny Nov 12, 2024
fc5fe34
Merge branch 'main' into issue214.
agarny Nov 13, 2024
13b96a1
modp_b64: upgraded to commit d09150a.
agarny Nov 13, 2024
ede5ab0
Merge branch 'main' into issue214.
agarny Nov 13, 2024
2ad2b55
Merge branch 'main' into issue214
agarny Nov 13, 2024
48eccef
Merge branch 'main' into issue214
agarny Nov 13, 2024
68eb3a2
Some minor cleaning up following the last merge.
agarny Nov 13, 2024
2fa86a4
Tests: removed unneeded header file.
agarny Nov 17, 2024
e6bb9c2
Fixed an issue with computing a canonical file name.
agarny Nov 17, 2024
a5f5b0c
SedmlFile: clarified a warning.
agarny Nov 17, 2024
2c71bbf
File tests: check existing relative local file.
agarny Nov 17, 2024
d3b0b82
SedInstance: removed our ISAN-specific way to specify initial conditi…
agarny Nov 18, 2024
7191826
CellmlFile: some minor cleaning up.
agarny Nov 18, 2024
8fe6f3b
CMake: some minor cleaning up.
agarny Nov 19, 2024
5331968
modp_b64: updated to version 7c1b327.
agarny Nov 19, 2024
17b2a50
FileManager: removed debugging code.
agarny Nov 19, 2024
4950216
File: a file is always managed.
agarny Nov 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .codespellexclude
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
afterAll(() => {
IssuePtrs mErrors;
return !mErrors.empty();
mErrors.push_back(issue);
return mErrors.size();
return mErrors;
mErrors.push_back(issue);
mErrors.clear();
return pimpl()->mErrors;
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ else()
if(JAVASCRIPT_BINDINGS_AVAILABLE)
if(JAVASCRIPT_UNIT_TESTING_AVAILABLE)
set(LIBOPENCOR_JAVASCRIPT_UNIT_TESTING_DOCSTRING "Enable JAVASCRIPT unit testing.")
set(LIBOPENCOR_JAVASCRIPT_UNIT_TESTING OFF CACHE BOOL "${LIBOPENCOR_JAVASCRIPT_UNIT_TESTING_DOCSTRING}")
set(LIBOPENCOR_JAVASCRIPT_UNIT_TESTING ${LIBOPENCOR_JAVASCRIPT_BINDINGS} CACHE BOOL "${LIBOPENCOR_JAVASCRIPT_UNIT_TESTING_DOCSTRING}")
endif()

if(NOT "${JAVASCRIPT_UNIT_TESTING}" STREQUAL "" AND JAVASCRIPT_UNIT_TESTING_AVAILABLE)
Expand Down Expand Up @@ -372,7 +372,7 @@ else()
if(PYTHON_BINDINGS_AVAILABLE)
if(PYTHON_UNIT_TESTING_AVAILABLE)
set(LIBOPENCOR_PYTHON_UNIT_TESTING_DOCSTRING "Enable Python unit testing.")
set(LIBOPENCOR_PYTHON_UNIT_TESTING OFF CACHE BOOL "${LIBOPENCOR_PYTHON_UNIT_TESTING_DOCSTRING}")
set(LIBOPENCOR_PYTHON_UNIT_TESTING ${LIBOPENCOR_PYTHON_BINDINGS} CACHE BOOL "${LIBOPENCOR_PYTHON_UNIT_TESTING_DOCSTRING}")
endif()

if(NOT "${PYTHON_UNIT_TESTING}" STREQUAL "" AND PYTHON_UNIT_TESTING_AVAILABLE)
Expand Down
57 changes: 57 additions & 0 deletions cmake/base64encoder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Copyright libOpenCOR contributors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "../extern/modp_b64/modp_b64.h"

#include <filesystem>
#include <fstream>
#include <iostream>

int main(int pArgC, char *pArgV[])
{
// Convert the given file to a base64-encoded string.

if (pArgC != 2) {
std::cerr << "Usage: " << pArgV[0] << " <file>" << std::endl;

return 1;
}

std::uintmax_t fileSize = std::filesystem::file_size(pArgV[1]);
char *buffer = new char[fileSize];
std::ifstream file(pArgV[1], std::ios::binary);

file.read(buffer, fileSize);

if (!file) {
std::cerr << "Error: the file could not be read." << std::endl;

return 1;
}

file.close();

char *base64 = new char[modp_b64_encode_len(fileSize)];

modp_b64_encode(base64, buffer, fileSize);

std::cout << base64 << std::endl;

delete[] base64;
delete[] buffer;

return 0;
}
11 changes: 11 additions & 0 deletions cmake/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -386,14 +386,25 @@ endfunction()

function(prepare_test TARGET)
# Prepare the given test.
# Note: we don't want modp_b64.cc to be subjected to Clang-Tidy, hence we compile it separately. From Cmake 3.27,
# we could use the SKIP_LINTING property to exclude it from Clang-Tidy, but for some reasons it's not working,
# so we compile it separately (as suggested at https://stackoverflow.com/a/75858167).

add_executable(${TARGET}
${ARGN})

add_dependencies(${TARGET} ${CMAKE_PROJECT_NAME})

set(MODP_B64_TARGET ${TARGET}_modp_b64)

add_library(${MODP_B64_TARGET} OBJECT ${CMAKE_SOURCE_DIR}/extern/modp_b64/modp_b64.cc)

set_target_properties(${MODP_B64_TARGET} PROPERTIES
CXX_CLANG_TIDY "")

target_link_libraries(${TARGET} PRIVATE
gtest_main
${MODP_B64_TARGET}
${CMAKE_PROJECT_NAME})

configure_target(${TARGET})
Expand Down
6 changes: 3 additions & 3 deletions cmake/environmentchecks.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -324,12 +324,12 @@ if(PYTHON_UNIT_TESTING_AVAILABLE AND PYTHON_EXE)
endif()
endif()

if( (APPLE AND LEAKS_EXE)
OR (NOT WIN32 AND PYTHON_EXE AND VALGRIND_EXE))
if( (APPLE AND PYTHON_EXE AND LEAKS_EXE)
OR (NOT APPLE AND NOT WIN32 AND PYTHON_EXE AND VALGRIND_EXE))
set(MEMORY_CHECKS_AVAILABLE TRUE)
else()
if(APPLE)
set(MEMORY_CHECKS_ERROR_MESSAGE "Memory checks are requested but the leaks tool could not be found.")
set(MEMORY_CHECKS_ERROR_MESSAGE "Memory checks are requested but Python and/or the leaks tool could not be found.")
else()
set(MEMORY_CHECKS_ERROR_MESSAGE "Memory checks are requested but Python and/or Valgrind could not be found.")
endif()
Expand Down
2 changes: 1 addition & 1 deletion cmake/packages.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ function(retrieve_package PACKAGE_NAME PACKAGE_VERSION PACKAGE_REPOSITORY RELEAS
if("${PACKAGE_NAME}" STREQUAL "libCellML")
#---GRY--- THIS IS TEMPORARY UNTIL libCellML HAS AN OFFICIAL RELEASE WITH THE INTERPRETER.

set(PACKAGE_URL "https://github.com/agarny/${PACKAGE_REPOSITORY}/releases/download/584ebb5/${PACKAGE_FILE}")
set(PACKAGE_URL "https://github.com/agarny/${PACKAGE_REPOSITORY}/releases/download/707e211/${PACKAGE_FILE}")
endif()

file(DOWNLOAD ${PACKAGE_URL} ${REAL_PACKAGE_FILE} STATUS STATUS)
Expand Down
3 changes: 2 additions & 1 deletion extern/README.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
`libOpenCOR <https://opencor.ws/libopencor/index.html>`__ relies on the following external projects:

- `GoogleTest <https://github.com/google/googletest>`__ `1.15.2 <https://github.com/google/googletest/releases/tag/v1.15.2>`__; and
- `GoogleTest <https://github.com/google/googletest>`__ `1.15.2 <https://github.com/google/googletest/releases/tag/v1.15.2>`__;
- `modp_b64 <https://chromium.googlesource.com/chromium/src/third_party/modp_b64/>`__ at commit `7c1b327 <https://chromium.googlesource.com/chromium/src/third_party/modp_b64/+/7c1b3276e72757e854b5b642284aa367436a4723>`__; and
- `nanobind <https://github.com/wjakob/nanobind>`__ `2.1.0 <https://github.com/wjakob/nanobind/releases/tag/v2.1.0>`__.
11 changes: 11 additions & 0 deletions extern/modp_b64/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright 2013 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

static_library("modp_b64") {
sources = [
"modp_b64.cc",
"modp_b64.h",
"modp_b64_data.h",
]
}
3 changes: 3 additions & 0 deletions extern/modp_b64/DEPS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include_rules = [
'+build',
]
6 changes: 6 additions & 0 deletions extern/modp_b64/DIR_METADATA
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
monorail: {
component: "Internals"
}
buganizer_public: {
component_id: 1456292
}
33 changes: 33 additions & 0 deletions extern/modp_b64/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
* MODP_B64 - High performance base64 encoder/decoder
* Version 1.3 -- 17-Mar-2006
* http://modp.com/release/base64
*
* Copyright (c) 2005, 2006 Nick Galbreath -- nickg [at] modp [dot] com
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of the modp.com nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1 change: 1 addition & 0 deletions extern/modp_b64/OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pkasting@chromium.org
24 changes: 24 additions & 0 deletions extern/modp_b64/README.chromium
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Name: modp base64 decoder
Short Name: stringencoders
URL: https://github.com/client9/stringencoders
Version: 2.0.0
Revision: 26701a1c1fcb98ae43eefcaee23abc58459a6e59
License: BSD-3-Clause
License File: LICENSE
Security Critical: yes
Shipped: yes

Description:
The source code was modified from upstream as follows:
- Removed the inclusion of modp's config.h
- Fixed compilation errors that occur under VC8
- Renamed modp_b64.c to modp_b64.cc to force it to be compiled as C++ and so
the inclusion of basictypes.h could be possible
- Made code safe on 64-bit systems
- Removed misaligned read/writes on little-endian systems
- Removed unreachable code
- Extended the API so callers can avoid overload for base64 encode
- Removed big endian support entirely
- Removed std::string APIs
- Added multiple decoding options to support Blink callers
- Added modp_b64_encode_data which doesn't append a null terminator
168 changes: 168 additions & 0 deletions extern/modp_b64/modp_b64.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set expandtab shiftwidth=4 tabstop=4: */
/**
* \file
* <PRE>
* MODP_B64 - High performance base64 encoder/decoder
* Version 1.3 -- 17-Mar-2006
* http://modp.com/release/base64
*
* Copyright &copy; 2005, 2006 Nick Galbreath -- nickg [at] modp [dot] com
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of the modp.com nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This is the standard "new" BSD license:
* http://www.opensource.org/licenses/bsd-license.php
* </PRE>
*/

/* public header */
#include "modp_b64.h"

#include "modp_b64_data.h"

#define BADCHAR 0x01FFFFFF

size_t modp_b64_encode_data(char* dest, const char* str, size_t len)
{
size_t i = 0;
uint8_t* p = (uint8_t*) dest;

/* unsigned here is important! */
uint8_t t1, t2, t3;

if (len > 2) {
for (; i < len - 2; i += 3) {
t1 = str[i]; t2 = str[i+1]; t3 = str[i+2];
*p++ = e0[t1];
*p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
*p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)];
*p++ = e2[t3];
}
}

switch (len - i) {
case 0:
break;
case 1:
t1 = str[i];
*p++ = e0[t1];
*p++ = e1[(t1 & 0x03) << 4];
*p++ = CHARPAD;
*p++ = CHARPAD;
break;
default: /* case 2 */
t1 = str[i]; t2 = str[i+1];
*p++ = e0[t1];
*p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
*p++ = e2[(t2 & 0x0F) << 2];
*p++ = CHARPAD;
}

return p - (uint8_t*)dest;
}

size_t modp_b64_encode(char* dest, const char* str, size_t len) {
size_t output_size = modp_b64_encode_data(dest, str, len);
dest[output_size] = '\0';
return output_size;
}

size_t do_decode_padding(const char* src, size_t len, ModpDecodePolicy policy) {
if (policy == ModpDecodePolicy::kNoPaddingValidation) {
while (len > 0 && src[len - 1] == CHARPAD) {
len--;
}
} else {
const size_t remainder = len % 4;
if (policy == ModpDecodePolicy::kStrict && (remainder != 0 || len < 4))
return MODP_B64_ERROR;
if (remainder == 0) {
if (src[len - 1] == CHARPAD) {
len--;
if (src[len - 1] == CHARPAD) {
len--;
}
}
}
}
return len % 4 == 1 ? MODP_B64_ERROR : len;
}

size_t modp_b64_decode(char* dest, const char* src, size_t len, ModpDecodePolicy policy)
{
if (len != 0)
len = do_decode_padding(src, len, policy);

if (len == 0 || len == MODP_B64_ERROR)
return len;

size_t i;
int leftover = len % 4;
size_t chunks = (leftover == 0) ? len / 4 - 1 : len /4;

uint8_t* p = (uint8_t*)dest;
uint32_t x = 0;
const uint8_t* y = (uint8_t*)src;
for (i = 0; i < chunks; ++i, y += 4) {
x = d0[y[0]] | d1[y[1]] | d2[y[2]] | d3[y[3]];
if (x >= BADCHAR) return MODP_B64_ERROR;
*p++ = ((uint8_t*)(&x))[0];
*p++ = ((uint8_t*)(&x))[1];
*p++ = ((uint8_t*)(&x))[2];
}

switch (leftover) {
case 0:
x = d0[y[0]] | d1[y[1]] | d2[y[2]] | d3[y[3]];

if (x >= BADCHAR) return MODP_B64_ERROR;
*p++ = ((uint8_t*)(&x))[0];
*p++ = ((uint8_t*)(&x))[1];
*p = ((uint8_t*)(&x))[2];
return (chunks+1)*3;
case 1: /* with padding this is an impossible case */
x = d0[y[0]];
*p = *((uint8_t*)(&x)); // i.e. first char/byte in int
break;
case 2: // * case 2, 1 output byte */
x = d0[y[0]] | d1[y[1]];
*p = *((uint8_t*)(&x)); // i.e. first char
break;
default: /* case 3, 2 output bytes */
x = d0[y[0]] | d1[y[1]] | d2[y[2]]; /* 0x3c */
*p++ = ((uint8_t*)(&x))[0];
*p = ((uint8_t*)(&x))[1];
break;
}

if (x >= BADCHAR) return MODP_B64_ERROR;

return 3*chunks + (6*leftover)/8;
}
Loading
Loading