Merge remote-tracking branch 'origin/docs' into cmake
This commit is contained in:
commit
4ad66f5c13
55
.gitattributes
vendored
55
.gitattributes
vendored
@ -38,32 +38,37 @@ Makefile text eol=lf encoding=utf-8
|
||||
|
||||
# Force binary files to be binary
|
||||
|
||||
# Archives
|
||||
*.7z filter=lfs diff=lfs merge=lfs -text
|
||||
*.br filter=lfs diff=lfs merge=lfs -text
|
||||
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||
*.tar filter=lfs diff=lfs merge=lfs -text
|
||||
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
# Documents
|
||||
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
# Images
|
||||
*.gif filter=lfs diff=lfs merge=lfs -text
|
||||
*.ico filter=lfs diff=lfs merge=lfs -text
|
||||
*.jpg filter=lfs diff=lfs merge=lfs -text
|
||||
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
||||
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||
*.png filter=lfs diff=lfs merge=lfs -text
|
||||
*.psd filter=lfs diff=lfs merge=lfs -text
|
||||
*.webp filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
# Fonts
|
||||
*.woff2 filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
# Other
|
||||
*.exe filter=lfs diff=lfs merge=lfs -text
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
|
@ -1,6 +1,7 @@
|
||||
[core]
|
||||
autocrlf = input
|
||||
whitespace = -tab-in-indent,tabwidth=4,indent-with-non-tab,trailing-space,space-before-tab
|
||||
whitespace = fix
|
||||
safecrlf=warn
|
||||
[apply]
|
||||
whitespace = fix
|
||||
@ -12,6 +13,8 @@
|
||||
[commit]
|
||||
gpgSign = true
|
||||
[submodule]
|
||||
recurseSubmodules = on-demand
|
||||
recurseSubmodules = on-demand
|
||||
[fetch]
|
||||
recurseSubmodules = on-demand
|
||||
recurseSubmodules = on-demand
|
||||
[diff]
|
||||
submodule = log
|
||||
|
12
.gitmodules
vendored
12
.gitmodules
vendored
@ -1,11 +1,9 @@
|
||||
[submodule "libsodium"]
|
||||
path = libsodium
|
||||
url = https://github.com/jedisct1/libsodium.git
|
||||
ignore = dirty
|
||||
[submodule "wxWidgets"]
|
||||
path = wxWidgets
|
||||
url = https://github.com/wxWidgets/wxWidgets.git
|
||||
ignore = dirty
|
||||
url = cpal.pw:~/libsodium.git
|
||||
[submodule "mpir"]
|
||||
path = mpir
|
||||
url = https://github.com/BrianGladman/mpir.git
|
||||
url = cpal.pw:~/mpir.git
|
||||
[submodule "wxWidgets"]
|
||||
path = wxWidgets
|
||||
url = cpal.pw:~/wxWidgets.git
|
||||
|
@ -25,11 +25,11 @@ namespace ro {
|
||||
// copy constructor
|
||||
sql(const sql& a) = delete;
|
||||
// move constructor
|
||||
sql(sql&& p) :std::unique_ptr<Icompiled_sql>(p.release()) { }
|
||||
sql(sql&& p) noexcept :std::unique_ptr<Icompiled_sql>(p.release()) { }
|
||||
// copy assignment
|
||||
sql& operator=(const sql) = delete;
|
||||
// Move assignment
|
||||
sql& operator=(sql&& p) {
|
||||
sql& operator=(sql&& p) noexcept {
|
||||
std::unique_ptr<Icompiled_sql>::reset(p.release());
|
||||
}
|
||||
sql(Icompiled_sql* p) :std::unique_ptr<Icompiled_sql>(p) {}
|
||||
|
@ -102,6 +102,105 @@ repository results in non portable surprises and complexity. Makes it hard
|
||||
for anyone else to build your project, because they will have to, by hand,
|
||||
tell your project where the libraries are on their system.
|
||||
|
||||
When one is developing code, you normally have a git branch. But
|
||||
the git commit of the master project in which the submodule is
|
||||
contained does not notice its subproject has changed, unless the
|
||||
subproject head has changed. And the subject project head will not
|
||||
change if it points to a name, rather than to a particular commit. For
|
||||
ones changes to a submodule to be reflected in the master project in
|
||||
any consistent or predictable way, the submodule has to be in
|
||||
detached head mode, with the head pointing directly to a commit,
|
||||
rather than pointing to a branch that points to a commit.
|
||||
|
||||
Git commands in master project do not look inside the subproject.
|
||||
They just look at the subproject's head.
|
||||
|
||||
This means that signing off on changes to a submodule is
|
||||
irrelevant. One signs off on the master project, which includes the
|
||||
hash of that submodule commit.
|
||||
|
||||
When one is changing submodules for the use of a particular
|
||||
project, making related changes in the master project and
|
||||
submodules, one should not track the changes by creating and
|
||||
updating branch names in the submodule, but by creating and
|
||||
updating branch names in the containing module, so that the
|
||||
commits in the submodule have no name in the submodule, the
|
||||
submodule is always in detached head state, albeit the head may be
|
||||
tagged. Names in submodules are primarily of value for
|
||||
amendments to the submodule as an independent module,
|
||||
intended to be used by multiple projects, and for this purpose, tags
|
||||
are better than branch names. wxWidgets releases are identified by
|
||||
tag, not by branch, and the names of branches are only used to
|
||||
communicate a particular project on the submodule to other people
|
||||
working on that project as their master project.
|
||||
|
||||
Branch names are not useful within a submodule, though
|
||||
submodule may well be, from the point of view of the primary
|
||||
developers, not a submodule but a module in its own right, used as
|
||||
a submodule in many different modules, so for them, branch names
|
||||
will be useful. But when you are modifying the submodules in a
|
||||
project as a single project, making related changes in the module
|
||||
and submodule, the names belong in the primary project module,
|
||||
Within the submodule, commits are nameless with detached head,
|
||||
the name in primary module naming a group of related commits in
|
||||
several submodules, which commits do not usually receive
|
||||
independent names of their own, even though the commits have to
|
||||
be made within the submodule, not in the containing module which
|
||||
names the complete set of interrelated commits.
|
||||
|
||||
In this case, working on submodules as part of a single larger project, you should set
|
||||
|
||||
```bash
|
||||
git config --local submodule.recurse true
|
||||
```
|
||||
|
||||
In the primary project, so that you conveniently push and pull a
|
||||
group of related changes as one thing, and the build for the whole
|
||||
project should treat the submodule libraries as having a
|
||||
dependency on module/.git/modules/submodule/HEAD, rather than
|
||||
checking every single file in the submodules every time to see
|
||||
if one has changed, for there could be an enormous number of
|
||||
them. The primary build should invoke the submodule build, which
|
||||
*will* check each file in the submodule for changes, only when the
|
||||
submodule detached head has changed. And therefore, you want it
|
||||
to change, you want the submodule head to be nameless and
|
||||
detached, whenever you modify a submodule as part of a larger
|
||||
project where you test your changes by rebuilding the whole
|
||||
project to make sure all your related changes fit together.
|
||||
|
||||
When tracking an upstream submodule that has submodules of its
|
||||
own, which have their own upstreams
|
||||
|
||||
Update your version with
|
||||
|
||||
```bash
|
||||
git pull upstream --recurse-submodules=on-demand «their-latest-release»
|
||||
```
|
||||
|
||||
Make sure things still work. Get everything working. (You do have unit test, right?)
|
||||
|
||||
then:
|
||||
|
||||
```bash
|
||||
git submodule foreach --recursive 'git push origin HEAD:«your-tracking-branch»'
|
||||
git submodule foreach --recursive 'git switch --detach'
|
||||
```
|
||||
|
||||
All of which, of course, presupposes you have already set unit tests,
|
||||
upstream, origin, and your tracking branch appropriately.
|
||||
|
||||
Even if your local modifications are nameless in your local
|
||||
submodule repository, on your remote submodule repository they
|
||||
need to have a name to be pushed to, hence you need to have a
|
||||
tracking branch in each of your remote images of each of your
|
||||
submodules, and that tracking branch will need to point to the root
|
||||
of a tree of all the nameless commits that the names and commits
|
||||
in your superproject that contains this submodules point to.
|
||||
|
||||
You want `.gitmodules` in your local image of the repository to
|
||||
reflect the location and fork of your new remote repository, with
|
||||
your remote as its `origin` and their remote as its `upstream`.
|
||||
|
||||
You need an enormous pile of source code, the work of many people over
|
||||
a very long time, and GitSubmodules allows this to scale, because the
|
||||
local great big pile of source code references many independent and
|
||||
@ -153,7 +252,6 @@ submodule and the next are such that one is only likely to make changes in
|
||||
one module at at time.
|
||||
|
||||
# Passphrases
|
||||
|
||||
All wallets now use random words - but you cannot carry an eighteen word random phrase though an airport in you head
|
||||
|
||||
Should use [grammatically correct passphrases](https://github.com/lungj/passphrase_generator).
|
||||
|
@ -188,7 +188,7 @@ way. Going to use base52 for any purposes for which my bright idea
|
||||
would have been useful, so should be rewritten to base64 regardless.
|
||||
|
||||
Using the hash of shared state goes together with immutable
|
||||
append only Merkle-patricia trees like ham and eggs, though you
|
||||
append only Merkle‑patricia trees like ham and eggs, though you
|
||||
don't need to keep the potentially enormous data structure around.
|
||||
When a connection has no activity for a little while, you can discard
|
||||
everything except a very small amount of data, primarily the keys,
|
||||
|
@ -1,6 +1,12 @@
|
||||
body {
|
||||
max-width: 30em;
|
||||
margin-left: 1em;
|
||||
font-family: "Georgia, Times New Roman", Times, serif;
|
||||
font-style: normal;
|
||||
font-variant: normal;
|
||||
font-weight: normal;
|
||||
font-stretch: normal;
|
||||
font-size: 16px;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
|
@ -49,13 +49,15 @@ takes a while. Normally when you make changes to the source code you
|
||||
should rebuild just the program, using `wallet.sln` on windows.
|
||||
To rebuild the documents after editing them, `docs/mkdocs.sh`
|
||||
|
||||
winConfigure.bat also configures the repository you just created to
|
||||
to use `.gitconfig` in the repository, causing git to to implement
|
||||
GPG signed commits -- because [cryptographic software is under attack]
|
||||
from NSA entryists and shills, who seek to introduce backdoors.
|
||||
winConfigure.bat also configures the repository you just created to use
|
||||
`.gitconfig` in the repository, causing git to to implement GPG signed
|
||||
commits -- because [cryptographic software is under attack] from NSA
|
||||
entryists and shills, who seek to introduce backdoors.
|
||||
|
||||
This may be inconvenient if you do not have `gpg` installed and set up.
|
||||
|
||||
It also means that subsequent pulls and merges will require you to have `gpg `trust the key `public_key.gpg`, and if you submit a pull request, the puller will need to trust your `gpg` public key.
|
||||
|
||||
`.gitconfig` adds several git aliases:
|
||||
|
||||
1. `git lg` to display the gpg trust information for the last few commits.
|
||||
@ -80,6 +82,13 @@ of Trust is too complicated and too user hostile to be workable or safe.
|
||||
|
||||
Never --sign any Gpg key related to this project. --lsign it.
|
||||
|
||||
`gitconfig` disallows merges unless you have told `gpg` to trust the
|
||||
public key corresponding to the private key that signed the tip of
|
||||
the root. So part of the pull request process is getting the puller to
|
||||
trust your public key, and you will not be able to pull updates
|
||||
unless you tell `gpg` to trust the key that is in the root directory as
|
||||
`public_key.gpg`.
|
||||
|
||||
Never check any Gpg key related to this project against a public
|
||||
gpg key repository. It should not be there.
|
||||
|
||||
|
@ -176,6 +176,12 @@ Setting up an actual server is similar to setting up the virtual machine
|
||||
modelling it, except you have to worry about the server getting overloaded
|
||||
and locking up.
|
||||
|
||||
On an actual server, you probably want to totally disable passwords by corrupting the shadow file once you have `ssh` working.
|
||||
|
||||
```bash
|
||||
usermod -L root
|
||||
```
|
||||
|
||||
If a server is configured with an [ample swap file] an overloaded server will
|
||||
lock up and have to be ungracefully powered down, which can corrupt the data
|
||||
on the server. If the swap file is inadequate, the OOM killer will shut
|
||||
|
52
docs/set_upstream.sh
Normal file
52
docs/set_upstream.sh
Normal file
@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
set -x
|
||||
echo intended to be run in the event of moving repositories
|
||||
git remote -v
|
||||
git remote set-url origin git@cpal.pw:~/wallet.git
|
||||
git submodule foreach --recursive 'git remote -v'
|
||||
cd libsodium
|
||||
git remote set-url origin git@cpal.pw:~/libsodium.git
|
||||
git remote set-url upstream https://github.com/jedisct1/libsodium.git
|
||||
cd ..
|
||||
cd mpir
|
||||
git remote set-url origin git@cpal.pw:~/mpir.git
|
||||
git remote set-url upstream https://github.com/BrianGladman/mpir.git
|
||||
cd ..
|
||||
cd wxWidgets
|
||||
git remote set-url origin git@cpal.pw:~/wxWidgets.git
|
||||
git remote set-url upstream https://github.com/wxWidgets/wxWidgets.git
|
||||
cd ..
|
||||
cd wxWidgets/3rdparty/catch
|
||||
git remote set-url origin git@cpal.pw:~/Catch.git
|
||||
git remote set-url upstream https://github.com/wxWidgets/Catch.git
|
||||
cd ../../..
|
||||
cd wxWidgets/3rdparty/nanosvg
|
||||
git remote set-url origin git@cpal.pw:~/nanosvg
|
||||
git remote set-url upstream https://github.com/wxWidgets/nanosvg
|
||||
cd ../../..
|
||||
cd wxWidgets/3rdparty/pcre
|
||||
git remote set-url origin git@cpal.pw:~/pcre
|
||||
git remote set-url upstream https://github.com/wxWidgets/pcre
|
||||
cd ../../..
|
||||
cd wxWidgets/src/expat
|
||||
git remote set-url origin git@cpal.pw:~/libexpat.git
|
||||
git remote set-url upstream https://github.com/wxWidgets/libexpat.git
|
||||
cd ../../..
|
||||
cd wxWidgets/src/jpeg
|
||||
git remote set-url origin git@cpal.pw:~/libjpeg-turbo.git
|
||||
git remote set-url upstream https://github.com/wxWidgets/libjpeg-turbo.git
|
||||
cd ../../..
|
||||
cd wxWidgets/src/png
|
||||
git remote set-url origin git@cpal.pw:~/libpng.git
|
||||
git remote set-url upstream https://github.com/wxWidgets/libpng.git
|
||||
cd ../../..
|
||||
cd wxWidgets/src/tiff
|
||||
git remote set-url origin git@cpal.pw:~/libtiff.git
|
||||
git remote set-url upstream https://github.com/wxWidgets/libtiff.git
|
||||
cd ../../..
|
||||
cd wxWidgets/src/zlib
|
||||
git remote set-url origin git@cpal.pw:~/zlib.git
|
||||
git remote set-url upstream https://github.com/wxWidgets/zlib.git
|
||||
cd ../../..
|
||||
winConfigure.sh
|
@ -264,6 +264,40 @@ So, you can navigate to whole world’s public conversation through
|
||||
approved links and reply-to links – but not every spammer, scammer, and
|
||||
shill in the world can fill your feed with garbage.
|
||||
|
||||
## Algorithm and data structure.
|
||||
|
||||
For this to work, the underlying structure needs to be something based on
|
||||
the same principles as Git and git repositories, except that Git relies on
|
||||
SSL and the Certificate Authority system to locate a repository, which
|
||||
dangerous centralization would fail under the inevitable attack. It needs to
|
||||
have instead for its repository name system a Kamelia distributed has
|
||||
table within which local repositories find the network addresses of remote
|
||||
repositories on the basis of the public key of a Zooko identity of a person
|
||||
who pushed a tag or a branch to that repository, a branch being a thread,
|
||||
and the branch head in this case being the most recent response to a thread
|
||||
by a person you are following.
|
||||
|
||||
The Distributed hash table key will be:\
|
||||
`human readable area of interest name/#public key of zooko name/
|
||||
human readable branch name/#hash of data item`\
|
||||
so that items that are likely to be looked up together will likely be near
|
||||
each other on the same physical disk, and transmitted over the same
|
||||
network connection. When someone approves of a text, then it goes into a
|
||||
repository he controls or has write access to, and gets a corresponding key
|
||||
in the distributed hash table.
|
||||
|
||||
The messages of the people you are following are likely to be in a
|
||||
relatively small number of repositories, even if the total number of
|
||||
repositories out there is enormous and the number of hashes in each
|
||||
repository is enormous, so this algorithm and data structure will scale, and
|
||||
the responses to that thread that they have approved, by people you are not
|
||||
following, will be commits in that repository, that, by pushing their latest
|
||||
response to that thread to a public repository, they committed to that
|
||||
repository.
|
||||
|
||||
Each repository contains all the material the poster has approved, resulting
|
||||
in considerable duplication, but not enormous duplication.
|
||||
|
||||
The underlying protocol and mechanism is that when you are following
|
||||
Bob, you get a Bob feed from a machine controlled by Bob, or controlled
|
||||
by someone that Bob has chosen to act on his behalf, and that when Bob
|
||||
|
@ -14,18 +14,54 @@ namespace ro {
|
||||
return id ^ (id >> 32);
|
||||
}
|
||||
|
||||
class charmap :public std::array<char, 0x100> {
|
||||
class charmap {
|
||||
public:
|
||||
std::array< char, 0x100> index{ 0, };
|
||||
charmap() = delete;
|
||||
constexpr charmap(const char* p, const char* q) {
|
||||
constexpr charmap(const char * p, const char * q) {
|
||||
while (unsigned int pu{ static_cast<unsigned char>(*p++) }) {
|
||||
assert((*this)[pu] == 0);
|
||||
(*this)[pu] = *q++;
|
||||
assert(index[pu] == 0);
|
||||
index[pu] = *q++;
|
||||
}
|
||||
assert(*(p - 1) == '\0' && *q == '\0');
|
||||
assert(*(p - 1) == '\0' && *q == '\0');
|
||||
/* when an instance of this class is declared constexpr,
|
||||
an assert does not trigger a run time error,
|
||||
because expression evaluated at compile time.
|
||||
Instead the compiler reports that the expression
|
||||
did not evaluate to a constant,
|
||||
|
||||
The error is confusing, because the error points to
|
||||
the declaration where the initialization was invoked,
|
||||
instead of pointing to the assert.
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
class charmapWithFixup {
|
||||
public:
|
||||
std::array< char, 0x100> index{ 0, };
|
||||
charmapWithFixup() = delete;
|
||||
constexpr charmapWithFixup(const char* p, const char* q) {
|
||||
while (unsigned int pu{ static_cast<unsigned char>(*p++) }) {
|
||||
assert(index[pu] == 0);
|
||||
index[pu] = *q++;
|
||||
}
|
||||
index['I'] = index['l']='0';
|
||||
assert(*(p - 1) == '\0' && *q == '\0');
|
||||
/* when an instance of this class is declared constexpr,
|
||||
an assert does not trigger a run time error,
|
||||
because expression evaluated at compile time.
|
||||
Instead the compiler reports that the expression
|
||||
did not evaluate to a constant,
|
||||
|
||||
The error is confusing, because the error points to
|
||||
the declaration where the initialization was invoked,
|
||||
instead of pointing to the assert.
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//template <> class base58<scalar> : public CompileSizedString<44> {};
|
||||
static_assert(sizeof(base58<point>) == 46, "base58 point strings unexpected size");
|
||||
|
||||
@ -33,17 +69,18 @@ namespace ro {
|
||||
static constexpr char index2MpirBase58[] { "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv" };
|
||||
|
||||
void map_base_from_mpir58(char* p) {
|
||||
static const charmap map(index2MpirBase58, index2cryptoBase58);
|
||||
while (unsigned int pu{ static_cast<unsigned char>(*p) }) {
|
||||
*p++ = map[pu];
|
||||
static constexpr charmap map(index2MpirBase58, index2cryptoBase58);
|
||||
while (uint8_t pu{ static_cast<uint8_t>(*p) }) {
|
||||
*p++ = map.index[pu];
|
||||
}
|
||||
}
|
||||
|
||||
void map_base_to_mpir58(const char* p, char* q, size_t count) {
|
||||
static const charmap map(index2cryptoBase58, index2MpirBase58);
|
||||
static constexpr charmap map(index2cryptoBase58, index2MpirBase58);
|
||||
static_assert(map.index[0xF0] == 0);
|
||||
while (count--) {
|
||||
unsigned int pu{ static_cast<unsigned char>(*p++) };
|
||||
char c{ map[pu] };
|
||||
char c{ map.index[pu] };
|
||||
if (c == '\0') throw NotBase58Exception();
|
||||
*q++ = c;
|
||||
}
|
||||
|
105
slash6.cpp
105
slash6.cpp
@ -15,11 +15,30 @@
|
||||
static constexpr uint8_t index2base64[]{
|
||||
"0123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz!$*+-_"
|
||||
};
|
||||
|
||||
/*
|
||||
control characters are stops
|
||||
! $ * + - permitted The characters "#%&'(),. are stops
|
||||
0-9 permitted The characters :;<=>? are stops
|
||||
A-Z and _ permitted, @ and [\]^ are stops
|
||||
a-z permitted. {|} ~` are stops, as is the mysterious control character 0x7F (del)
|
||||
*/
|
||||
// Unlike regular baseINV, and incompatible with it. Intended to encode stuff small enough
|
||||
// that it might be human typed and human transmitted, therefore maps 'o' and 'O' to '0', 'I' and
|
||||
// 'l' to '1'
|
||||
// uses six url safe additional characters !$*+-_ to bring it up to six bits
|
||||
//
|
||||
// But on reflection, useless, since human typed stuff like this should use Bitcoin's base 58 encoding
|
||||
// So going to switch to regular base64, despite the unreasonably immense amount of work I put into it.
|
||||
|
||||
// Unfortunately, Wireguard, with which I am going to need to interoperate, uses RFC4648, whose
|
||||
// algorithm is fundamentally different - no special treatment for I, O, o, and l, and uses =
|
||||
// to handle the case where you have boundary problems between eight and six bit groups.
|
||||
// They force everything to four character groups, using an = sign to indicate that the
|
||||
// bytes being represented stop before a multiple of three. https://www.base64encode.org
|
||||
|
||||
|
||||
|
||||
|
||||
static_assert(index2base64[63] == '_', "surprise numeral at 63");
|
||||
|
||||
// Being intended for small bits of data, assumes no whitespace within an entity
|
||||
@ -35,41 +54,71 @@ static_assert(index2base64[63] == '_', "surprise numeral at 63");
|
||||
// will return a number of bits less than the size of the input bit buffer, less than the bitcount
|
||||
// it was given.
|
||||
|
||||
// Table to convert ascii to six bit.
|
||||
static constexpr std::array<constexpr uint8_t, 0x100> ascii2six_ar{
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //control characters
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //control characters
|
||||
0xff, 0x3a, 0xff, 0xff, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3c, 0x3d, 0xff, 0x3e, 0xff, 0xff, // ! $ * + - permitted The characters "#%&'(),. are stops
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0-9 permitted The characters :;<=>? are stops
|
||||
0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x01, 0x12, 0x13, 0x14, 0x15, 0x16, 0x00,
|
||||
0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0xff, 0xff, 0xff, 0xff, 0x3f, // A-Z and _ permitted, @ and [\]^ are stops
|
||||
0xff, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x01, 0x2d, 0x2e, 0x00,
|
||||
0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, //a-z the characters {|} ~` are stops, as is the mysterious control character 0x7F (del)
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // utf8 multibyte characters, all stops.
|
||||
};
|
||||
|
||||
// Table to convert ascii to six bit as a good old fashioned non owning naked pointer to const,
|
||||
// whose storage is owned by a const static which exists until the program terminates.
|
||||
static const uint8_t *ascii2six{ &ascii2six_ar[0] };
|
||||
// Compile time execution is C++ is a pain, because expressions are apt to unpredictably lose
|
||||
// their constexpr character for reasons that are far from clear.
|
||||
//
|
||||
// You can declare anything reasonable to be constexpr, and the compiler will not issue an
|
||||
// error message until the code that attempts to use what you have declared constexpr is
|
||||
// invoked from somewhere else "expression does not evaluate to constant"
|
||||
//
|
||||
// an assert in an expression evaluated at compile time does not trigger a run time error,
|
||||
// Instead the compiler reports that the expression did not evaluate to a constant,
|
||||
//
|
||||
// The error is confusing, because the error points to the declaration where the initialization
|
||||
// was invoked,instead of pointing to the assert.
|
||||
|
||||
// To debug code intended to be run at compile time, exercise it at run time with
|
||||
// auto ptr(std::make_unique<Class>());
|
||||
// at run time;
|
||||
|
||||
class charindex {
|
||||
public:
|
||||
std::array< uint8_t, 0x100> index{ 0, };
|
||||
// this non const array will become constexpr and be constructed at compile time
|
||||
// when an instance of this class is created in a constexpr expression.
|
||||
charindex() = delete;
|
||||
constexpr charindex(const uint8_t* p) {
|
||||
uint8_t pu{ 0 };
|
||||
do { index[pu++] = 0xFF; } while (pu);
|
||||
uint8_t i{ 0 };
|
||||
while (pu = static_cast<uint8_t>(p[i])) {
|
||||
index[pu] = i;
|
||||
i++;
|
||||
assert(i != 0); //prevents unending execution,
|
||||
// inside a constexp, generates an "expression does not evaluate to constant"
|
||||
// error at compile time, rather than breaking at run time.
|
||||
}
|
||||
index['o'] = index['O'] = 0;
|
||||
index['l'] = index['I'] = 1;
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr charindex ascii2six_ar(index2base64);
|
||||
|
||||
//
|
||||
//
|
||||
// You really have to write compile time code in templates as a language, which is the totally
|
||||
// obscure and hard to use language apt to generate remarkably voluminous error messages
|
||||
// will little obvious connection to the actual problem, and surprising result that are ver
|
||||
// difficult to predict in advance or understand at all.
|
||||
// In general, the better solution is to have a routine that is called once and only once at the
|
||||
// beginning of the program, which initializes a bunch of static const values, if that solution is
|
||||
// adequate, or to have a preproces routine written in python which generates the required C
|
||||
// files and header files.
|
||||
|
||||
// After this experiment in compile time code, I swear off it.
|
||||
// Table to convert ascii to six bit as a good old fashioned non owning naked pointer to const,
|
||||
// whose storage is owned by a const static which exists until the program terminates.
|
||||
const uint8_t* const ascii2six{ &ascii2six_ar.index[0] };
|
||||
|
||||
void ascii2test() {
|
||||
for (unsigned int i{ 0 }; i < 0x100;i++) {
|
||||
char v = i;
|
||||
unsigned int j = ascii2six[i];
|
||||
char w = index2base64[j];
|
||||
if (j < 64) {
|
||||
assert(v == w || v == 'I' || v == 'l' || v == 'o' || v == 'O');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Decode does not have an input span of encoded characters, but a char *, because it assumes
|
||||
// the string is always terminated by an invalid character, such as the trailing null at the end of
|
||||
|
2
stdafx.h
2
stdafx.h
@ -62,7 +62,7 @@ constexpr bool b_WINDOWS = false;
|
||||
static_assert(wxUSE_UNSAFE_WXSTRING_CONV == 1,
|
||||
R"(In fully utf environment, (wallet.manifest plus
|
||||
/utf-8 compile option) all string conversions are safe.)");
|
||||
static_assert(wxMAJOR_VERSION == 3 && wxMINOR_VERSION == 1 && wxRELEASE_NUMBER == 6 && wxSUBRELEASE_NUMBER == 0, "expecting wxWidgets 3.1.6");
|
||||
static_assert(wxMAJOR_VERSION == 3 && wxMINOR_VERSION == 1 && wxRELEASE_NUMBER == 7 && wxSUBRELEASE_NUMBER == 0, "expecting wxWidgets 3.1.7");
|
||||
static_assert(wxUSE_IPV6 == 1, "IP6 unavailable in wxWidgets");
|
||||
static_assert(WXWIN_COMPATIBILITY_3_0 == 0, "wxWidgets api out of date");
|
||||
static_assert(wxUSE_COMPILER_TLS == (b_WINDOWS ? 2 : 1), "out of date workarounds in wxWidgets for windows bugs");
|
||||
|
@ -21,6 +21,8 @@ Namespace testbed is only defined in this cpp file, hence nothing within
|
||||
If it needs to interact with the outside world, should post a message
|
||||
analogously to queue_error_message, which then calls back to a
|
||||
routine in this file.*/
|
||||
void ascii2test();
|
||||
extern const uint8_t* const ascii2six;
|
||||
|
||||
namespace testbed {
|
||||
using ristretto255::hash, ristretto255::hsh, ristretto255::scalar,
|
||||
@ -49,5 +51,6 @@ If using a dialog, exceptions within the dialog will result in an error message
|
||||
|
||||
void testbed() {
|
||||
// queue_error_message("hello world");
|
||||
ascii2test();
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ set -e
|
||||
set -x
|
||||
git submodule foreach --recursive 'git reset --hard'
|
||||
git submodule foreach --recursive 'git clean -xdf'
|
||||
git submodule update --init --recursive
|
||||
git submodule update --init --recursive --remote
|
||||
git config --local include.path ../.gitconfig
|
||||
set +e
|
||||
set +x
|
||||
|
Loading…
Reference in New Issue
Block a user