mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-24 11:11:02 -07:00
Compare commits
277 Commits
FluxEngine
...
firmware
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3601f9f487 | ||
|
|
7f95f6b43f | ||
|
|
b2d7ba1a65 | ||
|
|
b550bbbd08 | ||
|
|
4cbb75df60 | ||
|
|
7d8926659e | ||
|
|
37ca3f74c7 | ||
|
|
56cbf39d59 | ||
|
|
a783e7f500 | ||
|
|
2f4ac42684 | ||
|
|
ec689e100e | ||
|
|
6f0909d992 | ||
|
|
0092dec49e | ||
|
|
3447689c19 | ||
|
|
d4563fd842 | ||
|
|
d2ecec6009 | ||
|
|
26f26aec50 | ||
|
|
34dfc2767f | ||
|
|
bc3d3cabce | ||
|
|
23d80b93ae | ||
|
|
0d59d3d195 | ||
|
|
192427cf80 | ||
|
|
98e4094d70 | ||
|
|
e88b939866 | ||
|
|
aed5a02ee1 | ||
|
|
9f1e1bb2b6 | ||
|
|
15e9383d0b | ||
|
|
4ec056900c | ||
|
|
983feb59b0 | ||
|
|
8b2ce33f83 | ||
|
|
44b452b30b | ||
|
|
f60c9981b8 | ||
|
|
7c3df93580 | ||
|
|
601d7dfcf8 | ||
|
|
41cb53a550 | ||
|
|
87c13ae20c | ||
|
|
c30482af66 | ||
|
|
5f4f2f10d7 | ||
|
|
ae630a0e18 | ||
|
|
c66931cb12 | ||
|
|
fb2dbe25cd | ||
|
|
bf4831be9f | ||
|
|
0f83082cf0 | ||
|
|
fbfde604e7 | ||
|
|
5e2dfbed73 | ||
|
|
571602d3de | ||
|
|
85693f2577 | ||
|
|
60bc8ad888 | ||
|
|
9bf309eb5c | ||
|
|
eeddfa87b6 | ||
|
|
861fe2466c | ||
|
|
3a2cce78ca | ||
|
|
4e01f1de0d | ||
|
|
4f0a5e854c | ||
|
|
c669a9c808 | ||
|
|
e4d827256f | ||
|
|
1c1ad2725e | ||
|
|
d18e54c5a3 | ||
|
|
7a885e23d3 | ||
|
|
33dde3a465 | ||
|
|
8d4ac59f03 | ||
|
|
4fbfc492ce | ||
|
|
ac1fb71bc5 | ||
|
|
01d6b37b83 | ||
|
|
2284b4dce1 | ||
|
|
b92f80e6be | ||
|
|
bd5596fa30 | ||
|
|
4614b63c30 | ||
|
|
cf41b6cbb2 | ||
|
|
87f3e0e291 | ||
|
|
1997abcde6 | ||
|
|
8b761298ee | ||
|
|
df0356b841 | ||
|
|
dc158ebff4 | ||
|
|
f8192b90f4 | ||
|
|
5237049e2c | ||
|
|
9d70fb261e | ||
|
|
8370b8a743 | ||
|
|
25656d81a1 | ||
|
|
be97791428 | ||
|
|
18b683d22e | ||
|
|
34e9742f71 | ||
|
|
087eb7777e | ||
|
|
c469c5e3a1 | ||
|
|
485c29bb49 | ||
|
|
aa0cf150bd | ||
|
|
91c52e91cd | ||
|
|
a1f4014738 | ||
|
|
8a136ac4f6 | ||
|
|
ea43b3dc6a | ||
|
|
57fc787819 | ||
|
|
a0164b8de3 | ||
|
|
9df35c1814 | ||
|
|
9d2a5fee86 | ||
|
|
a6b2e932fa | ||
|
|
05aaa2634b | ||
|
|
2c98f5c542 | ||
|
|
d246fca9df | ||
|
|
c79feb405c | ||
|
|
b1145f8da3 | ||
|
|
3588d681a2 | ||
|
|
55d894ae1f | ||
|
|
0509caf432 | ||
|
|
5d1d807e78 | ||
|
|
22ba38b2e0 | ||
|
|
42f858267c | ||
|
|
5b1a3173f8 | ||
|
|
97822bd9a8 | ||
|
|
b926f5a692 | ||
|
|
191dfdf13f | ||
|
|
a100f1fe1e | ||
|
|
471ccf281c | ||
|
|
6c959be188 | ||
|
|
010887f18f | ||
|
|
e4b5e4c502 | ||
|
|
2de3b4f92e | ||
|
|
225a93330d | ||
|
|
41b36649a9 | ||
|
|
55c26ab1c4 | ||
|
|
8b1e60a1fd | ||
|
|
ed0f38748b | ||
|
|
7d75a720ca | ||
|
|
5a38db166f | ||
|
|
3c9fb79263 | ||
|
|
98d5a2dad9 | ||
|
|
4ab8b4984d | ||
|
|
f741ad058e | ||
|
|
2512a4fc32 | ||
|
|
5554d5e608 | ||
|
|
48d5ed2ff9 | ||
|
|
2632668d0e | ||
|
|
f46e444aa2 | ||
|
|
1149ad86a2 | ||
|
|
e1398d98b0 | ||
|
|
8133e2b7aa | ||
|
|
ebe678b18b | ||
|
|
509217606c | ||
|
|
6fb694669c | ||
|
|
5a63172a86 | ||
|
|
93dcc7e242 | ||
|
|
243eea33e9 | ||
|
|
38a8367f62 | ||
|
|
a02953cccc | ||
|
|
f13f96967e | ||
|
|
f7c31281e0 | ||
|
|
ac34a43d9b | ||
|
|
c8d0950979 | ||
|
|
a4ff59eccb | ||
|
|
c3a50f9442 | ||
|
|
57e81ee72e | ||
|
|
05df0a37b1 | ||
|
|
25f2c3a8c1 | ||
|
|
c3aa12db78 | ||
|
|
a3bd7cc644 | ||
|
|
5a186b6960 | ||
|
|
639588fa68 | ||
|
|
f9510c54b2 | ||
|
|
3a8ddf8025 | ||
| a2801ea88c | |||
|
|
c2aae7ee18 | ||
|
|
9d0804eff4 | ||
|
|
6ff84b3693 | ||
|
|
b641e0282b | ||
|
|
37a467cabc | ||
|
|
e01a7110ac | ||
|
|
5dad5de548 | ||
|
|
295325a20b | ||
|
|
df0a9bac96 | ||
|
|
cf9cef6f87 | ||
|
|
f92814b24b | ||
|
|
331b59cd1e | ||
|
|
ed6d211aff | ||
|
|
a8f1469d36 | ||
|
|
74cb332706 | ||
|
|
89165369b1 | ||
|
|
a54e3d33a6 | ||
|
|
0f17984f41 | ||
|
|
6527ceb913 | ||
|
|
64a57ba837 | ||
|
|
74da9330f8 | ||
|
|
4fa1dd6860 | ||
|
|
e55effc9ca | ||
|
|
924b862f7c | ||
|
|
5f077762d5 | ||
|
|
1b0ec50711 | ||
|
|
22f320f1c4 | ||
|
|
9949476584 | ||
|
|
1b5b170557 | ||
|
|
925a3a4bdb | ||
|
|
720fe9f95f | ||
|
|
7c4f8e1443 | ||
|
|
79d24dff46 | ||
|
|
928435a31d | ||
|
|
26ac92eaa3 | ||
|
|
2974c08b08 | ||
|
|
5a7b0b3050 | ||
|
|
cc2d9bbdd1 | ||
|
|
e912152784 | ||
|
|
d00681f623 | ||
|
|
52942c3d2a | ||
|
|
dedabdd8d8 | ||
|
|
3061499860 | ||
|
|
20f18755ed | ||
|
|
333f2aba54 | ||
|
|
1cb673ed80 | ||
|
|
57e0bc784a | ||
|
|
425afa93da | ||
|
|
259b2cebc7 | ||
|
|
06589826c8 | ||
|
|
2245cd982a | ||
|
|
065b50769f | ||
|
|
d1e99852bc | ||
|
|
bf8f6ae687 | ||
|
|
4ad6805ea1 | ||
|
|
4f4e3f0b89 | ||
|
|
b51f2c1ec8 | ||
|
|
1bec06fd75 | ||
|
|
451d2e2d1d | ||
|
|
9cee12f9f4 | ||
|
|
f5d6011a77 | ||
|
|
64b2ff19ea | ||
|
|
9c17a64773 | ||
|
|
69c877ff66 | ||
|
|
ac557ffedc | ||
|
|
b1e41bc583 | ||
|
|
a144395ec9 | ||
|
|
0cf9d05489 | ||
|
|
0e6c0a41d0 | ||
|
|
8a83652d08 | ||
|
|
91ee72a8d6 | ||
|
|
91b1c8c13c | ||
|
|
26effeabe6 | ||
|
|
611c9740ed | ||
|
|
2a048c3228 | ||
|
|
f4fd83d999 | ||
|
|
cf68585808 | ||
|
|
9f9e926cff | ||
|
|
9dc0dd75fd | ||
|
|
9f285710f8 | ||
|
|
ee1c448327 | ||
|
|
e85bf1713e | ||
|
|
7341c71277 | ||
|
|
d579863311 | ||
|
|
c79cfc19aa | ||
|
|
997a6be267 | ||
|
|
762bb3006d | ||
|
|
07f2bd8cab | ||
|
|
daf83db9b3 | ||
|
|
55c6e19af4 | ||
|
|
9cadc94c5a | ||
|
|
cacdf9ef56 | ||
|
|
a3042fc6c0 | ||
|
|
3efd492525 | ||
|
|
55a5cbc356 | ||
|
|
2887b024ab | ||
|
|
917303edb9 | ||
|
|
c712c15a30 | ||
|
|
0c541db8e0 | ||
|
|
603b1520d7 | ||
|
|
c7eb8ad5c8 | ||
|
|
0b285aa7f4 | ||
|
|
e8665bd00c | ||
|
|
fb4eaa4332 | ||
|
|
874a9eae76 | ||
|
|
8230520956 | ||
|
|
66da9675f1 | ||
|
|
61ff48c005 | ||
|
|
5fc8a1e52a | ||
|
|
df1ac74069 | ||
|
|
91f718bf38 | ||
|
|
46e987e393 | ||
|
|
a59b4f7be7 | ||
|
|
ca66e3c35c | ||
|
|
31e2ad8cba | ||
|
|
320f32895a | ||
|
|
d4db131d3c | ||
|
|
27c2c9045e |
@@ -1,42 +0,0 @@
|
||||
version: '{branch}.{build}'
|
||||
clone_depth: 1
|
||||
skip_tags: true
|
||||
image: Visual Studio 2019
|
||||
|
||||
environment:
|
||||
MSYSTEM: MINGW32
|
||||
|
||||
init:
|
||||
- git config --global core.autocrlf input
|
||||
|
||||
install:
|
||||
- set PATH=c:\msys64\mingw32\bin;c:\msys64\usr\bin;c:\msys64\bin;%PATH%
|
||||
- echo %PATH%
|
||||
- pacman -S --noconfirm --needed make ninja mingw-w64-i686-libusb mingw-w64-i686-sqlite3 mingw-w64-i686-zlib mingw-w64-i686-gcc zip
|
||||
|
||||
build_script:
|
||||
- make
|
||||
- zip -9 fluxengine.zip fluxengine.exe brother120tool.exe brother240tool.exe FluxEngine.cydsn/CortexM3/ARM_GCC_541/Release/FluxEngine.hex
|
||||
|
||||
artifacts:
|
||||
- path: fluxengine.zip
|
||||
name: fluxengine.zip
|
||||
|
||||
deploy:
|
||||
release: FluxEngine Windows client version $(APPVEYOR_BUILD_NUMBER)
|
||||
description: >
|
||||
This is an automatically built version of the FluxEngine Windows client
|
||||
which is generated whenever a significant checkin has happened. It's had
|
||||
no testing whatsoever.
|
||||
|
||||
To use, download it, put it somewhere, and then run it from a cmd window
|
||||
or other command line shell.
|
||||
provider: GitHub
|
||||
auth_token:
|
||||
secure: dfJjj7fWCoDUz+Ni11OcNPB/U3TNJFwNA2AsL++ChFjniUsZLlC6SDWHiL/t4FZo
|
||||
artifact: fluxengine.zip
|
||||
draft: false
|
||||
prerelease: false
|
||||
on:
|
||||
branch: master
|
||||
|
||||
45
.github/workflows/ccpp.yml
vendored
45
.github/workflows/ccpp.yml
vendored
@@ -10,32 +10,45 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: apt
|
||||
run: sudo apt update && sudo apt install libusb-1.0-0-dev libsqlite3-dev ninja-build
|
||||
run: sudo apt update && sudo apt install libusb-1.0-0-dev libsqlite3-dev ninja-build protobuf-compiler
|
||||
- name: make
|
||||
run: make
|
||||
|
||||
build-macos:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: brew
|
||||
run: brew install sqlite pkg-config libusb ninja
|
||||
run: brew install sqlite pkg-config libusb ninja protobuf
|
||||
- name: make
|
||||
run: make
|
||||
|
||||
# build-windows:
|
||||
# runs-on: windows-latest
|
||||
# steps:
|
||||
# - uses: numworks/setup-msys2@v1
|
||||
# with:
|
||||
# path-type: inherit
|
||||
# - uses: actions/checkout@v1
|
||||
# - name: pacman
|
||||
# run: |
|
||||
# msys2do pacman -S --noconfirm --needed make ninja mingw-w64-i686-libusb mingw-w64-i686-sqlite3 mingw-w64-i686-zlib mingw-w64-i686-gcc zip
|
||||
# - name: build
|
||||
# run: |
|
||||
# msys2do make
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
update: true
|
||||
msystem: MINGW32
|
||||
install: >-
|
||||
make
|
||||
ninja
|
||||
mingw-w64-i686-libusb
|
||||
mingw-w64-i686-sqlite3
|
||||
mingw-w64-i686-zlib
|
||||
mingw-w64-i686-gcc
|
||||
zip
|
||||
mingw-w64-i686-protobuf
|
||||
vim
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: build
|
||||
run: |
|
||||
make
|
||||
|
||||
|
||||
63
.github/workflows/release.yml
vendored
Normal file
63
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
name: Autorelease
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
|
||||
jobs:
|
||||
dev-release:
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
update: true
|
||||
msystem: MINGW32
|
||||
install: >-
|
||||
make
|
||||
ninja
|
||||
mingw-w64-i686-libusb
|
||||
mingw-w64-i686-sqlite3
|
||||
mingw-w64-i686-zlib
|
||||
mingw-w64-i686-gcc
|
||||
zip
|
||||
mingw-w64-i686-protobuf
|
||||
vim
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: build
|
||||
run: |
|
||||
make
|
||||
- name: zip
|
||||
run: |
|
||||
zip -9 fluxengine.zip fluxengine.exe brother120tool.exe brother240tool.exe FluxEngine.cydsn/CortexM3/ARM_GCC_541/Release/FluxEngine.hex
|
||||
- name: date
|
||||
run: |
|
||||
echo "RELEASE_DATE=$(date --rfc-3339=date)" >> ${GITHUB_ENV}
|
||||
- name: tag
|
||||
uses: EndBug/latest-tag@latest
|
||||
with:
|
||||
tag-name: dev
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: delete-old-assets
|
||||
uses: mknejp/delete-release-assets@v1
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
tag: dev
|
||||
assets: |
|
||||
fluxengine.zip
|
||||
fail-if-no-assets: false
|
||||
- name: release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: Development build ${{ env.RELEASE_DATE }}
|
||||
files: |
|
||||
fluxengine.zip
|
||||
tag_name: dev
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,246 +1,246 @@
|
||||
:4000000000800020110000003110000031100000064A08B5136843F020031360044B1A6803F53F5302331A6001F020F8E8460040FA46004010B5054C237833B9044B13B18B
|
||||
:400040000448AFF300800123237010BD6881FF1F00000000B8380000084B10B51BB108490848AFF300800848036803B910BD074B002BFBD0BDE81040184700BF0000000051
|
||||
:400080006C81FF1FB8380000C880FF1F000000000A4A0B4B116801310B40002BBEBF03F1FF3363F03F030133136011685368994202BF024B01221A72704700BF8881FF1FCC
|
||||
:4000C0003F0000800A4A0B4B516801310B40002BBEBF03F1FF3363F03F030133536051681368994202BF024B01221A72704700BF8881FF1F3F0000800E4BDA681AB901215F
|
||||
:4001000019745A7410E05A7C1A741A7C0AB1002207E059699A69D8688A1A82428CBF002201225A745A699A611B7C13B1002002F043B970478881FF1F10B5C4B2204601F054
|
||||
:4001400057F90128FAD110BD08B572B60F4B0F495A6901325A61DA690132C82A08BF0022DA611A6AD8690132A72A08BF00220A621B6A002B0CBF02230023002814BF184660
|
||||
:4001800043F0010002F080FE62B608BD8881FF1F38B50446C5B2284602F0B0F8062002F0CDFA44F00200C0B202F0A8F8062002F0C5FA284602F0A2F8BDE83840062002F0C2
|
||||
:4001C000A7BA10B5642402F093F828B9FFF7E0FF013CF8D1204610BD012010BD70B5C4B2054620460E4601F003F9012805D0204601F01CFA2846FFF79FFF204601F000F9AD
|
||||
:40020000314605460246204601F0BCF9204601F0EFF80028FAD1284670BD000038B5044D0024285D013402F039FA402CF9D138BDAC81FF1F08B502F053FC002002F05CFCBD
|
||||
:4002400002F06EFC02F078FC80B208BD10B50446012002F06BF8642002F05AFAFFF7EAFF2080002002F062F8642002F051FAFFF7E1FF608010BD08B502F05EFD002002F02B
|
||||
:4002800067FD02F079FD02F083FD80B208BD10B50446FFF796FF322002F03AFAFFF7EBFF20800120FFF774FF322002F031FAFFF7E2FF608010BD0FB400B593B014AB53F835
|
||||
:4002C000042B402102A8019302F0DEFE02A802F07AF802F084F813B05DF804EB04B0704710B5044601780648FFF7E5FF0420FFF723FF62782146BDE81040042001F0D0B8B5
|
||||
:40030000CC38000007B50023ADF804308DF80600032301A88DF80530FFF7E2FF03B05DF804FB000010B5074C94F8643043B1002001F0D8FF002002F06BFD002384F864304E
|
||||
:4003400010BD00BF8881FF1F38B5104D837895F8672004469A4204D0FFF7E4FF002385F86A302368C5F865302279094B1A71A378002B14BF0220012002F04AFDE07802F02E
|
||||
:4003800041FD2079BDE8384002F078BD8881FF1FED81FF1F38B50D4C94F8645065B904F16500FFF7D1FF012001F09CFF4FF47A7002F0AEF984F86A506369E366012384F84D
|
||||
:4003C0006430BDE8384002F0E1B900BF8881FF1FF8B5214C0546FFF7DDFF94F86A3003B15DB91E48FFF767FFFFF7EBFE0120002384F86A00236702F0A1F92A46216F184872
|
||||
:40040000FFF759FF144E0027236F9D4216D001F06FFF00B13767236F9D4205DD0120FFF7B7FE336F013305E005DA0020FFF7B0FE336F013B336702F0A9F9E5E7322002F047
|
||||
:4004400067F92A2DCCBF0020012002F023FDBDE8F8400448FFF72FBF8881FF1FD9380000E0380000FD3800002DE9F04F99B062B602F0F6F99D49042002F01AFA9C4801F0D9
|
||||
:4004800043FF9C4802F0E6FC9B4801F077FF02F0C7FB02F099FA002002F0BAFC01F092FF0221002000F05AFF944C012001F0D2F8002384F86730FFF76DFFFFF782FE84F8A3
|
||||
:4004C0007400FFF72FFF012384F86730FFF762FFFFF777FE84F87500FFF724FF884B94F87400884994F875202546002A14BF0A461A46002808BF19468348FFF7DCFE032177
|
||||
:40050000084602F023F9264602F040F994F8643043B1EA6E6B699B1A41F28832934201D9FFF700FF00F052FF18B97848FFF7C3FE04E000F051FF0028F7D10BE000F046FF85
|
||||
:4005400010B902F023F9F9E77148FFF7B4FE032001F06CF8032000F04BFF0128D4D16D48FFF7F2FE6C490320FFF738FE94F876106A48FFF7A0FE94F87630023B142B00F229
|
||||
:40058000D483DFE813F01500D2031E00D2032400D2034F00D2037500D203D700D203BF01D2030603D2032A03D2033103D2034B0303238DF820308DF821300F238DF8223084
|
||||
:4005C00028E394F87800FFF703FF554B1FE3FFF7E1FE002323746069227C02F0FF0132B96B691B1AB3F57A7FF6DD0B4611E083B10022174696F878107069277494F810E007
|
||||
:40060000BEF1000F02D16B691B1AF7E701329142F3DA07228DF8202004228DF82120ADF82230F7E20220FFF787FD4FF000080DF1200A02F0ABF84FF480790027C9EB080303
|
||||
:40064000DA1907F80A200137402FF9D10220FFF773FD3A465146022000F022FFB9F10109EBD108F10108B8F1400FE2D12D4B38E04FF0010A4FF000080DF1200B02F086F844
|
||||
:400680004FF0000959460120FFF7A8FD08EB090300270493049B1BF807203B44DBB29A4209D08DE80C0041463B464A461E48FFF702FE4FF0000A0137402FEBD109F101091B
|
||||
:4006C000B9F5807FDED108F10108B8F1400FD5D151461648FFF7EFFDBAF1000F00F01A81134B1B8807A8ADF81C3094E249010000F900000091000000C50000008881FF1F0B
|
||||
:400700000F3900000B390000123900002A3900003D390000ED81FF1FFE81FF1F47390000BC380000BE3800005639000072390000C0380000206FFFF74BFE94F8780001F081
|
||||
:40074000F5FD94F8780001F0D9FD02F009FCB94BDFF8FC821A78002702F0FB021A701A7842F001021A701A7802F0FE021A701A7802F0FE021A7002F0F7FB0220FFF7DCFCF9
|
||||
:40078000012141F6FF734FF48042084602F046FB84F8B60001F068FF08F807000137402FF8D1DFF8B0A200270AF195091FFA89F80137402F14BF3A4600221AF8010F2244C0
|
||||
:4007C000062392F82420402101F082FF424646F24E419AF8000001F08DFF08F14008402F1FFA88F8E4D196F8793053B196F87C30F36000233374237C002BFCD000233374E1
|
||||
:40080000F36000234FF0FF32236062602372236894F8B600234493F8241001F0DDFE94F8B60001F09BFE012194F8B60001F06EFE2368002BFCD0002398467360D6F814A0D4
|
||||
:40084000012701F0A3FF6369B4F87A20CAEB030393420DD367B1042195F8B60001F0C8FE94F8B60001F0D4FE0028F9D107463072237AFBB96A682B689A4202D1002FE0D1D9
|
||||
:4008800018E00220FFF758FC6968402209EB8111022000F005FE6A68674B01321340002BBEBF03F1FF3363F03F03013308F101086360C6E70220277AFFF73EFC0022114687
|
||||
:4008C000022000F0EDFD0220FFF736FCFFB2FFF7A5FC002001F012FD37B15848FFF7EBFC0220FFF70FFD06E0554B08A81B88ADF82030FFF7F5FC227C4146237A5148FFF7BB
|
||||
:40090000DAFC15E25048FFF7D6FCD4F87A7017F03F0701D0032009E2286FFFF759FD95F8780001F003FD95F8780001F0E7FC012001F002FD02F014FB444BDFF814811A7857
|
||||
:4009400042F004021A701A7842F001021A701A7802F0FE021A701A7802F0FE021A7002F003FB01214FF4804341F6FF72084601F0E9FC85F8B60001F077FE08F8070001378C
|
||||
:40098000402FF8D1DFF8CC90002709F195031FFA83F804930137402F14BF3A46002219F8010F2244052392F82420402101F090FE414646F24B5299F8000001F09BFE08F1FF
|
||||
:4009C0004008402F1FFA88F8E4D100274FF0FF33376098467360BB463B46D6F87A9037725FEA99190CBF4FF0010A4FF0000A2168114A01310A40002ABCBF02F1FF3262F03B
|
||||
:400A00003F026068B8BF013282426FD02BB1227A002A7AD12A7C002A77D12068049A059302EB8010BAF1000F16D040223F2102F0F7FA1CE09E6400403F0000807C390000C9
|
||||
:400A4000C238000096390000A93900009B650040AC81FF1FAB81FF1F014601370120FFF7BDFBC7EB0903D3F1000A4AEB030A2168B34A01310A40002ABEBF02F1FF3262F0BB
|
||||
:400A80003F02013222606268059B01322ED12A683F2A2BD14FF00008C5F8048001F080FC85F808806B6895F8B6002B4493F8241001F092FD95F8B60001F050FD012195F8BF
|
||||
:400AC000B60001F023FD95F87E30EB6085F81080237C002BFCD04FF00008012086F8108001F06AFC404601F027FC00E023B1237A5BB92B7C4BB90123626842453FF477AFC1
|
||||
:400B00000BF1010BD5F8048071E701F04FFC012001F012FC002001F04FFC042194F8B60001F066FD94F8B60001F072FD80460028F8D196F8B60001F0FFFC337C327A029318
|
||||
:400B4000012303920193CDF800A05B463A4649467C48FFF7B0FBC6F80C80BAF1000F0BD0FFF75CFB002001F0C9FB237A63B17648FFF7A1FB0220D9E0B945F1D07349012035
|
||||
:400B8000FFF72CFB0137F7E77148FFF794FB714B3DE094F8780001F0C9FB206FFFF718FC6D48FFF788FB94F87930E36000232374237C002BFCD0012001F0FEFB00233374CE
|
||||
:400BC000237C002BFCD0002001F0F6FB00236348F360FFF770FB624B19E0002084F86A00FFF7F6FB5F4B12E094F8743023B195F875200AB985F8782094F875201AB113B9F6
|
||||
:400C0000012385F878305848FFF79EFB574B1B88ADF8203008A8FFF763FB89E0FFF782FB02F07CF8002002F01FF82A2701F04AFF002001F0EDFE3A46002108A802F0F0F9E0
|
||||
:400C400017238DF820308DF8217001F09FFD002001F048FB002002F0DBF8C82001F058FD0DF12200FFF7F2FA0DF13600FFF70FFB01F08CFD012002F0CBF8322001F048FD4D
|
||||
:400C80000DF12600FFF7E2FA0DF13A00FFF7FFFA012001F027FB4FF4967001F039FD01F075FD0DF12E00FFF7D1FA0DF14200FFF7EEFA002001F016FB4FF4967001F028FD84
|
||||
:400CC00001F064FD022002F0A3F8322001F020FD0DEB0700FFF7BAFA0DF13E00FFF7D7FA012001F0FFFA4FF4967001F011FD01F04DFD0DF13200FFF7A9FA0DF14600FFF756
|
||||
:400D0000C6FA002001F0EEFA4FF4967001F000FD01F03CFD002002F07BF8002384F86A3001F07EFF01F050FE74E70120FFF7EAFA032000F07BFC0E48FFF7BDFAFFF7E4BBB6
|
||||
:400D40003F000080B3390000E33900004092FF1FED390000C4380000F5390000033A0000C6380000C8380000FE81FF1FCA380000103A00002DE9F04172B6884B61221A70F9
|
||||
:400D8000A3F5F06301221A801924854A9C7092E803008033062283F8002283E80300522203F580731A707F4B7F4A1B787F4EDBB2137040F618027E4B00251A8041F25122A6
|
||||
:400DC00023F8022C33784FF4F07003F0010343EA450502F0BDF8013C05F003052ED0032DF0D1744B4FF480721A8007221A70724A002548211570917002221D705D7103F893
|
||||
:400E0000032C0422DA716D4A6D4C13786D4E43F00103137012F8013C062743F0030302F8013C2378012243F0800323705B4B1A70654A137843F02003137000E0FEE707FBAD
|
||||
:400E4000056300219A881868013502F0E9F8072DF5D15E485E4E002550F8041F05F1105303F1480221F0FF074933C9B20B4452005B0002329A4206D012F802EC12F801CC0C
|
||||
:400E80000EF807C0F5E7B0420D44E5D1514A002313609360136193614F4B504F1A68504BDFF888811A604F4B1A684F4B1A604F4A137843F002031370137C43F002031374F7
|
||||
:400EC0002378A2F5863243F040032370413A137843F010031370464A464B07CA03C31A80454A2833106843F8250C127903F8212C424A07CA03C31A80414AE83B07CA03C33B
|
||||
:400F00001A80404A083307CA03C31A803E4A3F4BA2F5616203CBC2F8100EC2F8141E1378042043F008031370394B02F5AA521B783D78DBB298F80060EDB203F007010C329F
|
||||
:400F40001B091170F6B2537045F003033B7046F0030388F800302F4B48221A702E4A402313702E49937013729372082382F81F3220220A7048710A72294A0A20137001F0C7
|
||||
:400F8000DDFB284B88F8006044223D70264D1A7094E80F0007C52B80BDE8F081004800405C0900480F010049A146004025420040224200400440004006400040A2430040AF
|
||||
:400FC000A0430040153A0000E8460040FCFFFF478C0000480076004064090048F8460040207600406809004828760040035001401C090048C051004028090048300900485A
|
||||
:401000003C090048480900483251004054090048CF0100491D51004001590040235B0040585B004076580040B0430040F946004008B501F0C9FF03680C2B00D1FEE7FEE79D
|
||||
:40104000084908B50B68084A1844821A802A01DC086005E001F0B8FF0C2303604FF0FF33184608BDCC80FF1F9093FF1F80B51148114B0025C0B1A3F1100192C92246043933
|
||||
:40108000161BB74204D051F8046F42F8046BF7E7114653F8046C8C1AA64202D041F8045BF9E701381033E5E701F094FFFFF7DCF9FEE700BF01000000E43B0000124A134BF0
|
||||
:4010C00010B51A60124A134C1368134843F4007313600023032B98BF54F823204FEA830188BF0E4A0133302B4250F3D10C4B1A780C4B1A700C4B084A1A60FFF73BFEBDE8CA
|
||||
:40110000104001F0EDB900BF0004FA050CED00E014ED00E0000000000080FF1F31100000BC760040C080FF1F08ED00E0F8B501F017FF4B4A01271378022643F001031370EA
|
||||
:40114000137C484C43F001031374474B02F5E3521F700B3203F8946C1378054603F07F031370002001F0EAFA2378404A03F0F90323701378384603F0DF03137023783B4325
|
||||
:40118000237001F0DBFA282001F0D8FA384B30461A7802F07F021A701A7802F0BF021A7023783343237001F0C9FA2378314A43F0040323700023137053702F4AFF2199544A
|
||||
:4011C0000133092BFBD1284601F0CEFE0721172001F0FCFA2949172001F0EAFA0721182001F0F4FA2649182001F0E2FA0721152001F0ECFA2349152001F0DAFA0721052032
|
||||
:4012000001F0E4FA2049052001F0D2FA0721062001F0DCFA1D49062001F0CAFA0721084601F0D4FA1A49072001F0C2FA0721082001F0CCFA1749082001F0BAFA0021162047
|
||||
:4012400001F0C4FA1449162001F0B2FA07210C2001F0BCFABDE8F84010490C2001F0A8BAA5430040944300409D60004012600040F851004084600040B592FF1FFB1A00008A
|
||||
:4012800035190000F91A00002D1A0000591A0000891A0000C11A0000011B0000751B0000214B224A10B5187000231370204A40201370204A0F2413701F4A13701F4A1370D9
|
||||
:4012C0001F4A13701F4A13701F4B4FF400021A604FF080721A604FF400121A6020221A601860802018604FF480701860174804704FF480001860164B1A70933B19B91A7851
|
||||
:4013000002F0FE0202E01A7842F001021A70114B03221A70802203F8202C012001F018FE0D4B04221A7010BDD092FF1FD692FF1FD492FF1FD592FF1FD192FF1FC092FF1F97
|
||||
:40134000D392FF1F4893FF1F00E100E09E6000409C600040286000401260004070B5074C054623780E461BB9FFF7E0FE0123237031462846BDE87040FFF792BF8092FF1F7A
|
||||
:401380000A4A002313700A4A13700A4A13700A4A13700A4A13700A4A13700A4A13700A4B03221A70802203F8202C7047D692FF1FD492FF1FD592FF1FD192FF1FC092FF1F05
|
||||
:4013C000D392FF1F4893FF1F28600040014B1878704700BFD592FF1F044B1A7802F0FF001AB118780022C0B21A707047D492FF1F024A0C2303FB002040787047DC92FF1FB8
|
||||
:40140000431E072B0CD8074A064B00010344805C5B7800F00F0043EA0020023880B2704700207047FC5F00401A4A38B50C2303FB00231B79090C13F0800F00F1FF35044670
|
||||
:4014400019BF8AB24FF480438BB24FF48042032D18D8DFE805F002070C110021084601F01BF80DE00021084600F0FAFF08E00021084600F0D9FF03E00021084600F0B8FF3E
|
||||
:40148000054B1855EDB2072D03D801F0EDF8034B185538BDDC92FF1FAC92FF1FB592FF1F431E072B2DE9F0470446894615465CD82F4F0C2202FB0072D388DFF8B8A09BB274
|
||||
:4014C000C3F500739D424FF00C0303FB007388BFD588DB7884BFC5F50075ADB2254A43EA15230601B354B244EBB28AF80130224B1A5C9846FF2A01D1FFF796FF0C2303FBBF
|
||||
:40150000047200215170B9F1000F28D03DB31B4F385D01F011F811232946FE2218F8040001F0D6F806F5C04278321FFA89F118F8040001F0DFF8124D18F80410385D01F004
|
||||
:401540004BF80121385D00F0E1FF735D43F002037355735D03F0FD037355BDE8F08703FB04746379DBB28AF80230BDE8F08700BFDC92FF1FFC5F0040B592FF1FAC92FF1FD4
|
||||
:40158000706000402DE9F047044615468846002940D0431E072B3FD8FFF732FFA84203D22046FFF72DFF05461D4E335DFF2B03D141462046FFF738FFDFF868A027011AF893
|
||||
:4015C000040000F0B9FF1223FE222946305D01F07FF807F5C0411FFA88F27831305D01F089F8DFF84490315D1AF8040000F0F4FF01211AF8040000F089FF17F8093043F0F1
|
||||
:40160000020307F8093017F8093003F0FD0307F8093002E00D4600E000252846BDE8F087B592FF1FAC92FF1F70600040431E072B0AD8064A0C2303FB002300225A705A7991
|
||||
:40164000034BD2B200011A54704700BFDC92FF1FFE5F0040431E072B9FBF024B000108221A547047FE5F004030B51A4A1A491B4D0878138803449BB21380194A00231488E7
|
||||
:40168000D8B2A4B27CB1082B0CD050680078C0B2E85450680133013050601088013880B21080ECE718460B780E4C082B0E4A00D040B10E4D2B7883F080032B700F23237022
|
||||
:4016C000022301E0022323701370094B1870087030BD00BF4C93FF1F4893FF1F00600040C492FF1FC192FF1FD692FF1FD292FF1F4993FF1F074B02221A70074B80221A70AE
|
||||
:40170000064B0F221A70064A00231370054A012013707047D692FF1FD292FF1FC192FF1F4893FF1F4993FF1F30B5164B16491B780A8803F00F03023BDBB21A4492B20A80CC
|
||||
:40174000124C134A0020118889B279B173B15568215C013BC9B229705168DBB20131516011880130013989B21180ECE7094A1370094A137883F080031370084B0B221A70DF
|
||||
:4017800030BD00BF296000404C93FF1F00600040C492FF1F4993FF1FD292FF1FC192FF1F064A06231370064A01201370054B80221A70054B00221A70704700BFD692FF1F52
|
||||
:4017C000C192FF1FD292FF1F4993FF1F054B9A683AB19A68044910709A680988518000229A607047C492FF1F4C93FF1F08B5124B1A78D2B21A701B78DBB21A0602D50F4A1E
|
||||
:40180000137008BD0220FFF7E1FF0D4B1B7803F06003202B05D0402B06D043B900F012FC04E001F0A5FB01E000F046FD10B9034B03221A7008BD00BF28600040C192FF1FC0
|
||||
:401840000060004008B5084A084B0120197813880B449BB21380064B00221A70FFF7B6FF044B03221A7008BD4C93FF1F4893FF1FD692FF1FC192FF1F08B50C4B1B78DBB25E
|
||||
:40188000042B07D0062B09D0022B0DD1BDE80840FFF7D8BFBDE80840FFF746BF0320FFF795FF034B03221A7008BD00BFD692FF1FC192FF1F08B5054B002201201A70FFF7B6
|
||||
:4018C00085FF034B03221A7008BD00BFD692FF1FC192FF1F08B50A4B1A7832B11A78094942F080020A7000221A70074B002201201A70FFF76BFF054B03221A7008BD00BFA5
|
||||
:40190000C092FF1F08600040D692FF1FC192FF1F074B1B78DBB2042B05D0062B05D0022B05D1FFF7A1BEFFF7C5BFFFF7D3BF7047D692FF1F38B51D4C2378DBB2DD0634D51B
|
||||
:4019400018060AD503F00F03012B2ED1FFF74EFF174B1B78190609D538BD5A0602D5FFF7D7FF03E09D0620D5FFF786FF23781B061BD4104B1A78104B1B7813430F4A13705F
|
||||
:401980001278934211D10A4A0849154613782078DBB2000605D41378DBB20B700B7803F00F0328788342F1D138BD38BD28600040C192FF1FD292FF1F4993FF1F29600040AD
|
||||
:4019C000054A00231380054A916819B191680B7092685380704700BF4C93FF1FC492FF1F0E4808B503889BB213B9FFF783FE13E00B4B02221A700B4B00221A70FFF7E0FFAC
|
||||
:401A0000094AD1799379028843EA012392B2934238BF0380FFF728FE012008BDC492FF1FD692FF1FD292FF1F00600040084B01221A700F3B9B7C074B1A7B02F00302012A07
|
||||
:401A40001EBFDA7B82F08002DA7301225A7370470B600040DC92FF1F094B02221A700F3B93F82230074B1A7E02F00302012A1EBFDA7E82F08002DA7601225A76704700BFFE
|
||||
:401A80000B600040DC92FF1F0B4B04221A700F3B93F83230094B93F8242002F00302012A1EBF93F8272082F0800283F82720012283F82520704700BF0B600040DC92FF1F78
|
||||
:401AC0000B4B08221A700F3B93F84230094B93F8302002F00302012A1EBF93F8332082F0800283F83320012283F83120704700BF0B600040DC92FF1F7047FFF741BC000081
|
||||
:401B0000F0B5184B184E19780C27C9B201234FF0000C31B3CA0720D5144A4FEA031E7244947850782040C5070DD507FB03652C79240608D5147804F0FE0414706D790C4C35
|
||||
:401B4000EDB204F80E50840706D507FB036425792D0658BF84F801C090700133DBB24908D7E7F0BD9F600040DC92FF1F70600040FE5F004000F0ACBC70B50446184B88B021
|
||||
:401B800003AA03F11006154618685968083303C5B3422A46F7D11B782B70FCB12223237001AD03232846637000F08AFE002220461146AB5C08AC04EB131414F8144C03F053
|
||||
:401BC0000F03847008AC234413F8143C0132082AC1700371417100F10400EAD108B070BD3F3A00002DE9F0431C4D01222E460C201F274FF0800E4FF0080C194B00FB02580B
|
||||
:401C00001401234418705F70164998F805902144B9F1000F07D098F8044024064CBF887081F802C001E081F802E000FB0261CC880132E4B29C71CC88092AC4F30724DC71A2
|
||||
:401C4000CC88E4B21C71C988C1F307215971D4D1054BFF221A70BDE8F08300BFDC92FF1F70600040FC5F00400A600040064B074A1B7802EBC30253681A7C824286BF03EB6F
|
||||
:401C8000C003586900207047D092FF1FA03A00002DE9F84F424B1A78002A7ED01878414D0138C0B2FFF7E2FFA8463F4AC3681478007ADFF800C1E4B203EBC0000C260027FE
|
||||
:401CC0004FF0010E834268D01A78A24263D11CF80420597891425ED19A7893F8039002F07F0206FB02FA05EB0A01CF7093F802B009F0030981F804B093F803B005F80AB0A6
|
||||
:401D0000B3F804A0A1F808A093F902A0BAF1000F0BDAB9F1010F0CBF4FF007094FF00D0981F8059081F801E009E0B9F1010F0CBF4FF005094FF0090981F805904F704FEAA3
|
||||
:401D400002191A4906FB0282494481F802E0B2F808A0CAF3072A81F800A0B2F808A05FFA8AFA81F801A0B2F806A011495FFA8AFA494481F806A0B2F80690C9F3072981F8FE
|
||||
:401D80000790B2F806905FFA89F981F80490D288C2F307224A71083394E7BDE8F88F00BFD592FF1FDC92FF1FD192FF1FFC5F004070600040C292FF1F08B5064B187801384A
|
||||
:401DC000C0B2FFF753FF20B143681B7900EBC300406908BDD592FF1F00212DE9F84F0B464E4E0C2707FB01F401313219092933554FF000059370494CD37013819372537031
|
||||
:401E00005371EFD118B1464B1D70464B1D70464B1A78002A7FD0187801250138C0B2FFF725FFA8464368DFF8F8E0DB790C2713F0400F3E4B4FF0000C1A7814BF42F0010273
|
||||
:401E400002F0FE021A70027AD20007FB0541C36803EB02094B4531D093F802A00AF07F06AE4229D10E89B3F804B0B6B25E4538BFA1F808B01E7893F801B01EF80660B34576
|
||||
:401E80001AD181F804A0DE780E7093F902A0DE78BAF1000F06F0030607DA012E0CBF07260D264E7181F8018006E0012E0CBF052609264E7181F801C00833CBE70135092D89
|
||||
:401EC000C3D1C1680A328B1C0A440C200833934209D013F8081C13F80A5C01F07F0100FB01418D72F2E7FFF767FF114B0121186000230C2000FB0142D38012890131134463
|
||||
:401F00009BB203F00102134409299BB2F2D1BDE8F84FFFF767BEBDE8F88F00BFDC92FF1FC292FF1F4A93FF1FD592FF1FD392FF1FD892FF1F114B1B7903F07F035A1E072A3C
|
||||
:401F400019D80F490C2202FB031291781B0141F0010191700021D170517841F002015170127912F0800F074A1A4414BF8D2389239370FFF715BC0020704700BF0060004065
|
||||
:401F8000DC92FF1FFC5F004030B4194B1A7902F07F02531E072B27D8164B0C2404FB02339978154D01F0FE0199700021D97029461201505D114400F07F0050555A7802F013
|
||||
:401FC000FD025A701A795B78120605D5012B01D18C7006E00D2303E0012B0CBF082309238B7030BCFFF7DCBB002030BC704700BF00600040DC92FF1FFC5F004010B50D4BA5
|
||||
:402000000D4C21791878C9B20138C0B2FFF72EFE43681B798B4201D2012909D8074A0848535CDBB24354A3780120DBB2535410BD002010BDD592FF1F00600040C292FF1FB6
|
||||
:402040004A93FF1F38B58A4A8A4C13780021DBB221801806517840F18D800A2900F20581DFE811F05D00030103010301030103010B0003017E0003018200D3787C49012B9C
|
||||
:4020800009D17D4B1A787D4B03EBC2035B685B686360122310E0CB78022B12D18878FFF7E5FD002800F0E180436863606368DA7863689B7843EA02232380BDE83840FFF7EE
|
||||
:4020C0008FBCCB78032B26D16D4B00228878D5B2854209D3664A91786A4AEE2908BF1346634A917881B106E0187801320028F1D018780344EAE764499278097C914203D180
|
||||
:402100006248FFF739FD614B1A78002A00F0AD801A78228018E0BDE8384000F029BF13F0030313D0022B40F0A0802380504B0C211B7903F07F02564B01FB02339A78554BC3
|
||||
:40214000D2B21A7000225A706360B6E702222280514A11784F4AC9B2117053706260ACE7012323804D4BEFE70123238013794C4A1344E9E701390A2977D8DFE801F0377608
|
||||
:402180004F76067676760A7620009378454ADBB25AE0937803F0FF0153B9404B1A7891425FD01970404B01201870FFF715FE58E0481EC0B2FFF75AFD0028EED155E0FFF793
|
||||
:4021C0001DFF002851D02A4A384913791279DBB2D2B20A70364A3249D25CCB5C9A4240D0314B01221A70FFF753FD3AE003F00303012B2BD009D3022B37D11D4B9B78002B47
|
||||
:4022000033D1BDE83840FFF7BFBE194B9B78012B2BD1214A137803F0FD0315E003F00303012B13D008D3022B1FD1114B9B78E3B9BDE83840FFF77EBE0D4B9B78012B14D1B7
|
||||
:40224000154A137843F0020313700AE0084B1A795AB998781B791749DBB2CA5C22EA0002CA54BDE83840FFF79BBA002038BD00BF00600040C492FF1FD092FF1FA03A000049
|
||||
:40228000043B00008C3A0000773B00006893FF1FDC92FF1F8192FF1FD392FF1FD592FF1FC292FF1FC092FF1FD492FF1FD192FF1F4A93FF1FD792FF1F074B1A78120609D546
|
||||
:4022C0005B78012B06D1054B054A5A6012781A80FFF786BB0020704700600040C492FF1F643A0000014B1870704700BF7A640040014B1878704700BF6B650040014B18702D
|
||||
:40230000704700BF79640040064A0123136002F688321268E0211064034A1170A2F540721360704780E100E000E400E0014B1870704700BF7A650040014B1870704700BF89
|
||||
:402340007865004073B515461E460B4C05230022019200920A4601461846237000F064F932462946207800F01FF90221207800F009F9207802B070BDD080FF1F064A04232E
|
||||
:40238000136002F688321268E0219064034A1170A2F202321360704780E100E002E400E0014B04221A60704700E100E0014B04221A60704780E100E0014B1870704700BF30
|
||||
:4023C0007E640040704738B505460078012428B100F066FD285D0134E4B2F8E738BD08B50D2000F05DFDBDE808400A2000F058BDF7B516461F460B4C002303250193009359
|
||||
:402400000A4601462846257000F00EF93A463146207800F0C9F80221207800F0B3F8207803B0F0BDE080FF1FF7B516461F460B4C00230225019300930A4601462846257030
|
||||
:4024400000F0F2F83A463146207800F0ADF82946207800F097F8207803B0F0BDE180FF1FF7B516461F460B4C00230125019300930A4601462846257000F0D6F83A463146DE
|
||||
:40248000207800F091F80221207800F07BF8207803B0F0BDE280FF1F73B515461E460B4C0023019300930A4601461846237000F0BBF832462946207800F076F8022120782A
|
||||
:4024C00000F060F8207802B070BD00BFE380FF1F024B1878C0F38010704700BF8F450040074A7F23802113705170064A013BDBB202F80839002BF9D1034A1370704700BFCC
|
||||
:40250000E480FF1FF87B00400078004017280FD8084B0001C25C11B142F0200201E002F0DF02C254C25C42F00102C25400207047012070471070004017280BD8064B0001EA
|
||||
:40254000C25C02F0FE02C254C25C02F0DF02C25400207047012070471070004017280DD8074900010B4603441A7942F004021A71435C43F001034354002070470120704740
|
||||
:402580001070004017280BD8064A0001835C490003F0F10301F00E011943815400207047012070471070004041F6FF73994208BF4FF400519A4208BF4FF4005217289FBF85
|
||||
:4025C000C00000F1804000F5EC4081809ABFC280002001207047000017289FBF034B00011954002088BF0120704700BF1970004017289FBF054B00011A5C01F007019DBFDC
|
||||
:402600001143195400200120704700BF1470004017289FBF034B0001185C00F0070088BFFF20704714700040172810B51AD8C00001F07F0100F1804441EAC21204F5EC4422
|
||||
:40264000D2B222709DF8082003F00F0343EA0213DBB263709DF80C30002003F00F03A370E07010BD012010BD10B500F079FC0A4A5378182B0AD91478013B5370E30003F1FB
|
||||
:40268000804303F5F0431B78137000E0FF2400F06BFC204610BD00BFE480FF1F030610B5044611D400F05CFC084AE300117803F1804303F5F0431970537814700133537094
|
||||
:4026C000BDE8104000F050BC10BD00BFE480FF1F30B504060CD411F4704509D1C40004F1804404F5F0442180A270E370284630BD012030BD03065FBFC00000F1804000F5D2
|
||||
:40270000F04081805ABFC280002001207047000038B50446084DB4F5004F05D9286800F017FCA4F50044F6E7034B58686043BDE8384000F00DBC00BFEC80FF1F024B1B7AB4
|
||||
:40274000584300F005BC00BFEC80FF1F0E4B00F003001A78490102F0FC02104318701A7801F0600142F080021A701A7802F07F021A701A7802F09F020A431A701A7842F060
|
||||
:4027800010021A70704700BF83430040014B01221A70704784430040044B00F00F021B6853F8220043F82210704700BF08ED00E0054A00F01F00126800F1100352F8230009
|
||||
:4027C00042F82310704700BF08ED00E000F01F0000F16040490100F56440C9B2017070470F4B10B50F4900240F205C609C60DC601C615C61FFF7D0FF0B4A136843F0040334
|
||||
:4028000013600A4B4FF47A72DB68B3FBF2F3084A1360084B4FF400421C60C3F8E82010BD8492FF1F8D28000010E000E0EC80FF1F14E000E018E000E0024A136843F0020334
|
||||
:402840001360704710E000E008B5FFF7F5FF034A136843F00103136008BD00BF10E000E010B5054CA3691BB9FFF7BAFF0123A361BDE81040FFF7E8BF8492FF1F024B186891
|
||||
:40288000C0F30040704700BF10E000E038B5FFF7F5FF012808D1054D002455F8243003B198470134052CF8D138BD00BF8892FF1F024B03EB80035868596070478492FF1F1F
|
||||
:4028C000134B144A1B78DBB20360127843EA0223114A0360127843EA0243104A0360127843EA026303600E4B0E4A1B78DBB24360127843EA02230C4A4360127843EA024382
|
||||
:402900000A4A4360127843EA02634360704700BF0301004904010049EC460040020100490101004900010049050100490601004910B500F015FB204A044613780A2043F07D
|
||||
:4029400002031370137C43F00203137412F80A3C43F0010302F80A3C937943F00103937102F5AB52137843F003031370134B18221A7013F8012C42F0400203F8012C13F837
|
||||
:40298000012C02F0FC0203F8012CCE2203F8062CA3F597530222183B1A70094A137843F008031370FFF7CAFE064B10222046BDE810401A6000F0D8BAAB4300400E59004026
|
||||
:4029C0002F5B004080E200E008B500F0C9FA0F4A137803F0FE031370A2F5AA521D3A137803F0FD031370137C03F0FD03137412F80A3C03F0FE0302F80A3C937903F0FE0388
|
||||
:402A00009371BDE8084000F0AFBA00BF08590040044A137803F03F0343EA8010C0B21070704700BF08590040082804D00A280CBF8223C22300E0422308380E4AC0B2042812
|
||||
:402A4000137098BF0C4B4FF0000298BF33F910100A4B88BF11461A8042F210734B4341F2883103F6C41393FBF1F305490B60054B1A8070470A590040503A00005293FF1FB7
|
||||
:402A80005493FF1F5893FF1F08B5102000F0A6F907210420FFF79AFE07490420FFF788FE064A0C20137843F006031370FFF7BCFF034B00221A8008BD812B0000095900402E
|
||||
:402AC0005093FF1F10B5054C23781BB9FFF7DCFF01232370BDE81040FFF72ABFA092FF1F044B1A7802F0FB021A701A7842F001021A7070470859004010B5084B1C7814F0F1
|
||||
:402B0000010403D10028F9D0002404E02046FFF715FE024B1B78204610BD00BF09590040034A044B1B881088181A00B2704700BF5893FF1FA25B00400E4A13881BB223B1D5
|
||||
:402B400011880A2309B2594301E00B4B19680B4B1B88C01A42F2107300B203FB00F2022391FBF3F30028D8BF5B42134493FBF1F000B270475293FF1F5493FF1F5093FF1F29
|
||||
:402B80007047000010B500F0EBF9214A044613780A2043F001031370137C43F00103137412F80A3C43F0020302F80A3C937943F00203937102F5AA521832137843F0030343
|
||||
:402BC0001370144B18221A7013F8012C42F0400203F8012C13F8012C02F0FC0203F8012CCE2203F8062CA3F597530222123B1A70094A137843F008031370FFF79FFD074BEE
|
||||
:402C000008222046BDE810401A6000F0ADB900BFAB43004006590040275B004080E200E008B500F09DF90F4A137803F0FE031370A2F5AA52153A137803F0FE031370137C9E
|
||||
:402C400003F0FE03137412F80A3C03F0FD0302F80A3C937903F0FD039371BDE8084000F083B900BF00590040044A137803F03F0343EA8010C0B21070704700BF0059004016
|
||||
:402C8000082804D00A280CBF8223C22300E0422308380E4AC0B20428137098BF0C4B4FF0000298BF33F910100A4B88BF11461A8042F210734B4341F2883103F6C41393FBDD
|
||||
:402CC000F1F305490B60054B1A807047025900405A3A00005E93FF1F6493FF1F5C93FF1F08B5102000F084F807210320FFF76EFD07490320FFF75CFD064A0C20137843F035
|
||||
:402D000006031370FFF7BCFF034B00221A8008BDD92D0000015900406093FF1F10B5054C23781BB9FFF7DCFF01232370BDE81040FFF728BFA192FF1F044B1A7802F0FB02D6
|
||||
:402D40001A701A7842F001021A7070470059004010B5084B1C7814F0010403D10028F9D0002404E02046FFF7E9FC024B1B78204610BD00BF01590040034A044B1B88108822
|
||||
:402D8000181A00B2704700BF5C93FF1FA05B00400E4A13881BB223B111880A2309B2594301E00B4B19680B4B1B88C01A42F2107300B203FB00F2022391FBF3F30028D8BF86
|
||||
:402DC0005B42134493FBF1F000B270475E93FF1F6493FF1F6093FF1F70470000034A00F0F800137803431370704700BF02410040034A00F0F800137803431370704700BF9A
|
||||
:402E000006410040014B1870704700BF78640040014B1870704700BF7965004073B515461E460B4C04230022019200920A46014618462370FFF7F8FB324629462078FFF7AB
|
||||
:402E4000B3FB02212078FFF79DFB207802B070BDFC80FF1F074A0223136002F688321268E0215064044A11706FF440710A441360704700BF80E100E001E400E0014B18708C
|
||||
:402E8000704700BF7C640040014B1870704700BF7B640040014B1870704700BF7F640040FEB5494652465B460EB40746244909688A46244A12682448022100F071F803009B
|
||||
:402EC00020480068C018204900F06AF8143883460121C9430C460125002600F041F8814651460B7823400B705846013000F030F83800F04028400B78234003430B705846AA
|
||||
:402F000000F026F80136072EF2D9002001300138013001200B78234003430B705846043000F016F8484600F01FF800BF00BF00BF0EBC894692469B46FEBD00BFAFF3008039
|
||||
:402F4000D480FF1FF880FF1F00C20100000000000230800803D000BF01380046FCD17047EFF3108072B6704780F31088704700BF094A137803F00303012B0AD0022B09D181
|
||||
:402F800013790C2103F07F02044B01FB02339B7A00E013790020704700600040DC92FF1F002902D0B0FBF1F0704708B14FF0FF3000F008B80029F8D00246B0FBF1F000FB0B
|
||||
:402FC00011217047704700BF014B1868704700BF6081FF1F0E4B70B51E460E4C0025E41AA410A54204D056F8253098470135F8E700F0DEFD084B094C1E46E41AA41000251E
|
||||
:40300000A54204D056F8253098470135F8E770BDBC3B0000BC3B0000BC3B0000C43B000003460244934202D003F8011BFAE7704730B5141E05469BB0184604DA8B232B6026
|
||||
:403040004FF0FF301DE04FF40273ADF80C300CBF234604F1FF33029305934FF6FF7300910491ADF80E3002461E9B6946284600F073F8431CBCBF8B232B6014B1009B0022F6
|
||||
:403080001A701BB030BD000007B5009313460A46014603480068FFF7CBFF03B05DF804FB6081FF1F2DE9F0478E6882469E420C46914698463ED88A8912F4906F3AD025685F
|
||||
:4030C000096902236F1A656905EB450595FBF3F57B1C43449D4238BF1D4653050FD5294600F04AFB064698B13A46216900F0D2FAA38923F4906343F08003A38113E02A462B
|
||||
:4031000000F098FB064670B92169504600F0E8FA0C23CAF80030A3894FF0FF3043F04003A381BDE8F08726613E44266046466561ED1BA560464528BF4646494632462068B9
|
||||
:4031400000F0B3FAA36800209B1BA36023681E442660BDE8F08700002DE9F04F9DB003938B8980461C060D4616460DD50B695BB9402100F001FB2860286118B90C23C8F8D4
|
||||
:403180000030CDE040236B610023099320238DF82930DFF89CB130238DF82A3037463C4614F8013B1BB9B7EB060910D003E0252BF9D02746F3E74B46324629464046FFF7EA
|
||||
:4031C00071FF013000F0A780099B4B4409933B78002B00F0A08000234FF0FF3204930793059206938DF853301A930126052221784E4800F041FA671C049B38B14B4A3C46E7
|
||||
:40320000801A06FA00F018430490EFE7D90644BF20228DF853201A0744BF2B228DF8532022782A2A03D0079A00210A200BE0039A111D12680391002A10DA524243F002006C
|
||||
:40324000079204900BE027463B780134303B092B03D800FB02320121F5E701B107923B782E2B1ED17B782A2B0AD1039B02371A1D1B680392002BB8BF4FF0FF33059310E010
|
||||
:40328000002319460593781C0A2407463A780130303A092A03D804FB01210123F5E703B1059103223978224800F0E6F940B14023CBEB000003FA00F0049B01371843049053
|
||||
:4032C000397806221B487E1C8DF8281000F0D4F988B1194B33B9039B073323F007030833039314E003AB00932A46144B04A94046AFF3008007E003AB00932A460F4B04A937
|
||||
:40330000404600F093F8B0F1FF3F824603D0099B5344099342E7AB895B0601D4099801E04FF0FF301DB0BDE8F08F00BF8B3B0000913B0000953B000000000000A5300000D1
|
||||
:403340002DE9F04791461F460A698B6806469342B8BF1346C9F8003091F843200C46DDF8208012B10133C9F800302368990642BFD9F800300233C9F80030256815F00605F2
|
||||
:4033800010D104F1190A07E00123524639463046C04701301AD00135E368D9F800209B1A9D42F1DB94F843302268003318BF012392060FD5E118302081F843005A1C94F84E
|
||||
:4033C00045102244023382F8431003E04FF0FF30BDE8F08704F1430239463046C0470130F4D02268D9F80050E36802F00602042A08BF5D1B2269A3680CBF25EAE57500252C
|
||||
:403400009342C4BF9B1AED184FF000091A344D4509D00123224639463046C0470130D5D009F10109F3E70020BDE8F0872DE9F04317460A7E85B06E2A984606460C460C9BE3
|
||||
:4034400001F1430E00F0AE8011D8632A22D009D8002A00F0BB80582A40F0CA8081F84520834955E0642A1ED0692A1CD0C0E0732A00F0B08009D86F2A2ED0702A40F0B880A0
|
||||
:403480000A6842F020020A603EE0752A24D0782A3AD0ADE01A6801F14205111D1960136884F84230A8E021681A6811F0800F02D0111D196008E011F0400F02F104011960E2
|
||||
:4034C00002D0B2F9003000E01368002B3CDA2D225B4284F8432037E021681A6811F0800F02D0111D196007E011F0400F02F10401196001D0138800E01368227E5C496F2A40
|
||||
:4035000014BF0A2208221BE078225A4984F845202268186812F0800F00F104051D6003D1550601D5038800E00368D00744BF42F0200222601BB9226822F020022260102266
|
||||
:40354000002084F8430001E049490A226568002DA56008DB206820F0040020602BB9002D7DD175460CE0002B79D07546B3FBF2F002FB1033CB5C05F8013D03460028F5D131
|
||||
:40358000082A0BD12368DA0708D5236962689A42DEBF302305F8013C05F1FF35C5EB0E0323612EE008681A6810F0800F496903D0101D1860136808E010F0400F02F1040087
|
||||
:4035C0001860136801D0198000E0196000232361754616E01A68111D1960156800216268284600F049F808B1401B6060636804E004F1420584F8422001232361002384F8A9
|
||||
:403600004330CDF800803B4603AA21463046FFF797FE013002D14FF0FF3026E023692A4639463046C0470130F5D023689B0710D5002504F1190907E001234A4639463046F8
|
||||
:40364000C0470130E7D00135E368039A9B1A9D42F2DBE068039B9842B8BF184605E00B7804F1420584F842308AE705B0BDE8F0833F3A00009C3B000010B5C9B202449042CF
|
||||
:40368000034605D01C7801308C42F8D1184610BD002010BD10B5431E0A44914204D011F8014B03F8014FF8E710BD884210B501EB020301D8421E0BE09842FBD28118D21A41
|
||||
:4036C000D34204D013F8014D01F8014DF8E710BD994204D011F8014B02F8014FF8E710BD38B50546002944D051F8043C0C1F002BB8BFE41800F0D4F81E4A1368114613B912
|
||||
:403700006360146030E0A3420DD92268A018834201BF18685B681218226063600C6023E0A24203D813465A68002AF9D118681918A1420BD12168014458188242196013D1F2
|
||||
:4037400010685268014419605A600DE002D90C232B6009E021686018824201BF106852680918216062605C602846BDE8384000F098B838BDA892FF1F70B5CD1C25F003051A
|
||||
:4037800008350C2D38BF0C25002D064601DBA94202D90C23336046E000F082F8234B1C681A462146A1B10B685B1B0ED40B2B03D90B60CC18CD501EE08C420BBF63684B6896
|
||||
:4037C0001360636018BF0C4615E00C464968E9E7174C23681BB9304600F052F820602946304600F04DF8431C18D0C41C24F00304A0420DD12560304600F053F804F10B005E
|
||||
:40380000231D20F00700C31A0ED05A42E25070BD211A304600F034F80130EBD10C233360304600F03EF8002070BD00BFA892FF1FA492FF1FF8B5074615460E4621B91146D1
|
||||
:40384000BDE8F840FFF798BF1AB9FFF749FF2846F8BD00F027F885420ED929463846FFF78BFF044650B131462A46FFF713FF31463846FFF735FF01E03046F8BD2046F8BD40
|
||||
:4038800038B5064C0023054608462360FDF7D8FB431C02D1236803B12B6038BD8C93FF1F7047704751F8040C0028BEBF091851F8043CC018043870470000000005020902A2
|
||||
:4038C0000B020D020F021102130215027265706C792030782530327800686F6D696E6700626567696E6E696E67207365656B2066726F6D20256420746F2025640066696E08
|
||||
:403900006973686564207365656B00796573006E6F00647269766520303A20257320647269766520313A2025730057616974696E6720666F72205553422E2E2E00555342F3
|
||||
:4039400020726561647900636F6D6D616E6420307825303278006661696C2025642B25642B2564203D3D2025642C206E6F74202564007061737365643D256400756E646544
|
||||
:403980007272756E206166746572202564207061636B65747300636F756E743D256420693D256420643D256400636D645F777269746500703D25642063723D256420637729
|
||||
:4039C0003D256420663D256420773D256420696E6465783D256420756E64657272756E3D256400756E64657272756E21007375636365737300737461727420657261736912
|
||||
:403A00006E670073746F702065726173696E670069646C650000510040100040510040300000000140001000140140000800400140000A004C0140000200500140200030F9
|
||||
:403A400031323334353637383941424344454600000100000004000000100001000000040000001028000000000104000100000000000000000157494E5553420000303043
|
||||
:403A800030303100000000000000000012034D005300460054003100300030000100000001000000A83A000001000000773B0000000000000000000001000000C03A000003
|
||||
:403AC00001000000493B000004000000E23A0000000000000000000000000000E03A0000FF00000001024000FF00000082024000FF00000003034000FF00000084034000F7
|
||||
:403B0000FF00020304030904160346006C007500780045006E00670069006E0065002A0343006F0077006C00610072006B00200054006500630068006E006F006C006F0003
|
||||
:403B400067006900650073000009022E0001010080320904000004FF00000107050102400000070582024000000705030340000A0705840340000A12010002FF0001080921
|
||||
:403B800012006E0100020180014300232D302B2000686C4C00656667454647003031323334353637383961626364656600000000F8B500BFF8BC08BC9E4670475900000094
|
||||
:403BC000BD100000F8B500BFF8BC08BC9E46704735000000E83B0000C880FF1FA00000002812000000000000000000009093FF1FFF000000675000400C0000000700000097
|
||||
:403C0000FFFFFFFF7F8000003F0000000000007D00FA0000400000000090D003FF000000000000000000000000000000000000000000000000000000000000000000000031
|
||||
:403C4000893B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080
|
||||
:403C80000081FF1F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065
|
||||
:4000000000800020110000004910000049100000064A08B5136843F020031360044B1A6803F53F5302331A6001F02CF8E8460040FA46004010B5054C237833B9044B13B14F
|
||||
:400040000448AFF300800123237010BD6881FF1F00000000D0380000084B10B51BB108490848AFF300800848036803B910BD074B002BFBD0BDE81040184700BF0000000039
|
||||
:400080006C81FF1FD0380000C880FF1F000000000A4A0B4B116801310B40002BBEBF03F1FF3363F03F030133136011685368994202BF024B01221A72704700BF8881FF1FB4
|
||||
:4000C0003F0000800A4A0B4B516801310B40002BBEBF03F1FF3363F03F030133536051681368994202BF024B01221A72704700BF8881FF1F3F000080114BDA68196919B9FD
|
||||
:4001000001221A75597514E09969521A19698A4294BF587D00201875187D094908B1002204E0086982428CBF002201224A75DA689A611B7D13B1002002F04AB9704700BF6C
|
||||
:400140008881FF1F10B5C4B2204601F05DF90128FAD110BD08B572B60F4B0F49DA680132DA60DA690132C82A08BF0022DA611A6AD8690132A72A08BF00220A621B6A002B0F
|
||||
:400180000CBF02230023002814BF184643F0010002F086FE62B608BD8881FF1F38B50446C5B2284602F0B6F8062002F0D3FA44F00200C0B202F0AEF8062002F0CBFA2846F9
|
||||
:4001C00002F0A8F8BDE83840062002F0ADBA10B5642402F099F828B9FFF7E0FF013CF8D1204610BD012010BD70B5C4B2054620460E4601F009F9012805D0204601F022FA20
|
||||
:400200002846FFF79FFF204601F006F9314605460246204601F0C2F9204601F0F5F80028FAD1284670BD000038B5044D0024285D013402F03FFA402CF9D138BDAC81FF1FBB
|
||||
:4002400008B502F059FC002002F062FC02F074FC02F07EFC80B208BD10B50446012002F071F8642002F060FAFFF7EAFF2080002002F068F8642002F057FAFFF7E1FF60807C
|
||||
:4002800010BD08B502F064FD002002F06DFD02F07FFD02F089FD80B208BD10B50446FFF796FF322002F040FAFFF7EBFF20800120FFF774FF322002F037FAFFF7E2FF6080BA
|
||||
:4002C00010BD0FB400B593B014AB53F8042B402102A8019302F0E4FE02A802F080F802F08AF813B05DF804EB04B0704710B5044601780648FFF7E5FF0420FFF723FF62780A
|
||||
:400300002146BDE81040042001F0D6B8E438000007B50023ADF804308DF80600032301A88DF80530FFF7E2FF03B05DF804FB000010B5074C94F8643043B1002001F0DEFFDE
|
||||
:40034000002002F071FD002384F8643010BD00BF8881FF1F38B5104D837895F8672004469A4204D0FFF7E4FF002385F86A302368C5F865302279094B1A71A378002B14BF41
|
||||
:400380000220012002F050FDE07802F047FD2079BDE8384002F07EBD8881FF1FED81FF1F38B50D4C94F8645065B904F16500FFF7D1FF012001F0A2FF4FF47A7002F0B4F954
|
||||
:4003C00084F86A50E368E366012384F86430BDE8384002F0E7B900BF8881FF1FF8B5214C0546FFF7DDFF94F86A3003B15DB91E48FFF767FFFFF7EBFE0120002384F86A0078
|
||||
:40040000236702F0A7F92A46216F1848FFF759FF144E0027236F9D4216D001F075FF00B13767236F9D4205DD0120FFF7B7FE336F013305E005DA0020FFF7B0FE336F013B03
|
||||
:40044000336702F0AFF9E5E7322002F06DF92A2DCCBF0020012002F029FDBDE8F8400448FFF72FBF8881FF1FF1380000F8380000153900002DE9F04F99B062B602F0FCF91F
|
||||
:400480009E49042002F020FA9D4801F049FF9D4802F0ECFC9C4801F07DFF02F0CDFB02F09FFA002002F0C0FC01F098FF0221002000F060FF954C012001F0D8F8002384F868
|
||||
:4004C0006730FFF76DFFFFF782FE84F87400FFF72FFF012384F86730FFF762FFFFF777FE84F87500FFF724FF894B94F87400894994F875202546002A14BF0A461A4600286F
|
||||
:4005000008BF19468448FFF7DCFE0321084602F029F9264602F046F994F8643043B1EA6EEB689B1A41F28832934201D9FFF700FF00F058FF18B97948FFF7C3FE04E000F06D
|
||||
:4005400057FF0028F7D10BE000F04CFF10B902F029F9F9E77248FFF7B4FE032001F072F8032000F051FF0128D4D16E48FFF7F2FE6D490320FFF738FE94F876106B48FFF7E5
|
||||
:40058000A0FE94F87630023B142B00F2D683DFE813F01500D4031E00D4032400D4035000D4037600D403D900D403C101D4030803D4032C03D4033303D4034D0303238DF851
|
||||
:4005C00020308DF821300F238DF822302AE394F87800FFF703FF564B21E340F2DC57FFF7DFFE00232375E068227D02F0FF012AB9EB681B1ABB42F7DD0B4611E083B100227E
|
||||
:40060000174696F87810F068277594F814E0BEF1000F02D1EB681B1AF7E701329142F3DA07228DF8202004228DF82120ADF82230F8E20220FFF786FD4FF000080DF1200A54
|
||||
:4006400002F0B0F84FF480790027C9EB0803DA1907F80A200137402FF9D10220FFF772FD3A465146022000F027FFB9F10109EBD108F10108B8F1400FE2D12E4B38E04FF06E
|
||||
:40068000010A4FF000080DF1200B02F08BF84FF0000959460120FFF7A7FD08EB090300270493049B1BF807203B44DBB29A4209D08DE80C0041463B464A461F48FFF701FEDC
|
||||
:4006C0004FF0000A0137402FEBD109F10109B9F5807FDED108F10108B8F1400FD5D151461648FFF7EEFDBAF1000F00F01B81144B1B8807A8ADF81C3095E200BF5501000004
|
||||
:40070000F900000091000000C50000008881FF1F27390000233900002A3900004239000055390000ED81FF1FFE81FF1F5F390000D4380000D63800006E3900008A390000D6
|
||||
:40074000D8380000206FFFF749FE94F8780001F0F9FD94F8780001F0DDFD02F00DFCB94BDFF8FC821A78002702F0FB021A701A7842F001021A701A7802F0FE021A701A786C
|
||||
:4007800002F0FE021A7002F0FBFB0220FFF7DAFC012141F6FF734FF48042084602F04AFB84F8B60001F06CFF08F807000137402FF8D1DFF8B0A200270AF195091FFA89F80A
|
||||
:4007C0000137402F14BF3A4600221AF8010F2244062392F82420402101F086FF424646F24F419AF8000001F091FF08F14008402F1FFA88F8E4D196F8793053B196F87C30B1
|
||||
:40080000336100233375237D002BFCD000233375336100234FF0FF32236062602372236894F8B600234493F8241001F0E1FE94F8B60001F09FFE012194F8B60001F072FE9E
|
||||
:400840002368002BFCD0002398467360D6F80CA0012701F0A7FFE368B4F87A20CAEB030393420DD367B1042195F8B60001F0CCFE94F8B60001F0D8FE0028F9D107463072C3
|
||||
:40088000237AFBB96A682B689A4202D1002FE0D118E00220FFF756FC6968402209EB8111022000F009FE6A68674B01321340002BBEBF03F1FF3363F03F03013308F101081C
|
||||
:4008C0006360C6E70220277AFFF73CFC00221146022000F0F1FD0220FFF734FCFFB2FFF7A3FC002001F016FD37B15848FFF7E9FC0220FFF70DFD06E0554B08A81B88ADF869
|
||||
:400900002030FFF7F3FC227D4146237A5148FFF7D8FC15E25048FFF7D4FCD4F87A7017F03F0701D0032009E2286FFFF757FD95F8780001F007FD95F8780001F0EBFC01204C
|
||||
:4009400001F006FD02F018FB444BDFF814811A7842F004021A701A7842F001021A701A7802F0FE021A701A7802F0FE021A7002F007FB01214FF4804341F6FF72084601F0BF
|
||||
:40098000EDFC85F8B60001F07BFE08F807000137402FF8D1DFF8CC90002709F195031FFA83F804930137402F14BF3A46002219F8010F2244052392F82420402101F094FEA6
|
||||
:4009C000414646F24A5299F8000001F09FFE08F14008402F1FFA88F8E4D100274FF0FF33376098467360BB463B46D6F87A9037725FEA99190CBF4FF0010A4FF0000A2168BA
|
||||
:400A0000114A01310A40002ABCBF02F1FF3262F03F026068B8BF013282426FD02BB1227A002A7AD12A7D002A77D12068049A059302EB8010BAF1000F16D040223F2102F079
|
||||
:400A4000FBFA1CE09F6400403F00008094390000DA380000AE390000C13900009A650040AC81FF1FAB81FF1F014601370120FFF7BBFBC7EB0903D3F1000A4AEB030A21684C
|
||||
:400A8000B34A01310A40002ABEBF02F1FF3262F03F02013222606268059B01322ED12A683F2A2BD14FF00008C5F8048001F084FC85F808806B6895F8B6002B4493F82410D5
|
||||
:400AC00001F096FD95F8B60001F054FD012195F8B60001F027FD95F87E302B6185F81480237D002BFCD04FF00008012086F8148001F06EFC404601F02BFC00E023B1237A40
|
||||
:400B00005BB92B7D4BB90123626842453FF477AF0BF1010BD5F8048071E701F053FC012001F016FC002001F053FC042194F8B60001F06AFD94F8B60001F076FD804600285F
|
||||
:400B4000F8D196F8B60001F003FD337D327A0293012303920193CDF800A05B463A4649467C48FFF7AEFBC6F81080BAF1000F0BD0FFF75AFB002001F0CDFB237A63B176484B
|
||||
:400B8000FFF79FFB0220D9E0B945F1D073490120FFF72AFB0137F7E77148FFF792FB714B3DE094F8780001F0CDFB206FFFF716FC6D48FFF786FB94F87930236100232375F4
|
||||
:400BC000237D002BFCD0012001F002FC00233375237D002BFCD0002001F0FAFB002363483361FFF76EFB624B19E0002084F86A00FFF7F4FB5F4B12E094F8743023B195F867
|
||||
:400C000075200AB985F8782094F875201AB113B9012385F878305848FFF79CFB574B1B88ADF8203008A8FFF761FB89E0FFF780FB02F080F8002002F023F82A2701F04EFFDD
|
||||
:400C4000002001F0F1FE3A46002108A802F0F4F917238DF820308DF8217001F0A3FD002001F04CFB002002F0DFF8C82001F05CFD0DF12200FFF7F0FA0DF13600FFF70DFBE9
|
||||
:400C800001F090FD012002F0CFF8322001F04CFD0DF12600FFF7E0FA0DF13A00FFF7FDFA012001F02BFB4FF4967001F03DFD01F079FD0DF12E00FFF7CFFA0DF14200FFF703
|
||||
:400CC000ECFA002001F01AFB4FF4967001F02CFD01F068FD022002F0A7F8322001F024FD0DEB0700FFF7B8FA0DF13E00FFF7D5FA012001F003FB4FF4967001F015FD01F023
|
||||
:400D000051FD0DF13200FFF7A7FA0DF14600FFF7C4FA002001F0F2FA4FF4967001F004FD01F040FD002002F07FF8002384F86A3001F082FF01F054FE74E70120FFF7E8FA75
|
||||
:400D4000032000F07FFC0E48FFF7BBFAFFF7E2BB3F000080CB390000FB3900004092FF1F053A0000DC3800000D3A00001B3A0000DE380000E0380000FE81FF1FE238000096
|
||||
:400D8000283A00002DE9F04172B6874A874D1378002443F020031370062606FB045300219A881868013402F047F9072CF5D18048804D002450F8041F04F1105303F14C02D0
|
||||
:400DC00021F0FF064D33C9B20B4452005B0002329A4206D012F8027C12F801EC07F806E0F5E7A8420C44E5D1734A00231360936013619361714A724D1168724A724C116044
|
||||
:400E0000724A19261168724A724F116072490A7842F002020A700A7C42F002020A742A78A1F5863142F040022A7041390A7842F010020A70694A07CA03C469492280086863
|
||||
:400E4000684A2834106009791171674A07CA03C42280664AE83C07CA03C42280644A083407CA03C42280634A03CAC4F80A006248C4F80E100178614C41F008010170604995
|
||||
:400E800061200870A1F5F061012008808E7092E803005C4A84E80300062111705221A2F580721170584A594912781C46D2B20A70574A4FF4E261118041F2512122F8021C31
|
||||
:400EC0003B784FF4F07003F0010343EA440303F0030402F049F8013E64D0032CF0D14D4A4FF4807313804C49072313704B4800230B704821017013705371494B02221A706B
|
||||
:400F000004229A7290F89A33464F43F0010380F89A3390F89933DFF82C8143F0030380F899332B78C12043F080032B70344B18703D4B3E481B783C78DBB298F80060E4B280
|
||||
:400F400003F0070ED34080F800E0F6B2437044F003033B7046F0030388F80030344B1970344940230B708B700B728B72082381F81F32202180F8B51280F8BA222E4A0A208F
|
||||
:400F8000117082F82D3001F0E5FB2C4B88F8006044223C702A4C1A7095E80F0007C42380BDE8F081FEE700BFE84600402D3A0000FCFFFF4794000048007600405C0B004894
|
||||
:400FC000A043004020760040C0510040600B0048287600402542004003500140140B0048200B0048CB510040280B0048340B0048400B00484C0B004822430040004100404B
|
||||
:4010000000480040004300400F010049A14600402242004004400040064000400840004001400040F8460040CF0100496E5800401D510040015900402B5B004076580040B5
|
||||
:40104000B0430040F946004008B501F0C9FF03680C2B00D1FEE7FEE7084908B50B68084A1844821A802A01DC086005E001F0B8FF0C2303604FF0FF33184608BDCC80FF1F34
|
||||
:401080009093FF1F80B51148114B0025C0B1A3F1100192C922460439161BB74204D051F8046F42F8046BF7E7114653F8046C8C1AA64202D041F8045BF9E701381033E5E757
|
||||
:4010C00001F094FFFFF7D6F9FEE700BF01000000FC3B0000124A134B10B51A60124A134C1368134843F4007313600023032B98BF54F823204FEA830188BF0E4A0133302B02
|
||||
:401100004250F3D10C4B1A780C4B1A700C4B084A1A60FFF737FEBDE8104001F0EDB900BF0004FA050CED00E014ED00E0000000000080FF1F49100000BC760040C080FF1F72
|
||||
:4011400008ED00E0F8B501F017FF4B4A01271378022643F001031370137C484C43F001031374474B02F5E3521F700B3203F8946C1378054603F07F031370002001F0EAFA93
|
||||
:401180002378404A03F0F90323701378384603F0DF03137023783B43237001F0DBFA282001F0D8FA384B30461A7802F07F021A701A7802F0BF021A7023783343237001F0BE
|
||||
:4011C000C9FA2378314A43F0040323700023137053702F4AFF2199540133092BFBD1284601F0CEFE0721172001F0FCFA2949172001F0EAFA0721182001F0F4FA2649182051
|
||||
:4012000001F0E2FA0721152001F0ECFA2349152001F0DAFA0721052001F0E4FA2049052001F0D2FA0721062001F0DCFA1D49062001F0CAFA0721084601F0D4FA1A490720CB
|
||||
:4012400001F0C2FA0721082001F0CCFA1749082001F0BAFA0021162001F0C4FA1449162001F0B2FA07210C2001F0BCFABDE8F84010490C2001F0A8BAA54300409443004068
|
||||
:401280009D60004012600040F851004084600040B592FF1F131B00004D190000111B0000451A0000711A0000A11A0000D91A0000191B00008D1B0000214B224A10B51870D4
|
||||
:4012C00000231370204A40201370204A0F2413701F4A13701F4A13701F4A13701F4A13701F4B4FF400021A604FF080721A604FF400121A6020221A601860802018604FF4F9
|
||||
:4013000080701860174804704FF480001860164B1A70933B19B91A7802F0FE0202E01A7842F001021A70114B03221A70802203F8202C012001F018FE0D4B04221A7010BD04
|
||||
:40134000D092FF1FD692FF1FD492FF1FD592FF1FD192FF1FC092FF1FD392FF1F4893FF1F00E100E09E6000409C600040286000401260004070B5074C054623780E461BB9B6
|
||||
:40138000FFF7E0FE0123237031462846BDE87040FFF792BF8092FF1F0A4A002313700A4A13700A4A13700A4A13700A4A13700A4A13700A4A13700A4B03221A70802203F84C
|
||||
:4013C000202C7047D692FF1FD492FF1FD592FF1FD192FF1FC092FF1FD392FF1F4893FF1F28600040014B1878704700BFD592FF1F044B1A7802F0FF001AB118780022C0B28E
|
||||
:401400001A707047D492FF1F024A0C2303FB002040787047DC92FF1F431E072B0CD8074A064B00010344805C5B7800F00F0043EA0020023880B2704700207047FC5F004062
|
||||
:401440001A4A38B50C2303FB00231B79090C13F0800F00F1FF35044619BF8AB24FF480438BB24FF48042032D18D8DFE805F002070C110021084601F01BF80DE000210846F4
|
||||
:4014800000F0FAFF08E00021084600F0D9FF03E00021084600F0B8FF054B1855EDB2072D03D801F0EDF8034B185538BDDC92FF1FAC92FF1FB592FF1F431E072B2DE9F0470D
|
||||
:4014C0000446894615465CD82F4F0C2202FB0072D388DFF8B8A09BB2C3F500739D424FF00C0303FB007388BFD588DB7884BFC5F50075ADB2254A43EA15230601B354B244E9
|
||||
:40150000EBB28AF80130224B1A5C9846FF2A01D1FFF796FF0C2303FB047200215170B9F1000F28D03DB31B4F385D01F011F811232946FE2218F8040001F0D6F806F5C04262
|
||||
:4015400078321FFA89F118F8040001F0DFF8124D18F80410385D01F04BF80121385D00F0E1FF735D43F002037355735D03F0FD037355BDE8F08703FB04746379DBB28AF8A7
|
||||
:401580000230BDE8F08700BFDC92FF1FFC5F0040B592FF1FAC92FF1F706000402DE9F047044615468846002940D0431E072B3FD8FFF732FFA84203D22046FFF72DFF0546CA
|
||||
:4015C0001D4E335DFF2B03D141462046FFF738FFDFF868A027011AF8040000F0B9FF1223FE222946305D01F07FF807F5C0411FFA88F27831305D01F089F8DFF84490315DE9
|
||||
:401600001AF8040000F0F4FF01211AF8040000F089FF17F8093043F0020307F8093017F8093003F0FD0307F8093002E00D4600E000252846BDE8F087B592FF1FAC92FF1F51
|
||||
:4016400070600040431E072B0AD8064A0C2303FB002300225A705A79034BD2B200011A54704700BFDC92FF1FFE5F0040431E072B9FBF024B000108221A547047FE5F00407B
|
||||
:4016800030B51A4A1A491B4D0878138803449BB21380194A00231488D8B2A4B27CB1082B0CD050680078C0B2E85450680133013050601088013880B21080ECE718460B78A4
|
||||
:4016C0000E4C082B0E4A00D040B10E4D2B7883F080032B700F232370022301E0022323701370094B1870087030BD00BF4C93FF1F4893FF1F00600040C492FF1FC192FF1F34
|
||||
:40170000D692FF1FD292FF1F4993FF1F074B02221A70074B80221A70064B0F221A70064A00231370054A012013707047D692FF1FD292FF1FC192FF1F4893FF1F4993FF1F11
|
||||
:4017400030B5164B16491B780A8803F00F03023BDBB21A4492B20A80124C134A0020118889B279B173B15568215C013BC9B229705168DBB20131516011880130013989B2B5
|
||||
:401780001180ECE7094A1370094A137883F080031370084B0B221A7030BD00BF296000404C93FF1F00600040C492FF1F4993FF1FD292FF1FC192FF1F064A06231370064ACF
|
||||
:4017C00001201370054B80221A70054B00221A70704700BFD692FF1FC192FF1FD292FF1F4993FF1F054B9A683AB19A68044910709A680988518000229A607047C492FF1F2D
|
||||
:401800004C93FF1F08B5124B1A78D2B21A701B78DBB21A0602D50F4A137008BD0220FFF7E1FF0D4B1B7803F06003202B05D0402B06D043B900F012FC04E001F0A5FB01E04F
|
||||
:4018400000F046FD10B9034B03221A7008BD00BF28600040C192FF1F0060004008B5084A084B0120197813880B449BB21380064B00221A70FFF7B6FF044B03221A7008BDC9
|
||||
:401880004C93FF1F4893FF1FD692FF1FC192FF1F08B50C4B1B78DBB2042B07D0062B09D0022B0DD1BDE80840FFF7D8BFBDE80840FFF746BF0320FFF795FF034B03221A70E0
|
||||
:4018C00008BD00BFD692FF1FC192FF1F08B5054B002201201A70FFF785FF034B03221A7008BD00BFD692FF1FC192FF1F08B50A4B1A7832B11A78094942F080020A700022E6
|
||||
:401900001A70074B002201201A70FFF76BFF054B03221A7008BD00BFC092FF1F08600040D692FF1FC192FF1F074B1B78DBB2042B05D0062B05D0022B05D1FFF7A1BEFFF742
|
||||
:40194000C5BFFFF7D3BF7047D692FF1F38B51D4C2378DBB2DD0634D518060AD503F00F03012B2ED1FFF74EFF174B1B78190609D538BD5A0602D5FFF7D7FF03E09D0620D5DF
|
||||
:40198000FFF786FF23781B061BD4104B1A78104B1B7813430F4A13701278934211D10A4A0849154613782078DBB2000605D41378DBB20B700B7803F00F0328788342F1D1E2
|
||||
:4019C00038BD38BD28600040C192FF1FD292FF1F4993FF1F29600040054A00231380054A916819B191680B7092685380704700BF4C93FF1FC492FF1F0E4808B503889BB255
|
||||
:401A000013B9FFF783FE13E00B4B02221A700B4B00221A70FFF7E0FF094AD1799379028843EA012392B2934238BF0380FFF728FE012008BDC492FF1FD692FF1FD292FF1F00
|
||||
:401A400000600040084B01221A700F3B9B7C074B1A7B02F00302012A1EBFDA7B82F08002DA7301225A7370470B600040DC92FF1F094B02221A700F3B93F82230074B1A7EF8
|
||||
:401A800002F00302012A1EBFDA7E82F08002DA7601225A76704700BF0B600040DC92FF1F0B4B04221A700F3B93F83230094B93F8242002F00302012A1EBF93F8272082F048
|
||||
:401AC000800283F82720012283F82520704700BF0B600040DC92FF1F0B4B08221A700F3B93F84230094B93F8302002F00302012A1EBF93F8332082F0800283F833200122D0
|
||||
:401B000083F83120704700BF0B600040DC92FF1F7047FFF741BC0000F0B5184B184E19780C27C9B201234FF0000C31B3CA0720D5144A4FEA031E7244947850782040C5074E
|
||||
:401B40000DD507FB03652C79240608D5147804F0FE0414706D790C4CEDB204F80E50840706D507FB036425792D0658BF84F801C090700133DBB24908D7E7F0BD9F60004080
|
||||
:401B8000DC92FF1F70600040FE5F004000F0ACBC70B50446184B88B003AA03F11006154618685968083303C5B3422A46F7D11B782B70FCB12223237001AD0323284663703F
|
||||
:401BC00000F08AFE002220461146AB5C08AC04EB131414F8144C03F00F03847008AC234413F8143C0132082AC1700371417100F10400EAD108B070BD573A00002DE9F043B7
|
||||
:401C00001C4D01222E460C201F274FF0800E4FF0080C194B00FB02581401234418705F70164998F805902144B9F1000F07D098F8044024064CBF887081F802C001E081F877
|
||||
:401C400002E000FB0261CC880132E4B29C71CC88092AC4F30724DC71CC88E4B21C71C988C1F307215971D4D1054BFF221A70BDE8F08300BFDC92FF1F70600040FC5F004028
|
||||
:401C80000A600040064B074A1B7802EBC30253681A7C824286BF03EBC003586900207047D092FF1FB83A00002DE9F84F424B1A78002A7ED01878414D0138C0B2FFF7E2FFEA
|
||||
:401CC000A8463F4AC3681478007ADFF800C1E4B203EBC0000C2600274FF0010E834268D01A78A24263D11CF80420597891425ED19A7893F8039002F07F0206FB02FA05EB77
|
||||
:401D00000A01CF7093F802B009F0030981F804B093F803B005F80AB0B3F804A0A1F808A093F902A0BAF1000F0BDAB9F1010F0CBF4FF007094FF00D0981F8059081F801E007
|
||||
:401D400009E0B9F1010F0CBF4FF005094FF0090981F805904F704FEA02191A4906FB0282494481F802E0B2F808A0CAF3072A81F800A0B2F808A05FFA8AFA81F801A0B2F81A
|
||||
:401D800006A011495FFA8AFA494481F806A0B2F80690C9F3072981F80790B2F806905FFA89F981F80490D288C2F307224A71083394E7BDE8F88F00BFD592FF1FDC92FF1F91
|
||||
:401DC000D192FF1FFC5F004070600040C292FF1F08B5064B18780138C0B2FFF753FF20B143681B7900EBC300406908BDD592FF1F00212DE9F84F0B464E4E0C2707FB01F46E
|
||||
:401E000001313219092933554FF000059370494CD3701381937253705371EFD118B1464B1D70464B1D70464B1A78002A7FD0187801250138C0B2FFF725FFA8464368DFF8E0
|
||||
:401E4000F8E0DB790C2713F0400F3E4B4FF0000C1A7814BF42F0010202F0FE021A70027AD20007FB0541C36803EB02094B4531D093F802A00AF07F06AE4229D10E89B3F8A4
|
||||
:401E800004B0B6B25E4538BFA1F808B01E7893F801B01EF80660B3451AD181F804A0DE780E7093F902A0DE78BAF1000F06F0030607DA012E0CBF07260D264E7181F80180C8
|
||||
:401EC00006E0012E0CBF052609264E7181F801C00833CBE70135092DC3D1C1680A328B1C0A440C200833934209D013F8081C13F80A5C01F07F0100FB01418D72F2E7FFF737
|
||||
:401F000067FF114B0121186000230C2000FB0142D3801289013113449BB203F00102134409299BB2F2D1BDE8F84FFFF767BEBDE8F88F00BFDC92FF1FC292FF1F4A93FF1F7A
|
||||
:401F4000D592FF1FD392FF1FD892FF1F114B1B7903F07F035A1E072A19D80F490C2202FB031291781B0141F0010191700021D170517841F002015170127912F0800F074A54
|
||||
:401F80001A4414BF8D2389239370FFF715BC0020704700BF00600040DC92FF1FFC5F004030B4194B1A7902F07F02531E072B27D8164B0C2404FB02339978154D01F0FE0155
|
||||
:401FC00099700021D97029461201505D114400F07F0050555A7802F0FD025A701A795B78120605D5012B01D18C7006E00D2303E0012B0CBF082309238B7030BCFFF7DCBB3C
|
||||
:40200000002030BC704700BF00600040DC92FF1FFC5F004010B50D4B0D4C21791878C9B20138C0B2FFF72EFE43681B798B4201D2012909D8074A0848535CDBB24354A378F6
|
||||
:402040000120DBB2535410BD002010BDD592FF1F00600040C292FF1F4A93FF1F38B58A4A8A4C13780021DBB221801806517840F18D800A2900F20581DFE811F05D00030155
|
||||
:4020800003010301030103010B0003017E0003018200D3787C49012B09D17D4B1A787D4B03EBC2035B685B686360122310E0CB78022B12D18878FFF7E5FD002800F0E18000
|
||||
:4020C000436863606368DA7863689B7843EA02232380BDE83840FFF78FBCCB78032B26D16D4B00228878D5B2854209D3664A91786A4AEE2908BF1346634A917881B106E046
|
||||
:40210000187801320028F1D018780344EAE764499278097C914203D16248FFF739FD614B1A78002A00F0AD801A78228018E0BDE8384000F029BF13F0030313D0022B40F0A3
|
||||
:40214000A0802380504B0C211B7903F07F02564B01FB02339A78554BD2B21A7000225A706360B6E702222280514A11784F4AC9B2117053706260ACE7012323804D4BEFE722
|
||||
:402180000123238013794C4A1344E9E701390A2977D8DFE801F037764F76067676760A7620009378454ADBB25AE0937803F0FF0153B9404B1A7891425FD01970404B012062
|
||||
:4021C0001870FFF715FE58E0481EC0B2FFF75AFD0028EED155E0FFF71DFF002851D02A4A384913791279DBB2D2B20A70364A3249D25CCB5C9A4240D0314B01221A70FFF788
|
||||
:4022000053FD3AE003F00303012B2BD009D3022B37D11D4B9B78002B33D1BDE83840FFF7BFBE194B9B78012B2BD1214A137803F0FD0315E003F00303012B13D008D3022B3C
|
||||
:402240001FD1114B9B78E3B9BDE83840FFF77EBE0D4B9B78012B14D1154A137843F0020313700AE0084B1A795AB998781B791749DBB2CA5C22EA0002CA54BDE83840FFF71A
|
||||
:402280009BBA002038BD00BF00600040C492FF1FD092FF1FB83A00001C3B0000A43A00008F3B00006893FF1FDC92FF1F8192FF1FD392FF1FD592FF1FC292FF1FC092FF1FB0
|
||||
:4022C000D492FF1FD192FF1F4A93FF1FD792FF1F074B1A78120609D55B78012B06D1054B054A5A6012781A80FFF786BB0020704700600040C492FF1F7C3A0000014B18707E
|
||||
:40230000704700BF7B650040014B1878704700BF6B640040014B1870704700BF75650040064A0123136002F688321268E0211064034A1170A2F540721360704780E100E038
|
||||
:4023400000E400E0014B1870704700BF7E640040014B1870704700BF7D64004073B515461E460B4C05230022019200920A4601461846237000F064F932462946207800F0D1
|
||||
:402380001FF90221207800F009F9207802B070BDD080FF1F064A0423136002F688321268E0219064034A1170A2F202321360704780E100E002E400E0014B04221A607047FE
|
||||
:4023C00000E100E0014B04221A60704780E100E0014B1870704700BF78650040704738B505460078012428B100F066FD285D0134E4B2F8E738BD08B50D2000F05DFDBDE81C
|
||||
:4024000008400A2000F058BDF7B516461F460B4C00230325019300930A4601462846257000F00EF93A463146207800F0C9F80221207800F0B3F8207803B0F0BDE080FF1F52
|
||||
:40244000F7B516461F460B4C00230225019300930A4601462846257000F0F2F83A463146207800F0ADF82946207800F097F8207803B0F0BDE180FF1FF7B516461F460B4CCE
|
||||
:4024800000230125019300930A4601462846257000F0D6F83A463146207800F091F80221207800F07BF8207803B0F0BDE280FF1F73B515461E460B4C0023019300930A46DE
|
||||
:4024C00001461846237000F0BBF832462946207800F076F80221207800F060F8207802B070BD00BFE380FF1F024B1878C0F38010704700BF8F450040074A7F2380211370A9
|
||||
:402500005170064A013BDBB202F80839002BF9D1034A1370704700BFE480FF1FF87B00400078004017280FD8084B0001C25C11B142F0200201E002F0DF02C254C25C42F096
|
||||
:402540000102C25400207047012070471070004017280BD8064B0001C25C02F0FE02C254C25C02F0DF02C25400207047012070471070004017280DD8074900010B460344B6
|
||||
:402580001A7942F004021A71435C43F00103435400207047012070471070004017280BD8064A0001835C490003F0F10301F00E0119438154002070470120704710700040C7
|
||||
:4025C00041F6FF73994208BF4FF400519A4208BF4FF4005217289FBFC00000F1804000F5EC4081809ABFC280002001207047000017289FBF034B00011954002088BF012020
|
||||
:40260000704700BF1970004017289FBF054B00011A5C01F007019DBF1143195400200120704700BF1470004017289FBF034B0001185C00F0070088BFFF207047147000402E
|
||||
:40264000172810B51AD8C00001F07F0100F1804441EAC21204F5EC44D2B222709DF8082003F00F0343EA0213DBB263709DF80C30002003F00F03A370E07010BD012010BDC8
|
||||
:4026800010B500F079FC0A4A5378182B0AD91478013B5370E30003F1804303F5F0431B78137000E0FF2400F06BFC204610BD00BFE480FF1F030610B5044611D400F05CFC32
|
||||
:4026C000084AE300117803F1804303F5F04319705378147001335370BDE8104000F050BC10BD00BFE480FF1F30B504060CD411F4704509D1C40004F1804404F5F0442180BE
|
||||
:40270000A270E370284630BD012030BD03065FBFC00000F1804000F5F04081805ABFC280002001207047000038B50446084DB4F5004F05D9286800F017FCA4F50044F6E70B
|
||||
:40274000034B58686043BDE8384000F00DBC00BFEC80FF1F024B1B7A584300F005BC00BFEC80FF1F0E4B00F003001A78490102F0FC02104318701A7801F0600142F0800287
|
||||
:402780001A701A7802F07F021A701A7802F09F020A431A701A7842F010021A70704700BF83430040014B01221A70704784430040044B00F00F021B6853F8220043F82210C4
|
||||
:4027C000704700BF08ED00E0054A00F01F00126800F1100352F8230042F82310704700BF08ED00E000F01F0000F16040490100F56440C9B2017070470F4B10B50F490024CC
|
||||
:402800000F205C609C60DC601C615C61FFF7D0FF0B4A136843F0040313600A4B4FF47A72DB68B3FBF2F3084A1360084B4FF400421C60C3F8E82010BD8492FF1FA5280000F5
|
||||
:4028400010E000E0EC80FF1F14E000E018E000E0024A136843F002031360704710E000E008B5FFF7F5FF034A136843F00103136008BD00BF10E000E010B5054CA3691BB9F6
|
||||
:40288000FFF7BAFF0123A361BDE81040FFF7E8BF8492FF1F024B1868C0F30040704700BF10E000E038B5FFF7F5FF012808D1054D002455F8243003B198470134052CF8D1C3
|
||||
:4028C00038BD00BF8892FF1F024B03EB80035868596070478492FF1F134B144A1B78DBB20360127843EA0223114A0360127843EA0243104A0360127843EA026303600E4B60
|
||||
:402900000E4A1B78DBB24360127843EA02230C4A4360127843EA02430A4A4360127843EA02634360704700BF0301004904010049EC46004002010049010100490001004991
|
||||
:40294000050100490601004910B500F015FB204A044613780A2043F002031370137C43F00203137412F80A3C43F0010302F80A3C937943F00103937102F5AB52137843F0C1
|
||||
:4029800003031370134B18221A7013F8012C42F0400203F8012C13F8012C02F0FC0203F8012CCE2203F8062CA3F597530222183B1A70094A137843F008031370FFF7CAFE4B
|
||||
:4029C000064B10222046BDE810401A6000F0D8BAAB4300400E5900402F5B004080E200E008B500F0C9FA0F4A137803F0FE031370A2F5AA521D3A137803F0FD031370137CD7
|
||||
:402A000003F0FD03137412F80A3C03F0FE0302F80A3C937903F0FE039371BDE8084000F0AFBA00BF08590040044A137803F03F0343EA8010C0B21070704700BF085900401A
|
||||
:402A4000082804D00A280CBF8223C22300E0422308380E4AC0B20428137098BF0C4B4FF0000298BF33F910100A4B88BF11461A8042F210734B4341F2883103F6C41393FB1F
|
||||
:402A8000F1F305490B60054B1A8070470A590040683A00005293FF1F5493FF1F5893FF1F08B5102000F0A6F907210420FFF79AFE07490420FFF788FE064A0C20137843F002
|
||||
:402AC00006031370FFF7BCFF034B00221A8008BD992B0000095900405093FF1F10B5054C23781BB9FFF7DCFF01232370BDE81040FFF72ABFA092FF1F044B1A7802F0FB0262
|
||||
:402B00001A701A7842F001021A7070470859004010B5084B1C7814F0010403D10028F9D0002404E02046FFF715FE024B1B78204610BD00BF09590040034A044B1B88108826
|
||||
:402B4000181A00B2704700BF5893FF1FA25B00400E4A13881BB223B111880A2309B2594301E00B4B19680B4B1B88C01A42F2107300B203FB00F2022391FBF3F30028D8BFCA
|
||||
:402B80005B42134493FBF1F000B270475293FF1F5493FF1F5093FF1F7047000010B500F0EBF9214A044613780A2043F001031370137C43F00103137412F80A3C43F00203F7
|
||||
:402BC00002F80A3C937943F00203937102F5AA521832137843F003031370144B18221A7013F8012C42F0400203F8012C13F8012C02F0FC0203F8012CCE2203F8062CA3F5CD
|
||||
:402C000097530222123B1A70094A137843F008031370FFF79FFD074B08222046BDE810401A6000F0ADB900BFAB43004006590040275B004080E200E008B500F09DF90F4AAB
|
||||
:402C4000137803F0FE031370A2F5AA52153A137803F0FE031370137C03F0FE03137412F80A3C03F0FD0302F80A3C937903F0FD039371BDE8084000F083B900BF005900406D
|
||||
:402C8000044A137803F03F0343EA8010C0B21070704700BF00590040082804D00A280CBF8223C22300E0422308380E4AC0B20428137098BF0C4B4FF0000298BF33F910102D
|
||||
:402CC0000A4B88BF11461A8042F210734B4341F2883103F6C41393FBF1F305490B60054B1A80704702590040723A00005E93FF1F6493FF1F5C93FF1F08B5102000F084F8A9
|
||||
:402D000007210320FFF76EFD07490320FFF75CFD064A0C20137843F006031370FFF7BCFF034B00221A8008BDF12D0000015900406093FF1F10B5054C23781BB9FFF7DCFFC0
|
||||
:402D400001232370BDE81040FFF728BFA192FF1F044B1A7802F0FB021A701A7842F001021A7070470059004010B5084B1C7814F0010403D10028F9D0002404E02046FFF7A0
|
||||
:402D8000E9FC024B1B78204610BD00BF01590040034A044B1B881088181A00B2704700BF5C93FF1FA05B00400E4A13881BB223B111880A2309B2594301E00B4B19680B4B8A
|
||||
:402DC0001B88C01A42F2107300B203FB00F2022391FBF3F30028D8BF5B42134493FBF1F000B270475E93FF1F6493FF1F6093FF1F70470000034A00F0F80013780343137066
|
||||
:402E0000704700BF02410040034A00F0F800137803431370704700BF06410040014B1870704700BF77650040014B1870704700BF7465004073B515461E460B4C04230022C3
|
||||
:402E4000019200920A46014618462370FFF7F8FB324629462078FFF7B3FB02212078FFF79DFB207802B070BDFC80FF1F074A0223136002F688321268E0215064044A1170A6
|
||||
:402E80006FF440710A441360704700BF80E100E001E400E0014B1870704700BF78640040014B1870704700BF7B640040014B1870704700BF79650040FEB5494652465B460F
|
||||
:402EC0000EB40746244909688A46244A12682448022100F071F8030020480068C018204900F06AF8143883460121C9430C460125002600F041F8814651460B7823400B7016
|
||||
:402F00005846013000F030F83800F04028400B78234003430B70584600F026F80136072EF2D9002001300138013001200B78234003430B705846043000F016F8484600F07F
|
||||
:402F40001FF800BF00BF00BF0EBC894692469B46FEBD00BFAFF30080D480FF1FF880FF1F00C20100000000000230800803D000BF01380046FCD17047EFF3108072B67047A4
|
||||
:402F800080F31088704700BF094A137803F00303012B0AD0022B09D113790C2103F07F02044B01FB02339B7A00E013790020704700600040DC92FF1F002902D0B0FBF1F0F4
|
||||
:402FC000704708B14FF0FF3000F008B80029F8D00246B0FBF1F000FB11217047704700BF014B1868704700BF6081FF1F0E4B70B51E460E4C0025E41AA410A54204D056F8C7
|
||||
:40300000253098470135F8E700F0DEFD084B094C1E46E41AA4100025A54204D056F8253098470135F8E770BDD43B0000D43B0000D43B0000DC3B000003460244934202D0A0
|
||||
:4030400003F8011BFAE7704730B5141E05469BB0184604DA8B232B604FF0FF301DE04FF40273ADF80C300CBF234604F1FF33029305934FF6FF7300910491ADF80E300246EB
|
||||
:403080001E9B6946284600F073F8431CBCBF8B232B6014B1009B00221A701BB030BD000007B5009313460A46014603480068FFF7CBFF03B05DF804FB6081FF1F2DE9F04703
|
||||
:4030C0008E6882469E420C46914698463ED88A8912F4906F3AD02568096902236F1A656905EB450595FBF3F57B1C43449D4238BF1D4653050FD5294600F04AFB064698B1FA
|
||||
:403100003A46216900F0D2FAA38923F4906343F08003A38113E02A4600F098FB064670B92169504600F0E8FA0C23CAF80030A3894FF0FF3043F04003A381BDE8F087266174
|
||||
:403140003E44266046466561ED1BA560464528BF464649463246206800F0B3FAA36800209B1BA36023681E442660BDE8F08700002DE9F04F9DB003938B8980461C060D46C4
|
||||
:4031800016460DD50B695BB9402100F001FB2860286118B90C23C8F80030CDE040236B610023099320238DF82930DFF89CB130238DF82A3037463C4614F8013B1BB9B7EB2C
|
||||
:4031C000060910D003E0252BF9D02746F3E74B46324629464046FFF771FF013000F0A780099B4B4409933B78002B00F0A08000234FF0FF3204930793059206938DF8533038
|
||||
:403200001A930126052221784E4800F041FA671C049B38B14B4A3C46801A06FA00F018430490EFE7D90644BF20228DF853201A0744BF2B228DF8532022782A2A03D0079AE1
|
||||
:4032400000210A200BE0039A111D12680391002A10DA524243F00200079204900BE027463B780134303B092B03D800FB02320121F5E701B107923B782E2B1ED17B782A2BC0
|
||||
:403280000AD1039B02371A1D1B680392002BB8BF4FF0FF33059310E0002319460593781C0A2407463A780130303A092A03D804FB01210123F5E703B1059103223978224843
|
||||
:4032C00000F0E6F940B14023CBEB000003FA00F0049B013718430490397806221B487E1C8DF8281000F0D4F988B1194B33B9039B073323F007030833039314E003AB00936E
|
||||
:403300002A46144B04A94046AFF3008007E003AB00932A460F4B04A9404600F093F8B0F1FF3F824603D0099B5344099342E7AB895B0601D4099801E04FF0FF301DB0BDE883
|
||||
:40334000F08F00BFA33B0000A93B0000AD3B000000000000BD3000002DE9F04791461F460A698B6806469342B8BF1346C9F8003091F843200C46DDF8208012B10133C9F83C
|
||||
:4033800000302368990642BFD9F800300233C9F80030256815F0060510D104F1190A07E00123524639463046C04701301AD00135E368D9F800209B1A9D42F1DB94F843306A
|
||||
:4033C0002268003318BF012392060FD5E118302081F843005A1C94F845102244023382F8431003E04FF0FF30BDE8F08704F1430239463046C0470130F4D02268D9F8005092
|
||||
:40340000E36802F00602042A08BF5D1B2269A3680CBF25EAE57500259342C4BF9B1AED184FF000091A344D4509D00123224639463046C0470130D5D009F10109F3E700207C
|
||||
:40344000BDE8F0872DE9F04317460A7E85B06E2A984606460C460C9B01F1430E00F0AE8011D8632A22D009D8002A00F0BB80582A40F0CA8081F84520834955E0642A1ED0BC
|
||||
:40348000692A1CD0C0E0732A00F0B08009D86F2A2ED0702A40F0B8800A6842F020020A603EE0752A24D0782A3AD0ADE01A6801F14205111D1960136884F84230A8E02168C0
|
||||
:4034C0001A6811F0800F02D0111D196008E011F0400F02F10401196002D0B2F9003000E01368002B3CDA2D225B4284F8432037E021681A6811F0800F02D0111D196007E072
|
||||
:4035000011F0400F02F10401196001D0138800E01368227E5C496F2A14BF0A2208221BE078225A4984F845202268186812F0800F00F104051D6003D1550601D5038800E061
|
||||
:403540000368D00744BF42F0200222601BB9226822F0200222601022002084F8430001E049490A226568002DA56008DB206820F0040020602BB9002D7DD175460CE0002B3D
|
||||
:4035800079D07546B3FBF2F002FB1033CB5C05F8013D03460028F5D1082A0BD12368DA0708D5236962689A42DEBF302305F8013C05F1FF35C5EB0E0323612EE008681A687C
|
||||
:4035C00010F0800F496903D0101D1860136808E010F0400F02F104001860136801D0198000E0196000232361754616E01A68111D1960156800216268284600F049F808B172
|
||||
:40360000401B6060636804E004F1420584F8422001232361002384F84330CDF800803B4603AA21463046FFF797FE013002D14FF0FF3026E023692A4639463046C047013070
|
||||
:40364000F5D023689B0710D5002504F1190907E001234A4639463046C0470130E7D00135E368039A9B1A9D42F2DBE068039B9842B8BF184605E00B7804F1420584F8423012
|
||||
:403680008AE705B0BDE8F083573A0000B43B000010B5C9B202449042034605D01C7801308C42F8D1184610BD002010BD10B5431E0A44914204D011F8014B03F8014FF8E7C8
|
||||
:4036C00010BD884210B501EB020301D8421E0BE09842FBD28118D21AD34204D013F8014D01F8014DF8E710BD994204D011F8014B02F8014FF8E710BD38B50546002944D089
|
||||
:4037000051F8043C0C1F002BB8BFE41800F0D4F81E4A1368114613B96360146030E0A3420DD92268A018834201BF18685B681218226063600C6023E0A24203D813465A68A1
|
||||
:40374000002AF9D118681918A1420BD12168014458188242196013D110685268014419605A600DE002D90C232B6009E021686018824201BF106852680918216062605C609A
|
||||
:403780002846BDE8384000F098B838BDA892FF1F70B5CD1C25F0030508350C2D38BF0C25002D064601DBA94202D90C23336046E000F082F8234B1C681A462146A1B10B683D
|
||||
:4037C0005B1B0ED40B2B03D90B60CC18CD501EE08C420BBF63684B681360636018BF0C4615E00C464968E9E7174C23681BB9304600F052F820602946304600F04DF8431C4D
|
||||
:4038000018D0C41C24F00304A0420DD12560304600F053F804F10B00231D20F00700C31A0ED05A42E25070BD211A304600F034F80130EBD10C233360304600F03EF800206A
|
||||
:4038400070BD00BFA892FF1FA492FF1FF8B5074615460E4621B91146BDE8F840FFF798BF1AB9FFF749FF2846F8BD00F027F885420ED929463846FFF78BFF044650B131468C
|
||||
:403880002A46FFF713FF31463846FFF735FF01E03046F8BD2046F8BD38B5064C0023054608462360FDF7D8FB431C02D1236803B12B6038BD8C93FF1F7047704751F8040C10
|
||||
:4038C0000028BEBF091851F8043CC0180438704700000000050209020B020D020F021102130215027265706C792030782530327800686F6D696E6700626567696E6E696E71
|
||||
:4039000067207365656B2066726F6D20256420746F2025640066696E6973686564207365656B00796573006E6F00647269766520303A20257320647269766520313A202589
|
||||
:40394000730057616974696E6720666F72205553422E2E2E0055534220726561647900636F6D6D616E6420307825303278006661696C2025642B25642B2564203D3D2025B5
|
||||
:40398000642C206E6F74202564007061737365643D256400756E64657272756E206166746572202564207061636B65747300636F756E743D256420693D256420643D256436
|
||||
:4039C00000636D645F777269746500703D25642063723D25642063773D256420663D256420773D256420696E6465783D256420756E64657272756E3D256400756E6465723A
|
||||
:403A000072756E2100737563636573730073746172742065726173696E670073746F702065726173696E670069646C65000051004010004051004030000000014000100080
|
||||
:403A4000140140000800400140000A004C0140000200500140200030313233343536373839414243444546000001000000040000001000010000000400000010280000002A
|
||||
:403A8000000104000100000000000000000157494E5553420000303030303100000000000000000012034D005300460054003100300030000100000001000000C03A00005A
|
||||
:403AC000010000008F3B0000000000000000000001000000D83A000001000000613B000004000000FA3A0000000000000000000000000000F83A0000FF000000010240009F
|
||||
:403B0000FF00000082024000FF00000003034000FF00000084034000FF00020304030904160346006C007500780045006E00670069006E0065002A0343006F0077006C00CF
|
||||
:403B4000610072006B00200054006500630068006E006F006C006F0067006900650073000009022E0001010080320904000004FF00000107050102400000070582024000E6
|
||||
:403B8000000705030340000A0705840340000A12010002FF0001080912006E0100020180014300232D302B2000686C4C00656667454647003031323334353637383961629F
|
||||
:403BC0006364656600000000F8B500BFF8BC08BC9E46704759000000D5100000F8B500BFF8BC08BC9E46704735000000003C0000C880FF1FA0000000281200000000000046
|
||||
:403C0000000000009093FF1FFF000000675000400C00000007000000FFFFFFFF7F8000003F0000000000C05D80BB000030000000006CDC02FF00000000000000000000002F
|
||||
:403C4000000000000000000000000000000000000000000000000000A13B000000000000000000000000000000000000000000000000000000000000000000000000000068
|
||||
:403C80000000000000000000000000000000000000000000000000000081FF1F00000000000000000000000000000000000000000000000000000000000000000000000065
|
||||
:403CC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C4
|
||||
:403D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083
|
||||
:403D40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043
|
||||
@@ -4098,52 +4098,52 @@
|
||||
:40FF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041
|
||||
:40FFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
||||
:0200000480007A
|
||||
:400000000145004009520040015B0040016500400101014003030140010501400307014052080140500901404F0A0140480B0140490C0140470D0140400E0140360F01409E
|
||||
:4000400002150140031701405C18014057190140471A0140531B01400B400140124101400B4201400D43014002440140074501400B4601400C470140104801401149014069
|
||||
:40008000154C01400D4D014005500140045101407E02080209411080110218041902600C61157C402721290AE204E601EA20EE02E202E608EA10EE04000801080404050568
|
||||
:4000C0000708080809080C400D080E1011011201130E143A16401708180819081C021E042305240825042701280629082A782C202D012E402F02307F310F327F330F380AE4
|
||||
:400100003B0A580459045B045C995F018203830187018A108C018D018E248F08907C9282930E961097019A809D019E1C9F04A101A210A302A510A610AA10AB01AC01AE48FD
|
||||
:40014000B01FB10FB4F0B510BA20BB02BF10D608D80BD90BDB04DC99DD90DF01012202010488051007800A860B100C020DA00E2011011208134414021504162017201804BE
|
||||
:4001800019021A041B011CA01E202008220126012790282029202A012C022E282F4032493514360139013B443C803D2A5980614069906F0278417B0288049141928093D450
|
||||
:4001C00094249602970A982299249A019B409C019D019EC0A188A208A402A504A709B404B502B604C0FBC2FFC4EFCAF7CCEBCEFBD608D808DE01E608EA10EE0400FC0108A1
|
||||
:4002000002020310071408200AD00BE40CE10D100E080F8212031314161017141D1F1E101F4020802110223C2321261028402A302B142CE12E04301F310F33F034E03B08A2
|
||||
:40024000580B590B5B045C995F0180368209852A86128740882D89098A128B148E098F209080924093C09440968098079C249D089F13A03FA180A320A840A908ADEAB0076D
|
||||
:40028000B1E0B280B301B438B518B640B706BE44D808D904DB04DC99DF0100820120040A07050A420B100EA80F01110112091304171219201A401D8A1E081F4020602101B0
|
||||
:4002C000231025102652275029202A012C022F483249364239033B543D283E806102620169406C0C6F0178017F0187058C028D04900292809345946495029642971298206E
|
||||
:4003000099049B069C019D219E449F01A041A208A418A701B040B204B7C0C0FBC2FDC45FCAB5CC9BCE7FDE11E40800020104040806140A010C1C101012081301140215050D
|
||||
:400340001601170220032B022D062E022F0130043107320336183A083F015608580459045B045C095D905F018128829083118401853F86448A9C8C208D3F8EC090C191FFA2
|
||||
:40038000922895149690972199019A039B0E9D409E90A0FCA202A902AA90AB01ADC0AE90B140B330B41FB50FB6E0B780BA80D608D80BD90BDB04DC99DD90DF0101A604240E
|
||||
:4003C0000501070208400A240B400EA0120113121401164019801A041B401D841EA02080229C2344260129602C082F0230023294370539063A053B403F01580259025A0213
|
||||
:400400005B405F806140670168036A806B026C016F06780182019440950296E4974698209C429D209E049F02A412A580A741B240B420B540C0FFC23FC49BCA3CCCCFCE8BAA
|
||||
:40044000D618D818DE01EA20EE0203900401060407900A100B9C0D010E100F4812101520161017C01A031B031DFC1E1C1F02201C2202239025C127242A102B902C012E08A9
|
||||
:400480002F9033E0341F351F3B08420147E0482049FF4AFF4BFF4F83580859085A045B045C995D095F018310871C8B108D018F0893109F03A310A501A704AB10AD1CAF0254
|
||||
:4004C000B71FD908DB04DC90DF0100400120032008420A281110134219101A0820042120220826802701284229202A042B202C422D202F20312032483402368039123B4544
|
||||
:400500003C203D103F454180520159105A445B0160046208638269406E8078807C807F018201C007C20FC40BCAFFCC9ECEFFD008D60FD80FDE18EA01EE08E020E623EE0BF2
|
||||
:40054000022005880612083209880C080E010F011049118812321432151017A0182119461A1C1BB81D9A1E091F20206321422204230424322588282029882A022C322D04B6
|
||||
:400580003020313F324033C1341F37C1398A3A203E055608580459045B045C995D905F018401860289018D028E039002920199089B049D049F08A004B002B102B204B304D8
|
||||
:4005C000B401B501B708B822B988BE15BF55C043C520C802C9FFCAFFCBFFCD20CEF0D110D804D904DA04DB04DD09DF01E108E240E340E480E640E740000801400320051496
|
||||
:40060000060107400A800D800EA8108016441799181019021B101C401E081F0420012111220424A02505264227A02D202F52324033203504360137A039903C243E4040504B
|
||||
:40064000488049204A0459405A205D045E085F4064016580670268046A806C036E406F01831085118B4491D0938094A89504970A984099449B509C019D119EC89F20A0500A
|
||||
:40068000A188A211A402A535A708A980C0F5C2F8C4F8CAF0CCFCCE7CD003D61CD810E022E620EA04EE0B010129022C013102350136013E403F115608580459045B045D9048
|
||||
:4006C0005F0180478208830885218626874E880189018A388B708D4E8E40914E92029426974E98269B029D809E11A010A201A321A520A604A701A811AA26AB04AC26AD0FF1
|
||||
:40070000AF10B040B380B43FB57FB63FBAA0BB20BF04C003C50EC70CC811C9FFCAFFCBFFD004D601D804D904DA04DB04DC99DD09DF01E2C0040205940DA20E201002150580
|
||||
:40074000162017A01B401D111E011F102040221024042530260827082B042E642F40344035043602371038013C803D283E0145084F04570858905C406001630868026C042B
|
||||
:400780006D016E046F02768981028410860888808D028E049002910492409380940C96209724984099869A049BB09D119E899F08A040A18CA212A530A74AA881AE04B74049
|
||||
:4007C000C0F0C2F0C4F1CAF4CCF0CEF1D040D61CD80CE008E404E602E8041B011F083180330836843B408340C630CCF0CE10E22032043380364037023B043F808180A0042B
|
||||
:40080000A340A580A604AE80AF41B004CCF0CE60E680EE40531057208510960897049F02A004A644A780D460E240860491209608972498809F02A004A640A7A0AA04B48062
|
||||
:40084000E610EE201680C40458405E019A80A404AC04D401D6011B04844096019C40A404A710B680B710C608EA08EE0808080B080E020F4087048A209601A404A710AB043D
|
||||
:40088000C20FE00425808004871089808B04912097249880A004A720AB02AE40AF80C820E6C0EED0511054045880700477809008912098809B80A004AB80AF20D4E0DC8000
|
||||
:4008C000DE20EA80EE1005200A400C100F201C0852225620610186029641A220A404A710AA41AC08AF40C001C20DC601D407D80270018001852086018810960198109920A0
|
||||
:40090000AA20B501DC01E204EC0201010D010F0111011D0100FF01AB02021105BF0000A09F001F000000000000000000100000004000000000000000C0000000FF0000B88D
|
||||
:4009400047004700000100008000000282008200000000000007070007000000270018012700180100040000000500000000000000000000000000000000000000000000C4
|
||||
:400980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037
|
||||
:4009C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F7
|
||||
:400A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B6
|
||||
:400A40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076
|
||||
:400A80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036
|
||||
:400AC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F6
|
||||
:400B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B5
|
||||
:400B40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000075
|
||||
:400000000145004009520040015B0040016400400301014002030140080501400C0701405A0801404F0901405E0A0140480B0140510C0140490D01404F0E01403E0F014057
|
||||
:40004000261401403215014028160140371701405B1801404A190140521A0140561B01400C4001400D4101400B4201400E4301400244014007450140094601400E47014042
|
||||
:400080000D4801400F490140194C01400D4D014006500140045101407E02084409021080110218011904601361197C4027212A0A8840E204E620A440EE028602980CA44036
|
||||
:4000C000A808AC04E282EA08EE04870289028A048F10980C9940A202A440AD40E64AEA01EE0C02080301041706E80701080809020A400C800D030E08100F11021408150176
|
||||
:4001000016201702181019021A071C081EF01F0220012204230224012502260628012A022B012CFF2D0330FF35033E013F105608580459045B045D905F01808081748301C8
|
||||
:400140008480867E8752884089528A108C408D528E20907E910793089524975B983E9A409B049C409D329E049FC0A040A152A202A440A552A608A87EA952AD20AE01AF8055
|
||||
:40018000B103B31CB6FFB7E0BB88BE40D804D904DB04DC90DF010008011002800301051007620A050B400D200E020F501080114412091554170119801E8020402101228854
|
||||
:4001C00023612704284029942D512F103001312032883510368939023B943C083E013F505C80640268016A406D806F08840288019140928293809408950A964097159801FC
|
||||
:400200009B089C229D159E069F20A004A128A201A401A540A648A708AC80C0FFC2FBC4FFCAFFCCFFCEFFD610D810E280E608E808EA01EE0C002001110250050106100901A8
|
||||
:400240000A030B1E0D110E1C107C110D120213221440151116301D041E1020802461260428612A082E103060310332803330341F350437083E043F1040234520480249FF27
|
||||
:400280004AFF4BFF4D204EF05110580B59045A045C995D095F0161086240634064806640674081408201840188078B128C078D368E088F0992109309940799249A069C019B
|
||||
:4002C0009D079E02A006A209A401A604A801A92DAA06AB12AC0FAD3FB140B401B507B61EB738BE10BF01D804D90BDB04DC99DF0100800122032005550A410B200E800F1598
|
||||
:400300001080112012221401154A172019221A101D401E061F40201821AA22012308244026A027042E402F0831823208342036803701381839423D903E02421448805C40CC
|
||||
:400340006D106F0178027C028701891091409281932096409C029D229E049F04A040A110A202A320A401A940AF48B340C0FFC2FDC4FFCA30CCBBCEBFD006D610DE81E2802C
|
||||
:40038000007C0160028206100710080109400A240D7C0E030F02121013031501161C1704180119011A481B081E101F1022102310268027102B102E102F1C301F311F3320DC
|
||||
:4003C000354036F03A805608580B590B5B045C995D905F01800482118314851086E08782881F89088A208B108D1F8F40901F9240951097219B149C019E1E9F14A3E4A41F55
|
||||
:40040000A680A808AA11AC02AE11AF14B1F0B30FB4F0B60FBA20BB02D80BD90BDB04DC99DF010102024003240444068007240A410C800D220F201222131014011502170861
|
||||
:4004400019C01A031B301C401F412080210223B024182530262128402A402C812D822E102F2031403324344036213784380839023A803B303C143EC03F015F40670169402A
|
||||
:4004800078027C0291029290960297129C029D629E049F04A202A441A522A621A730AA12C0FEC2F9C4B7CAF9CCFECEFFD610D810DE81EE02001C010102020306061008010D
|
||||
:4004C00009040A040B010E0312101507180119071A081E102102221023012A1C2D072E10301F3107580B590B5B045C995F0181E782908310878488208AC08B188E908F84EC
|
||||
:40050000929093849508969097229801990E9A489B419D019E039F06A29CA3E4A4C1A624A784AA90AB84ACFCAE02B21FB4E0B5F8B707BA20BB80C202C60EC804C9FFCAFF6A
|
||||
:40054000CBFFCF83D80BD90BDA04DB04DC99DD09DF01004203640552070109220A020D620F201080120213101522174418401D181F10210122022550269029022B012C803A
|
||||
:400580002D022E102F203120330436A0370539223B103C8A3D203F0245484605470848044B1057405C405E225F086520660167226A8078027C0283408D48C0DFC2FBC4FBE9
|
||||
:4005C000CAE9CCF6CEF5D020D6F0D8F0DE810A010C01130115012301260134013501382039203E103F105608580459045B045D905F018C029001930195019C04A602A902A1
|
||||
:40060000B002B204B301B401B702B802B908BE15BF44D804D904DB04DF01030507010E400F011308170418041E281F022304268027102B402F08330537055B405D805E2030
|
||||
:40064000614065C06B056E406F0883488B068C048E808F4093019F10A604A844AA10AF50B001B220B404C083C290C424CA21CCC3D638D808E204E6A0E811EA08EE035608FE
|
||||
:400680005B045D9080018505870289088D068F019002930194049510972098089B029D04A130A204A520A710A908AA08AD08B002B107B208B330B404B508B601BE41BF11A1
|
||||
:4006C000D608D804D904DB04DC99DD90DF01000208080A080B8010041302188419081A012080210822202809290A3004329238083A803B2059605F406110628067016801DA
|
||||
:4007000081088204868087408A018D209208980C99429A809B029D109F10A202A440A910B280C008C20EC40ACA0FCC0FCE0ED61CD81CE001E408E662EC04EE0A00100260BB
|
||||
:4007400003010453070209020A080B200C010D030F0410401210130115081604170119091A531BF21C011D801E021F022053210223102401250226022740280129022BFC12
|
||||
:400780002C132DFF2E203070320F340F35FF360F3A023F10580459045B045C095F018020840185028602870188208C028D018E01902094F89604970198109A039C049D0478
|
||||
:4007C0009E40A020A10BA480A508A604A813A902AAE4AC07AE08AF02B104B2FFB308B503B703BBA0BE04BF01D804D904DB04DC90DF01002A03010501072509200B920D227D
|
||||
:400800000E211365155619081C021D051F1420102180228223162610280229082A212C042D402F64324835203680372938403B043E093F506A406F027D017E808204842025
|
||||
:4008400088208E4290409142928293C19408951D9605973498029A019B2C9CE09D159E049F03A128A209A308A480AA02B140B504B740C0FFC2FFC4FFCAFFCCFACEFAE210B7
|
||||
:40088000E480E662EE2A0001011F02080401050106400704080109010A200B080C010D1F0E021001121013401401154016FE18041B1F1C801D011E011F0221012201231E7A
|
||||
:4008C00027202804291F2AF92CFF2D012F1032FF333F35403E043F10400246E0470C481849FF4AFF4BFF50045601580459045A045B045C905D095F0162C08040843286C42E
|
||||
:4009000088408C068E08922294F8960498809A049C40A040A410A602A840AE01B0FFB4FFB822D804DB04DC09DF010052032004500640072009A00B900E620F04114012402C
|
||||
:40094000132114441540170819081D101F21202421042204231029282A82312832013340351036103956400442804301502466086710680469146A416B416F02708071025A
|
||||
:40098000720683028440860490509142920293859408951C96059702980499209B289C409D109E089F01A001A1A8A201A4B4A502A720AB08AF42B320B480B620C0FFC2FFD1
|
||||
:4009C000C4FBCA0FCC0FCE0FD004E040E210E440E831EC40EE201B011F083020330836843B4083408820C630CCF0CE10E22032043380364037043B043F80A340A604AE80F7
|
||||
:400A0000AF41CCF0CE60EE405010570484408A80960897049F04A644A780D460E24086048C10942096089704A040A280A640A784AA04AB04E610EA80EE201420C40458108D
|
||||
:400A40005E019820A404AC04D401D6011B049502960198209C10A404B101C608EA0408080B080F41870495029601970199809C10A404AB05AC20AD80C20F240883048B04A7
|
||||
:400A80008E409704A040A280A704AE40AF80C820E620EE50528054405A40722076808AA09240A040A280AA80B404D4E0DC80DE20EC20070208020D811C085320568059806E
|
||||
:400AC0005F0185808A018F039502960199809C10A404AC08AF40C001C20DC601D407D601E208E40975018C028D018F209802A720AA80B010DE04E002E208E402E804010148
|
||||
:400B00000D010F0111011B011D0100FF01AB020211050000BF0000A09F001F000000000000000000100000004000000000000000C0000000FF0000B8470047000001000013
|
||||
:400B400080000002820082000000000000070700070000001D0018011D00180100040000000500000000000000000000000000000000000000000000000000000000000065
|
||||
:400B80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035
|
||||
:400BC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F5
|
||||
:400C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B4
|
||||
@@ -4615,12 +4615,12 @@
|
||||
:0200000490105A
|
||||
:04000000BC90ACAF55
|
||||
:0200000490303A
|
||||
:02000000CEC56B
|
||||
:0200000064D4C6
|
||||
:0200000490402A
|
||||
:4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0
|
||||
:400040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080
|
||||
:400080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040
|
||||
:4000C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
:0200000490501A
|
||||
:0C00000000012E16106900002E2FDF2ECC
|
||||
:0C00000000012E16106900002E30753D26
|
||||
:00000001FF
|
||||
@@ -272,7 +272,7 @@
|
||||
<Data key="derive_type" value="AUTO" />
|
||||
<Data key="desired_freq" value="1600000" />
|
||||
<Data key="desired_unit" value="0" />
|
||||
<Data key="divider" value="40" />
|
||||
<Data key="divider" value="30" />
|
||||
<Data key="domain" value="DIGITAL" />
|
||||
<Data key="enabled" value="True" />
|
||||
<Data key="minus_accuracy" value="0.25" />
|
||||
@@ -390,7 +390,7 @@
|
||||
<Data key="derive_type" value="AUTO" />
|
||||
<Data key="desired_freq" value="1600000" />
|
||||
<Data key="desired_unit" value="0" />
|
||||
<Data key="divider" value="40" />
|
||||
<Data key="divider" value="30" />
|
||||
<Data key="domain" value="DIGITAL" />
|
||||
<Data key="enabled" value="True" />
|
||||
<Data key="minus_accuracy" value="0.25" />
|
||||
@@ -604,7 +604,7 @@
|
||||
<Data key="check_tolerance" value="True" />
|
||||
<Data key="clock_version" value="v1" />
|
||||
<Data key="derive_type" value="BUILTIN" />
|
||||
<Data key="desired_freq" value="64" />
|
||||
<Data key="desired_freq" value="48" />
|
||||
<Data key="desired_unit" value="6" />
|
||||
<Data key="divider" value="0" />
|
||||
<Data key="domain" value="0" />
|
||||
@@ -814,7 +814,7 @@
|
||||
</Group>
|
||||
<Group key="Component">
|
||||
<Group key="v1">
|
||||
<Data key="cy_boot" value="cy_boot_v5_81" />
|
||||
<Data key="cy_boot" value="cy_boot_v6_10" />
|
||||
<Data key="Em_EEPROM_Dynamic" value="Em_EEPROM_Dynamic_v2_20" />
|
||||
<Data key="LIN_Dynamic" value="LIN_Dynamic_v5_0" />
|
||||
</Group>
|
||||
@@ -4214,7 +4214,7 @@
|
||||
</Group>
|
||||
<Group key="System3">
|
||||
<Data key="CYDEV_CONFIG_FASTBOOT_ENABLED" value="True" />
|
||||
<Data key="CYDEV_CONFIG_UNUSED_IO" value="AllowButWarn" />
|
||||
<Data key="CYDEV_CONFIG_UNUSED_IO" value="Disallowed" />
|
||||
<Data key="CYDEV_CONFIGURATION_ECC" value="True" />
|
||||
<Data key="CYDEV_CONFIGURATION_MODE" value="COMPRESSED" />
|
||||
<Data key="CYDEV_DEBUGGING_DPS" value="Disable" />
|
||||
|
||||
@@ -2913,6 +2913,110 @@
|
||||
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>
|
||||
<filters />
|
||||
</CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0>
|
||||
<CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFolderSerialize" version="3">
|
||||
<CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtBaseContainerSerialize" version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="Clock_2" persistent="">
|
||||
<Hidden v="True" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<CyGuid_0820c2e7-528d-4137-9a08-97257b946089 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemListSerialize" version="2">
|
||||
<dependencies>
|
||||
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="Clock_2.c" persistent="Generated_Source\PSoC5\Clock_2.c">
|
||||
<Hidden v="True" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<build_action v="SOURCE_C;CortexM3;;;" />
|
||||
<PropertyDeltas />
|
||||
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
|
||||
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="Clock_2.h" persistent="Generated_Source\PSoC5\Clock_2.h">
|
||||
<Hidden v="True" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<build_action v="HEADER;;;;" />
|
||||
<PropertyDeltas />
|
||||
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
|
||||
</dependencies>
|
||||
</CyGuid_0820c2e7-528d-4137-9a08-97257b946089>
|
||||
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>
|
||||
<filters />
|
||||
</CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0>
|
||||
<CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFolderSerialize" version="3">
|
||||
<CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtBaseContainerSerialize" version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="Clock_3" persistent="">
|
||||
<Hidden v="True" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<CyGuid_0820c2e7-528d-4137-9a08-97257b946089 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemListSerialize" version="2">
|
||||
<dependencies>
|
||||
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="Clock_3.c" persistent="Generated_Source\PSoC5\Clock_3.c">
|
||||
<Hidden v="True" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<build_action v="SOURCE_C;CortexM3;;;" />
|
||||
<PropertyDeltas />
|
||||
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
|
||||
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="Clock_3.h" persistent="Generated_Source\PSoC5\Clock_3.h">
|
||||
<Hidden v="True" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<build_action v="HEADER;;;;" />
|
||||
<PropertyDeltas />
|
||||
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
|
||||
</dependencies>
|
||||
</CyGuid_0820c2e7-528d-4137-9a08-97257b946089>
|
||||
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>
|
||||
<filters />
|
||||
</CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0>
|
||||
<CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFolderSerialize" version="3">
|
||||
<CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtBaseContainerSerialize" version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="Clock_5" persistent="">
|
||||
<Hidden v="True" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<CyGuid_0820c2e7-528d-4137-9a08-97257b946089 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemListSerialize" version="2">
|
||||
<dependencies>
|
||||
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="Clock_5.c" persistent="Generated_Source\PSoC5\Clock_5.c">
|
||||
<Hidden v="True" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<build_action v="SOURCE_C;CortexM3;;;" />
|
||||
<PropertyDeltas />
|
||||
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
|
||||
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="Clock_5.h" persistent="Generated_Source\PSoC5\Clock_5.h">
|
||||
<Hidden v="True" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<build_action v="HEADER;;;;" />
|
||||
<PropertyDeltas />
|
||||
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
|
||||
</dependencies>
|
||||
</CyGuid_0820c2e7-528d-4137-9a08-97257b946089>
|
||||
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>
|
||||
<filters />
|
||||
</CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0>
|
||||
<CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFolderSerialize" version="3">
|
||||
<CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtBaseContainerSerialize" version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="USBFS_ep5" persistent="">
|
||||
<Hidden v="True" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<CyGuid_0820c2e7-528d-4137-9a08-97257b946089 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemListSerialize" version="2">
|
||||
<dependencies>
|
||||
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="USBFS_ep5_dma.c" persistent="Generated_Source\PSoC5\USBFS_ep5_dma.c">
|
||||
<Hidden v="True" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<build_action v="SOURCE_C;CortexM3;;;" />
|
||||
<PropertyDeltas />
|
||||
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
|
||||
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
|
||||
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="USBFS_ep5_dma.h" persistent="Generated_Source\PSoC5\USBFS_ep5_dma.h">
|
||||
<Hidden v="True" />
|
||||
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
|
||||
<build_action v="HEADER;;;;" />
|
||||
<PropertyDeltas />
|
||||
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
|
||||
</dependencies>
|
||||
</CyGuid_0820c2e7-528d-4137-9a08-97257b946089>
|
||||
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>
|
||||
<filters />
|
||||
</CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0>
|
||||
</dependencies>
|
||||
</CyGuid_0820c2e7-528d-4137-9a08-97257b946089>
|
||||
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>
|
||||
@@ -3480,8 +3584,8 @@
|
||||
</platforms>
|
||||
<project_current_platform v="c9323d49-d323-40b8-9b59-cc008d68a989" />
|
||||
<last_selected_tab v="Cypress" />
|
||||
<WriteAppVersionLastSavedWith v="4.2.0.641" />
|
||||
<WriteAppMarketingVersionLastSavedWith v=" 4.2" />
|
||||
<WriteAppVersionLastSavedWith v="4.4.0.80" />
|
||||
<WriteAppMarketingVersionLastSavedWith v=" 4.4" />
|
||||
<project_id v="ff3eb327-f593-4eb3-a00f-72497469e963" />
|
||||
<GenerateDescriptionFiles v="False" />
|
||||
</CyGuid_49cfd574-032a-4a64-b7be-d4eeeaf25e43>
|
||||
@@ -3493,9 +3597,7 @@
|
||||
<library_dep persistent="${CyRoot}\psoc\content\default\CyAnnotationLibrary\CyAnnotationLibrary.cylib\CyAnnotationLibrary.cyprj" />
|
||||
</library_deps>
|
||||
<CyGuid_b0d670ad-d48f-47cb-9d0b-b1642bab195c type_name="CyDesigner.Common.Base.CyExprTypeMgr" version="1" />
|
||||
<ignored_deps>
|
||||
<library_dep persistent="C:\Users\dg\Documents\PSoC Creator\4.1\Downloads ( 4.1).cylib\Downloads ( 4.1).cyprj" />
|
||||
</ignored_deps>
|
||||
<ignored_deps />
|
||||
</CyGuid_495451fe-d201-4d01-b22d-5d3f5609ac37>
|
||||
<boot_component v="" />
|
||||
<current_generation v="150" />
|
||||
|
||||
@@ -20,13 +20,14 @@ module Sequencer (
|
||||
|
||||
localparam STATE_LOAD = 0;
|
||||
localparam STATE_WRITING = 1;
|
||||
localparam STATE_WAITING = 2;
|
||||
|
||||
reg state;
|
||||
reg [1:0] state;
|
||||
reg [5:0] countdown;
|
||||
reg pulsepending;
|
||||
|
||||
assign req = (!reset && (state == STATE_LOAD));
|
||||
assign wdata = (!reset && (state == STATE_WRITING) && (countdown == 0) && pulsepending);
|
||||
assign wdata = (!reset && (state == STATE_WAITING) && (countdown == 0) && pulsepending);
|
||||
assign debug_state = 0;
|
||||
|
||||
reg olddataclock;
|
||||
@@ -37,11 +38,6 @@ assign dataclocked = !olddataclock && dataclock;
|
||||
reg oldsampleclock;
|
||||
reg sampleclocked;
|
||||
|
||||
reg oldindex;
|
||||
wire indexed;
|
||||
always @(posedge clock) oldindex <= index;
|
||||
assign indexed = !oldindex && index;
|
||||
|
||||
always @(posedge clock)
|
||||
begin
|
||||
if (reset)
|
||||
@@ -65,7 +61,7 @@ begin
|
||||
if (dataclocked)
|
||||
begin
|
||||
pulsepending <= opcode[7];
|
||||
countdown <= opcode[5:0];
|
||||
countdown <= opcode[5:0] - 1; /* compensate for extra tick in state machine */
|
||||
|
||||
state <= STATE_WRITING;
|
||||
end
|
||||
@@ -76,12 +72,15 @@ begin
|
||||
if (sampleclocked)
|
||||
begin
|
||||
if (countdown == 0)
|
||||
state <= STATE_LOAD;
|
||||
state <= STATE_WAITING;
|
||||
else
|
||||
countdown <= countdown - 1;
|
||||
sampleclocked <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_WAITING:
|
||||
state <= STATE_LOAD;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
Binary file not shown.
@@ -79,6 +79,7 @@ CY_ISR(index_irq_cb)
|
||||
* the track. */
|
||||
static bool hardsec_index_irq_primed = false;
|
||||
static uint32_t hardsec_last_pulse_time = 0;
|
||||
uint32_t index_pulse_duration = clock - hardsec_last_pulse_time;
|
||||
|
||||
if (!hardsec_index_threshold)
|
||||
{
|
||||
@@ -87,12 +88,18 @@ CY_ISR(index_irq_cb)
|
||||
}
|
||||
else
|
||||
{
|
||||
index_irq = hardsec_index_irq_primed;
|
||||
/* It's only an index pulse if the previous pulse is less than
|
||||
* the threshold.
|
||||
*/
|
||||
index_irq = (index_pulse_duration <= hardsec_index_threshold) ?
|
||||
hardsec_index_irq_primed : false;
|
||||
|
||||
if (index_irq)
|
||||
hardsec_index_irq_primed = false;
|
||||
else
|
||||
hardsec_index_irq_primed =
|
||||
clock - hardsec_last_pulse_time <= hardsec_index_threshold;
|
||||
index_pulse_duration <= hardsec_index_threshold;
|
||||
|
||||
hardsec_last_pulse_time = clock;
|
||||
}
|
||||
|
||||
@@ -275,7 +282,6 @@ static void seek_to(int track)
|
||||
CyWdtClear();
|
||||
}
|
||||
CyDelay(STEP_SETTLING_TIME);
|
||||
|
||||
TK43_REG_Write(track < 43); /* high if 0..42, low if 43 or up */
|
||||
print("finished seek");
|
||||
}
|
||||
@@ -305,7 +311,7 @@ static void cmd_measure_speed(struct measurespeed_frame* f)
|
||||
while (!index_irq)
|
||||
{
|
||||
elapsed = clock - start_clock;
|
||||
if (elapsed > 1000)
|
||||
if (elapsed > 1500)
|
||||
{
|
||||
elapsed = 0;
|
||||
break;
|
||||
@@ -416,7 +422,6 @@ static void cmd_read(struct read_frame* f)
|
||||
seek_to(current_track);
|
||||
SIDE_REG_Write(f->side);
|
||||
STEP_REG_Write(f->side); /* for drives which multiplex SIDE and DIR */
|
||||
|
||||
/* Do slow setup *before* we go into the real-time bit. */
|
||||
|
||||
{
|
||||
@@ -562,7 +567,6 @@ static void cmd_write(struct write_frame* f)
|
||||
seek_to(current_track);
|
||||
SIDE_REG_Write(f->side);
|
||||
STEP_REG_Write(f->side); /* for drives which multiplex SIDE and DIR */
|
||||
|
||||
SEQUENCER_CONTROL_Write(1); /* put the sequencer into reset */
|
||||
{
|
||||
uint8_t i = CyEnterCriticalSection();
|
||||
@@ -627,7 +631,6 @@ static void cmd_write(struct write_frame* f)
|
||||
|
||||
/* Wait for the index marker. While this happens, the DMA engine
|
||||
* will prime the FIFO. */
|
||||
|
||||
hardsec_index_threshold = f->hardsec_threshold_ms;
|
||||
index_irq = false;
|
||||
while (!index_irq)
|
||||
@@ -693,7 +696,7 @@ abort:
|
||||
static void cmd_erase(struct erase_frame* f)
|
||||
{
|
||||
SIDE_REG_Write(f->side);
|
||||
seek_to(current_track);
|
||||
seek_to(current_track);
|
||||
/* Disk is now spinning. */
|
||||
|
||||
print("start erasing");
|
||||
|
||||
30
Makefile
30
Makefile
@@ -1,21 +1,23 @@
|
||||
PACKAGES = zlib sqlite3 libusb-1.0
|
||||
PACKAGES = zlib sqlite3 libusb-1.0 protobuf
|
||||
|
||||
export CFLAGS = --std=c++14 -ffunction-sections -fdata-sections
|
||||
export LDFLAGS =
|
||||
export CFLAGS = -x c++ --std=c++14 -ffunction-sections -fdata-sections
|
||||
export LDFLAGS = -pthread
|
||||
|
||||
export COPTFLAGS = -Os
|
||||
export LDOPTFLAGS = -Os -s
|
||||
export LDOPTFLAGS = -Os
|
||||
|
||||
export CDBGFLAGS = -O0 -g
|
||||
export LDDBGFLAGS = -O0 -g
|
||||
|
||||
ifeq ($(OS), Windows_NT)
|
||||
export PROTOC = /mingw32/bin/protoc
|
||||
export CXX = /mingw32/bin/g++
|
||||
export AR = /mingw32/bin/ar rcs
|
||||
export AR = /mingw32/bin/ar rc
|
||||
export RANLIB = /mingw32/bin/ranlib
|
||||
export STRIP = /mingw32/bin/strip
|
||||
export CFLAGS += -I/mingw32/include/libusb-1.0
|
||||
export CFLAGS += -I/mingw32/include/libusb-1.0 -I/mingw32/include
|
||||
export LDFLAGS +=
|
||||
export LIBS = -static -lz -lsqlite3 -lusb-1.0
|
||||
export LIBS += -L/mingw32/lib -static -lz -lsqlite3 -lusb-1.0 -lprotobuf
|
||||
export EXTENSION = .exe
|
||||
else
|
||||
|
||||
@@ -25,21 +27,31 @@ $(warning These pkg-config packages are installed: $(shell pkg-config --list-all
|
||||
$(error You must have these pkg-config packages installed: $(PACKAGES))
|
||||
endif
|
||||
|
||||
export PROTOC = protoc
|
||||
export CXX = g++
|
||||
export AR = ar rcs
|
||||
export AR = ar rc
|
||||
export RANLIB = ranlib
|
||||
export STRIP = strip
|
||||
export CFLAGS += $(shell pkg-config --cflags $(PACKAGES))
|
||||
export LDFLAGS +=
|
||||
export LIBS = $(shell pkg-config --libs $(PACKAGES))
|
||||
export LIBS += $(shell pkg-config --libs $(PACKAGES))
|
||||
export EXTENSION =
|
||||
|
||||
ifeq ($(shell uname),Darwin)
|
||||
AR = ar rcS
|
||||
RANLIB += -c -no_warning_for_no_symbols
|
||||
endif
|
||||
|
||||
endif
|
||||
export XXD = xxd
|
||||
|
||||
CFLAGS += -Ilib -Idep/fmt -Iarch
|
||||
|
||||
export OBJDIR = .obj
|
||||
|
||||
all: .obj/build.ninja
|
||||
@ninja -f .obj/build.ninja
|
||||
@if command -v cscope > /dev/null; then cscope -bRq; fi
|
||||
|
||||
clean:
|
||||
@echo CLEAN
|
||||
|
||||
39
README.md
39
README.md
@@ -4,6 +4,11 @@ FluxEngine
|
||||
(If you're reading this on GitHub, the formatting's a bit messed up. [Try the
|
||||
version on cowlark.com instead.](http://cowlark.com/fluxengine/)
|
||||
|
||||
**Breaking news!** As of 2021-05-21, the command line environment has changed
|
||||
_substantially_ (to make it more consistent and flexible, and allow some new
|
||||
backend features like multi-format IBM scheme disks, which are popular with
|
||||
CP/M). If things don't work the way you expect, please check the documentation.
|
||||
|
||||
What?
|
||||
-----
|
||||
|
||||
@@ -85,20 +90,20 @@ people who've had it work).
|
||||
|
||||
### Old disk formats
|
||||
|
||||
| Format | Read? | Write? | Notes |
|
||||
|:-----------------------------------------|:-----:|:------:|-------|
|
||||
| [IBM PC compatible](doc/disk-ibm.md) | 🦄 | 🦄 | and compatibles (like the Atari ST) |
|
||||
| [Acorn ADFS](doc/disk-acornadfs.md) | 🦄 | 🦖* | single- and double- sided |
|
||||
| [Acorn DFS](doc/disk-acorndfs.md) | 🦄 | 🦖* | |
|
||||
| [Ampro Little Board](doc/disk-ampro.md) | 🦖 | 🦖* | |
|
||||
| [Apple II DOS 3.3](doc/disk-apple2.md) | 🦄 | | doesn't do logical sector remapping |
|
||||
| [Amiga](doc/disk-amiga.md) | 🦄 | | |
|
||||
| [Commodore 64 1541](doc/disk-c64.md) | 🦖 | | and probably the other GCR formats |
|
||||
| [Brother 120kB](doc/disk-brother.md) | 🦄 | | |
|
||||
| [Brother 240kB](doc/disk-brother.md) | 🦄 | 🦄 | |
|
||||
| [Brother FB-100](doc/disk-fb100.md) | 🦖 | | Tandy Model 100, Husky Hunter, knitting machines |
|
||||
| [Macintosh 800kB](doc/disk-macintosh.md) | 🦄 | 🦄 | and probably the 400kB too |
|
||||
| [TRS-80](doc/disk-trs80.md) | 🦖 | 🦖* | a minor variation of the IBM scheme |
|
||||
| Format | Read? | Write? | Notes |
|
||||
|:------------------------------------------|:-----:|:------:|-------|
|
||||
| [IBM PC compatible](doc/disk-ibm.md) | 🦄 | 🦄 | and compatibles (like the Atari ST) |
|
||||
| [Acorn ADFS](doc/disk-acornadfs.md) | 🦄 | 🦖* | single- and double- sided |
|
||||
| [Acorn DFS](doc/disk-acorndfs.md) | 🦄 | 🦖* | |
|
||||
| [Ampro Little Board](doc/disk-ampro.md) | 🦖 | 🦖* | |
|
||||
| [Apple II DOS 3.3](doc/disk-apple2.md) | 🦄 | | doesn't do logical sector remapping |
|
||||
| [Amiga](doc/disk-amiga.md) | 🦄 | 🦄 | |
|
||||
| [Commodore 64 1541/1581](doc/disk-c64.md) | 🦄 | 🦄 | and probably the other formats |
|
||||
| [Brother 120kB](doc/disk-brother.md) | 🦄 | 🦖 | |
|
||||
| [Brother 240kB](doc/disk-brother.md) | 🦄 | 🦄 | |
|
||||
| [Brother FB-100](doc/disk-fb100.md) | 🦖 | | Tandy Model 100, Husky Hunter, knitting machines |
|
||||
| [Macintosh 800kB](doc/disk-macintosh.md) | 🦄 | 🦄 | and probably the 400kB too |
|
||||
| [TRS-80](doc/disk-trs80.md) | 🦖 | 🦖* | a minor variation of the IBM scheme |
|
||||
{: .datatable }
|
||||
|
||||
`*`: these formats are variations of the generic IBM format, and since the
|
||||
@@ -118,7 +123,9 @@ at least, check the CRC so what data's there is probably good.
|
||||
| [AES Superplus / No Problem](doc/disk-aeslanier.md) | 🦖 | | hard sectors! |
|
||||
| [Durango F85](doc/disk-durangof85.md) | 🦖 | | 5.25" |
|
||||
| [DVK MX](doc/disk-mx.md) | 🦖 | | Soviet PDP-11 clone |
|
||||
| [VDS Eco1](doc/disk-eco1.md) | 🦖 | | 8" mixed format |
|
||||
| [Micropolis](doc/disk-micropolis.md) | 🦄 | | Micropolis 100tpi drives |
|
||||
| [Northstar(doc/disk-northstar.md) | 🦖 | 🦖 | 5.25" hard sectors |
|
||||
| [TI DS990 FD1000](doc/disk-tids990.md) | 🦄 | 🦄 | 8" |
|
||||
| [Victor 9000](doc/disk-victor9k.md) | 🦖 | | 8" |
|
||||
| [Zilog MCZ](doc/disk-zilogmcz.md) | 🦖 | | 8" _and_ hard sectors |
|
||||
@@ -219,3 +226,7 @@ written by Sean T Barett (and others). It is public domain/Unlicense/MIT
|
||||
licensed, at your choice. Please see the contents of the directory for the full
|
||||
text.
|
||||
|
||||
As an exception, `dep/snowhouse` contains the snowhouse assertion library,
|
||||
taken from https://github.com/banditcpp/snowhouse. It is Boost Standard License
|
||||
1.0 licensed. Please see the contents of the directory for the full text.
|
||||
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
|
||||
class Sector;
|
||||
class Fluxmap;
|
||||
class AesLanierDecoderProto;
|
||||
|
||||
class AesLanierDecoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
AesLanierDecoder(const AesLanierDecoderProto&) {}
|
||||
virtual ~AesLanierDecoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
|
||||
4
arch/aeslanier/aeslanier.proto
Normal file
4
arch/aeslanier/aeslanier.proto
Normal file
@@ -0,0 +1,4 @@
|
||||
syntax = "proto2";
|
||||
|
||||
message AesLanierDecoderProto {}
|
||||
|
||||
@@ -12,10 +12,13 @@
|
||||
class Sector;
|
||||
class Fluxmap;
|
||||
class SectorSet;
|
||||
class AmigaDecoderProto;
|
||||
class AmigaEncoderProto;
|
||||
|
||||
class AmigaDecoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
AmigaDecoder(const AmigaDecoderProto&) {}
|
||||
virtual ~AmigaDecoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
@@ -27,13 +30,16 @@ public:
|
||||
class AmigaEncoder : public AbstractEncoder
|
||||
{
|
||||
public:
|
||||
AmigaEncoder(const AmigaEncoderProto& config):
|
||||
_config(config) {}
|
||||
virtual ~AmigaEncoder() {}
|
||||
|
||||
public:
|
||||
std::unique_ptr<Fluxmap> encode(int physicalTrack, int physicalSide, const SectorSet& allSectors);
|
||||
};
|
||||
|
||||
extern FlagGroup amigaEncoderFlags;
|
||||
private:
|
||||
const AmigaEncoderProto& _config;
|
||||
};
|
||||
|
||||
extern uint32_t amigaChecksum(const Bytes& bytes);
|
||||
extern Bytes amigaInterleave(const Bytes& input);
|
||||
|
||||
13
arch/amiga/amiga.proto
Normal file
13
arch/amiga/amiga.proto
Normal file
@@ -0,0 +1,13 @@
|
||||
syntax = "proto2";
|
||||
|
||||
import "lib/common.proto";
|
||||
|
||||
message AmigaDecoderProto {}
|
||||
|
||||
message AmigaEncoderProto {
|
||||
optional double clock_rate_us = 1
|
||||
[default=2.00, (help)="Encoded data clock rate."];
|
||||
optional double post_index_gap_ms = 2
|
||||
[default=0.5, (help)="Post-index gap before first sector header."];
|
||||
}
|
||||
|
||||
@@ -6,18 +6,7 @@
|
||||
#include "crc.h"
|
||||
#include "sectorset.h"
|
||||
#include "writer.h"
|
||||
|
||||
FlagGroup amigaEncoderFlags;
|
||||
|
||||
static DoubleFlag clockRateUs(
|
||||
{ "--clock-rate" },
|
||||
"Encoded data clock rate (microseconds).",
|
||||
2.00);
|
||||
|
||||
static DoubleFlag postIndexGapMs(
|
||||
{ "--post-index-gap" },
|
||||
"Post-index gap before first sector header (milliseconds).",
|
||||
0.5);
|
||||
#include "arch/amiga/amiga.pb.h"
|
||||
|
||||
static bool lastBit;
|
||||
|
||||
@@ -33,13 +22,14 @@ static void write_bits(std::vector<bool>& bits, unsigned& cursor, const std::vec
|
||||
for (bool bit : src)
|
||||
{
|
||||
if (cursor < bits.size())
|
||||
bits[cursor++] = bit;
|
||||
lastBit = bits[cursor++] = bit;
|
||||
}
|
||||
}
|
||||
|
||||
static void write_bits(std::vector<bool>& bits, unsigned& cursor, uint64_t data, int width)
|
||||
{
|
||||
cursor += width;
|
||||
lastBit = data & 1;
|
||||
for (int i=0; i<width; i++)
|
||||
{
|
||||
unsigned pos = cursor - i - 1;
|
||||
@@ -49,19 +39,16 @@ static void write_bits(std::vector<bool>& bits, unsigned& cursor, uint64_t data,
|
||||
}
|
||||
}
|
||||
|
||||
static void write_interleaved_bytes(std::vector<bool>& bits, unsigned& cursor, const Bytes& bytes)
|
||||
static void write_bits(std::vector<bool>& bits, unsigned& cursor, const Bytes& bytes)
|
||||
{
|
||||
assert(!(bytes.size() & 3));
|
||||
Bytes interleaved = amigaInterleave(bytes);
|
||||
encodeMfm(bits, cursor, interleaved, lastBit);
|
||||
}
|
||||
ByteReader br(bytes);
|
||||
BitReader bitr(br);
|
||||
|
||||
static void write_interleaved_bytes(std::vector<bool>& bits, unsigned& cursor, uint32_t data)
|
||||
{
|
||||
Bytes b(4);
|
||||
ByteWriter bw(b);
|
||||
bw.write_be32(data);
|
||||
write_interleaved_bytes(bits, cursor, b);
|
||||
while (!bitr.eof())
|
||||
{
|
||||
if (cursor < bits.size())
|
||||
bits[cursor++] = bitr.get();
|
||||
}
|
||||
}
|
||||
|
||||
static void write_sector(std::vector<bool>& bits, unsigned& cursor, const Sector* sector)
|
||||
@@ -69,11 +56,27 @@ static void write_sector(std::vector<bool>& bits, unsigned& cursor, const Sector
|
||||
if ((sector->data.size() != 512) && (sector->data.size() != 528))
|
||||
Error() << "unsupported sector size --- you must pick 512 or 528";
|
||||
|
||||
uint32_t checksum = 0;
|
||||
|
||||
auto write_interleaved_bytes = [&](const Bytes& bytes)
|
||||
{
|
||||
Bytes interleaved = amigaInterleave(bytes);
|
||||
Bytes mfm = encodeMfm(interleaved, lastBit);
|
||||
checksum ^= amigaChecksum(mfm);
|
||||
checksum &= 0x55555555;
|
||||
write_bits(bits, cursor, mfm);
|
||||
};
|
||||
|
||||
auto write_interleaved_word = [&](uint32_t word)
|
||||
{
|
||||
Bytes b(4);
|
||||
b.writer().write_be32(word);
|
||||
write_interleaved_bytes(b);
|
||||
};
|
||||
|
||||
write_bits(bits, cursor, AMIGA_SECTOR_RECORD, 6*8);
|
||||
|
||||
std::vector<bool> headerBits(20*16);
|
||||
unsigned headerCursor = 0;
|
||||
|
||||
checksum = 0;
|
||||
Bytes header =
|
||||
{
|
||||
0xff, /* Amiga 1.0 format byte */
|
||||
@@ -81,22 +84,16 @@ static void write_sector(std::vector<bool>& bits, unsigned& cursor, const Sector
|
||||
(uint8_t) sector->logicalSector,
|
||||
(uint8_t) (AMIGA_SECTORS_PER_TRACK - sector->logicalSector)
|
||||
};
|
||||
write_interleaved_bytes(headerBits, headerCursor, header);
|
||||
write_interleaved_bytes(header);
|
||||
Bytes recoveryInfo(16);
|
||||
if (sector->data.size() == 528)
|
||||
recoveryInfo = sector->data.slice(512, 16);
|
||||
write_interleaved_bytes(headerBits, headerCursor, recoveryInfo);
|
||||
write_interleaved_bytes(recoveryInfo);
|
||||
write_interleaved_word(checksum);
|
||||
|
||||
std::vector<bool> dataBits(512*16);
|
||||
unsigned dataCursor = 0;
|
||||
write_interleaved_bytes(dataBits, dataCursor, sector->data);
|
||||
|
||||
write_bits(bits, cursor, headerBits);
|
||||
uint32_t headerChecksum = amigaChecksum(toBytes(headerBits));
|
||||
write_interleaved_bytes(bits, cursor, headerChecksum);
|
||||
uint32_t dataChecksum = amigaChecksum(toBytes(dataBits));
|
||||
write_interleaved_bytes(bits, cursor, dataChecksum);
|
||||
write_bits(bits, cursor, dataBits);
|
||||
Bytes data = sector->data.slice(0, 512);
|
||||
write_interleaved_word(amigaChecksum(encodeMfm(amigaInterleave(data), lastBit)));
|
||||
write_interleaved_bytes(data);
|
||||
}
|
||||
|
||||
std::unique_ptr<Fluxmap> AmigaEncoder::encode(
|
||||
@@ -105,11 +102,11 @@ std::unique_ptr<Fluxmap> AmigaEncoder::encode(
|
||||
if ((physicalTrack < 0) || (physicalTrack >= AMIGA_TRACKS_PER_DISK))
|
||||
return std::unique_ptr<Fluxmap>();
|
||||
|
||||
int bitsPerRevolution = 200000.0 / clockRateUs;
|
||||
int bitsPerRevolution = 200000.0 / _config.clock_rate_us();
|
||||
std::vector<bool> bits(bitsPerRevolution);
|
||||
unsigned cursor = 0;
|
||||
|
||||
fillBitmapTo(bits, cursor, postIndexGapMs * 1000 / clockRateUs, { true, false });
|
||||
fillBitmapTo(bits, cursor, _config.post_index_gap_ms() * 1000 / _config.clock_rate_us(), { true, false });
|
||||
lastBit = false;
|
||||
|
||||
for (int sectorId=0; sectorId<AMIGA_SECTORS_PER_TRACK; sectorId++)
|
||||
@@ -123,7 +120,7 @@ std::unique_ptr<Fluxmap> AmigaEncoder::encode(
|
||||
fillBitmapTo(bits, cursor, bits.size(), { true, false });
|
||||
|
||||
std::unique_ptr<Fluxmap> fluxmap(new Fluxmap);
|
||||
fluxmap->appendBits(bits, clockRateUs*1e3);
|
||||
fluxmap->appendBits(bits, _config.clock_rate_us()*1e3);
|
||||
return fluxmap;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,12 @@
|
||||
|
||||
class Sector;
|
||||
class Fluxmap;
|
||||
class Apple2DecoderProto;
|
||||
|
||||
class Apple2Decoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
Apple2Decoder(const Apple2DecoderProto&) {}
|
||||
virtual ~Apple2Decoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
|
||||
4
arch/apple2/apple2.proto
Normal file
4
arch/apple2/apple2.proto
Normal file
@@ -0,0 +1,4 @@
|
||||
syntax = "proto2";
|
||||
|
||||
message Apple2DecoderProto {}
|
||||
|
||||
@@ -14,11 +14,15 @@
|
||||
#define BROTHER_SECTORS_PER_TRACK 12
|
||||
|
||||
class Sector;
|
||||
class SectorSet;
|
||||
class Fluxmap;
|
||||
class BrotherDecoderProto;
|
||||
class BrotherEncoderProto;
|
||||
|
||||
class BrotherDecoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
BrotherDecoder(const BrotherDecoderProto& config) {}
|
||||
virtual ~BrotherDecoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
@@ -29,20 +33,17 @@ public:
|
||||
class BrotherEncoder : public AbstractEncoder
|
||||
{
|
||||
public:
|
||||
BrotherEncoder(int format, int bias):
|
||||
_format(format),
|
||||
_bias(bias)
|
||||
BrotherEncoder(const BrotherEncoderProto& config):
|
||||
_config(config)
|
||||
{}
|
||||
|
||||
virtual ~BrotherEncoder() {}
|
||||
|
||||
private:
|
||||
int _format;
|
||||
int _bias;
|
||||
const BrotherEncoderProto& _config;
|
||||
|
||||
public:
|
||||
std::unique_ptr<Fluxmap> encode(int physicalTrack, int physicalSide, const SectorSet& allSectors);
|
||||
};
|
||||
|
||||
extern FlagGroup brotherEncoderFlags;
|
||||
|
||||
#endif
|
||||
|
||||
20
arch/brother/brother.proto
Normal file
20
arch/brother/brother.proto
Normal file
@@ -0,0 +1,20 @@
|
||||
syntax = "proto2";
|
||||
|
||||
message BrotherDecoderProto {}
|
||||
|
||||
enum BrotherFormat {
|
||||
BROTHER240 = 0;
|
||||
BROTHER120 = 1;
|
||||
};
|
||||
|
||||
message BrotherEncoderProto {
|
||||
optional double clock_rate_us = 1 [default = 3.83];
|
||||
optional double post_index_gap_ms = 2 [default = 1.0];
|
||||
optional double sector_spacing_ms = 3 [default = 16.2];
|
||||
optional double post_header_spacing_ms = 4 [default = 0.69];
|
||||
optional string sector_skew = 5 [default = "05a3816b4927"];
|
||||
|
||||
optional BrotherFormat format = 6 [default = BROTHER240];
|
||||
optional int32 bias = 7 [default = 0];
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "crc.h"
|
||||
#include "sectorset.h"
|
||||
#include "writer.h"
|
||||
#include "arch/brother/brother.pb.h"
|
||||
|
||||
FlagGroup brotherEncoderFlags;
|
||||
|
||||
@@ -132,17 +133,17 @@ std::unique_ptr<Fluxmap> BrotherEncoder::encode(
|
||||
int logicalTrack;
|
||||
if (physicalSide != 0)
|
||||
return std::unique_ptr<Fluxmap>();
|
||||
physicalTrack -= _bias;
|
||||
switch (_format)
|
||||
physicalTrack -= _config.bias();
|
||||
switch (_config.format())
|
||||
{
|
||||
case 120:
|
||||
case BROTHER120:
|
||||
if ((physicalTrack < 0) || (physicalTrack >= (BROTHER_TRACKS_PER_120KB_DISK*2))
|
||||
|| (physicalTrack & 1))
|
||||
return std::unique_ptr<Fluxmap>();
|
||||
logicalTrack = physicalTrack/2;
|
||||
break;
|
||||
|
||||
case 240:
|
||||
case BROTHER240:
|
||||
if ((physicalTrack < 0) || (physicalTrack >= BROTHER_TRACKS_PER_240KB_DISK))
|
||||
return std::unique_ptr<Fluxmap>();
|
||||
logicalTrack = physicalTrack;
|
||||
|
||||
@@ -1,16 +1,42 @@
|
||||
#ifndef C64_H
|
||||
#define C64_H
|
||||
|
||||
#include "decoders/decoders.h"
|
||||
#include "encoders/encoders.h"
|
||||
|
||||
#define C64_SECTOR_RECORD 0xffd49
|
||||
#define C64_DATA_RECORD 0xffd57
|
||||
#define C64_SECTOR_LENGTH 256
|
||||
|
||||
/* Source: http://www.unusedino.de/ec64/technical/formats/g64.html
|
||||
1. Header sync FF FF FF FF FF (40 'on' bits, not GCR)
|
||||
2. Header info 52 54 B5 29 4B 7A 5E 95 55 55 (10 GCR bytes)
|
||||
3. Header gap 55 55 55 55 55 55 55 55 55 (9 bytes, never read)
|
||||
4. Data sync FF FF FF FF FF (40 'on' bits, not GCR)
|
||||
5. Data block 55...4A (325 GCR bytes)
|
||||
6. Inter-sector gap 55 55 55 55...55 55 (4 to 12 bytes, never read)
|
||||
1. Header sync (SYNC for the next sector)
|
||||
*/
|
||||
#define C64_HEADER_DATA_SYNC 0xFF
|
||||
#define C64_HEADER_BLOCK_ID 0x08
|
||||
#define C64_DATA_BLOCK_ID 0x07
|
||||
#define C64_HEADER_GAP 0x55
|
||||
#define C64_INTER_SECTOR_GAP 0x55
|
||||
#define C64_PADDING 0x0F
|
||||
|
||||
#define C64_TRACKS_PER_DISK 40
|
||||
#define C64_BAM_TRACK 17
|
||||
|
||||
|
||||
class Sector;
|
||||
class Fluxmap;
|
||||
class Commodore64DecoderProto;
|
||||
class Commodore64EncoderProto;
|
||||
|
||||
class Commodore64Decoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
Commodore64Decoder(const Commodore64DecoderProto&) {}
|
||||
virtual ~Commodore64Decoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
@@ -18,4 +44,25 @@ public:
|
||||
void decodeDataRecord();
|
||||
};
|
||||
|
||||
class Commodore64Encoder : public AbstractEncoder
|
||||
{
|
||||
public:
|
||||
Commodore64Encoder(const Commodore64EncoderProto& config):
|
||||
_config(config)
|
||||
{}
|
||||
|
||||
virtual ~Commodore64Encoder() {}
|
||||
|
||||
public:
|
||||
std::unique_ptr<Fluxmap> encode(int physicalTrack, int physicalSide, const SectorSet& allSectors);
|
||||
|
||||
private:
|
||||
void writeSector(std::vector<bool>& bits, unsigned& cursor, const Sector* sector) const;
|
||||
|
||||
private:
|
||||
const Commodore64EncoderProto& _config;
|
||||
uint8_t _formatByte1;
|
||||
uint8_t _formatByte2;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
13
arch/c64/c64.proto
Normal file
13
arch/c64/c64.proto
Normal file
@@ -0,0 +1,13 @@
|
||||
syntax = "proto2";
|
||||
|
||||
import "lib/common.proto";
|
||||
|
||||
message Commodore64DecoderProto {}
|
||||
|
||||
message Commodore64EncoderProto {
|
||||
optional double post_index_gap_us = 1 [default=0.0,
|
||||
(help) = "post-index gap before first sector header."];
|
||||
optional double clock_compensation_factor = 2 [default=1.0,
|
||||
(help) = "scale the output clock by this much."];
|
||||
}
|
||||
|
||||
349
arch/c64/encoder.cc
Normal file
349
arch/c64/encoder.cc
Normal file
@@ -0,0 +1,349 @@
|
||||
#include "globals.h"
|
||||
#include "record.h"
|
||||
#include "decoders/decoders.h"
|
||||
#include "encoders/encoders.h"
|
||||
#include "c64.h"
|
||||
#include "crc.h"
|
||||
#include "sectorset.h"
|
||||
#include "sector.h"
|
||||
#include "writer.h"
|
||||
#include "fmt/format.h"
|
||||
#include "arch/c64/c64.pb.h"
|
||||
#include <ctype.h>
|
||||
#include "bytes.h"
|
||||
|
||||
static bool lastBit;
|
||||
|
||||
static double clockRateUsForTrack(unsigned track)
|
||||
{
|
||||
/*
|
||||
* Track # Sectors/Track Speed Zone bits/rotation
|
||||
* 1 – 17 21 3 61,538.4
|
||||
* 18 – 24 19 2 57,142.8
|
||||
* 25 – 30 18 1 53,333.4
|
||||
* 31 – 35 17 0 50,000.0
|
||||
*/
|
||||
if (track < 17)
|
||||
return 200000.0/61538.4;
|
||||
if (track < 24)
|
||||
return 200000.0/57142.8;
|
||||
if (track < 30)
|
||||
return 200000.0/53333.4;
|
||||
return 200000.0/50000.0;
|
||||
|
||||
}
|
||||
|
||||
static unsigned sectorsForTrack(unsigned track)
|
||||
{
|
||||
/*
|
||||
* Track Sectors/track # Sectors Storage in Bytes
|
||||
* ----- ------------- --------- ----------------
|
||||
* 1-17 21 357 7820
|
||||
* 18-24 19 133 7170
|
||||
* 25-30 18 108 6300
|
||||
* 31-40(*) 17 85 6020
|
||||
* ---
|
||||
* 683 (for a 35 track image)
|
||||
*/
|
||||
if (track < 17)
|
||||
return 21;
|
||||
if (track < 24)
|
||||
return 19;
|
||||
if (track < 30)
|
||||
return 18;
|
||||
return 17;
|
||||
}
|
||||
|
||||
static int encode_data_gcr(uint8_t data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
#define GCR_ENTRY(gcr, data) \
|
||||
case data: return gcr;
|
||||
#include "data_gcr.h"
|
||||
#undef GCR_ENTRY
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
static void write_bits(std::vector<bool>& bits, unsigned& cursor, const std::vector<bool>& src)
|
||||
{
|
||||
for (bool bit : src) //Range-based for loop
|
||||
{
|
||||
if (cursor < bits.size())
|
||||
bits[cursor++] = bit;
|
||||
}
|
||||
}
|
||||
|
||||
static void write_bits(std::vector<bool>& bits, unsigned& cursor, uint64_t data, int width)
|
||||
{
|
||||
cursor += width;
|
||||
for (int i=0; i<width; i++)
|
||||
{
|
||||
unsigned pos = cursor - i - 1;
|
||||
if (pos < bits.size())
|
||||
bits[pos] = data & 1;
|
||||
data >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void bindump(std::ostream& stream, std::vector<bool>& buffer)
|
||||
{
|
||||
size_t pos = 0;
|
||||
|
||||
while ((pos < buffer.size()) and (pos <520))
|
||||
{
|
||||
stream << fmt::format("{:5d} : ", pos);
|
||||
for (int i=0; i<40; i++)
|
||||
{
|
||||
if ((pos+i) < buffer.size())
|
||||
stream << fmt::format("{:01b}", (buffer[pos+i]));
|
||||
else
|
||||
stream << "-- ";
|
||||
if ((((pos + i + 1) % 8) == 0) and i != 0)
|
||||
stream << " ";
|
||||
|
||||
}
|
||||
stream << std::endl;
|
||||
pos += 40;
|
||||
}
|
||||
}
|
||||
static std::vector<bool> encode_data(uint8_t input)
|
||||
{
|
||||
/*
|
||||
* Four 8-bit data bytes are converted to four 10-bit GCR bytes at a time by
|
||||
* the 1541 DOS. RAM is only an 8-bit storage device though. This hardware
|
||||
* limitation prevents a 10-bit GCR byte from being stored in a single
|
||||
* memory location. Four 10-bit GCR bytes total 40 bits - a number evenly
|
||||
* divisible by our overriding 8-bit constraint. Commodore sub- divides the
|
||||
* 40 GCR bits into five 8-bit bytes to solve this dilemma. This explains
|
||||
* why four 8-bit data bytes are converted to GCR form at a time. The
|
||||
* following step by step example demonstrates how this bit manipulation is
|
||||
* performed by the DOS.
|
||||
*
|
||||
* STEP 1. Four 8-bit Data Bytes
|
||||
* $08 $10 $00 $12
|
||||
*
|
||||
* STEP 2. Hexadecimal to Binary Conversion
|
||||
* 1. Binary Equivalents
|
||||
* $08 $10 $00 $12
|
||||
* 00001000 00010000 00000000 00010010
|
||||
*
|
||||
* STEP 3. Binary to GCR Conversion
|
||||
* 1. Four 8-bit Data Bytes
|
||||
* 00001000 00010000 00000000 00010010
|
||||
* 2. High and Low Nybbles
|
||||
* 0000 1000 0001 0000 0000 0000 0001 0010
|
||||
* 3. High and Low Nybble GCR Equivalents
|
||||
* 01010 01001 01011 01010 01010 01010 01011 10010
|
||||
* 4. Four 10-bit GCR Bytes
|
||||
* 0101001001 0101101010 0101001010 0101110010
|
||||
*
|
||||
* STEP 4. 10-bit GCR to 8-bit GCR Conversion
|
||||
* 1. Concatenate Four 10-bit GCR Bytes
|
||||
* 0101001001010110101001010010100101110010
|
||||
* 2. Five 8-bit Subdivisions
|
||||
* 01010010 01010110 10100101 00101001 01110010
|
||||
*
|
||||
* STEP 5. Binary to Hexadecimal Conversion
|
||||
* 1. Hexadecimal Equivalents
|
||||
* 01010010 01010110 10100101 00101001 01110010
|
||||
* $52 $56 $A5 $29 $72
|
||||
*
|
||||
* STEP 6. Four 8-bit Data Bytes are Recorded as Five 8-bit GCR Bytes
|
||||
* $08 $10 $00 $12
|
||||
*
|
||||
* are recorded as
|
||||
* $52 $56 $A5 $29 $72
|
||||
*/
|
||||
|
||||
std::vector<bool> output(10, false);
|
||||
uint8_t hi = 0;
|
||||
uint8_t lo = 0;
|
||||
uint8_t lo_GCR = 0;
|
||||
uint8_t hi_GCR = 0;
|
||||
|
||||
//Convert the byte in high and low nibble
|
||||
lo = input >> 4; //get the lo nibble shift the bits 4 to the right
|
||||
hi = input & 15; //get the hi nibble bij masking the lo bits (00001111)
|
||||
|
||||
|
||||
lo_GCR = encode_data_gcr(lo); //example value: 0000 GCR = 01010
|
||||
hi_GCR = encode_data_gcr(hi); //example value: 1000 GCR = 01001
|
||||
//output = [0,1,2,3,4,5,6,7,8,9]
|
||||
//value = [0,1,0,1,0,0,1,0,0,1]
|
||||
// 01010 01001
|
||||
|
||||
int b = 4;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (i < 5) //01234
|
||||
{ //i = 0 op
|
||||
output[4-i] = (lo_GCR & 1); //01010
|
||||
|
||||
//01010 -> & 00001 -> 00000 output[4] = 0
|
||||
//00101 -> & 00001 -> 00001 output[3] = 1
|
||||
//00010 -> & 00001 -> 00000 output[2] = 0
|
||||
//00001 -> & 00001 -> 00001 output[1] = 1
|
||||
//00000 -> & 00001 -> 00000 output[0] = 0
|
||||
lo_GCR >>= 1;
|
||||
} else
|
||||
{
|
||||
output[i+b] = (hi_GCR & 1); //01001
|
||||
//01001 -> & 00001 -> 00001 output[9] = 1
|
||||
//00100 -> & 00001 -> 00000 output[8] = 0
|
||||
//00010 -> & 00001 -> 00000 output[7] = 0
|
||||
//00001 -> & 00001 -> 00001 output[6] = 1
|
||||
//00000 -> & 00001 -> 00000 output[5] = 0
|
||||
hi_GCR >>= 1;
|
||||
b = b-2;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
void Commodore64Encoder::writeSector(std::vector<bool>& bits, unsigned& cursor, const Sector* sector) const
|
||||
{
|
||||
/* Source: http://www.unusedino.de/ec64/technical/formats/g64.html
|
||||
* 1. Header sync FF FF FF FF FF (40 'on' bits, not GCR)
|
||||
* 2. Header info 52 54 B5 29 4B 7A 5E 95 55 55 (10 GCR bytes)
|
||||
* 3. Header gap 55 55 55 55 55 55 55 55 55 (9 bytes, never read)
|
||||
* 4. Data sync FF FF FF FF FF (40 'on' bits, not GCR)
|
||||
* 5. Data block 55...4A (325 GCR bytes)
|
||||
* 6. Inter-sector gap 55 55 55 55...55 55 (4 to 12 bytes, never read)
|
||||
* 1. Header sync (SYNC for the next sector)
|
||||
*/
|
||||
if ((sector->status == Sector::OK) or (sector->status == Sector::BAD_CHECKSUM))
|
||||
{
|
||||
// There is data to encode to disk.
|
||||
if ((sector->data.size() != C64_SECTOR_LENGTH))
|
||||
Error() << fmt::format("unsupported sector size {} --- you must pick 256", sector->data.size());
|
||||
|
||||
// 1. Write header Sync (not GCR)
|
||||
for (int i=0; i<6; i++)
|
||||
write_bits(bits, cursor, C64_HEADER_DATA_SYNC, 1*8); /* sync */
|
||||
|
||||
// 2. Write Header info 10 GCR bytes
|
||||
/*
|
||||
* The 10 byte header info (#2) is GCR encoded and must be decoded to
|
||||
* it's normal 8 bytes to be understood. Once decoded, its breakdown is
|
||||
* as follows:
|
||||
*
|
||||
* Byte $00 - header block ID ($08)
|
||||
* 01 - header block checksum 16 (EOR of $02-$05)
|
||||
* 02 - Sector
|
||||
* 03 - Track
|
||||
* 04 - Format ID byte #2
|
||||
* 05 - Format ID byte #1
|
||||
* 06-07 - $0F ("off" bytes)
|
||||
*/
|
||||
uint8_t encodedTrack = ((sector->logicalTrack) + 1); // C64 track numbering starts with 1. Fluxengine with 0.
|
||||
uint8_t encodedSector = sector->logicalSector;
|
||||
// uint8_t formatByte1 = C64_FORMAT_ID_BYTE1;
|
||||
// uint8_t formatByte2 = C64_FORMAT_ID_BYTE2;
|
||||
uint8_t headerChecksum = (encodedTrack ^ encodedSector ^ _formatByte1 ^ _formatByte2);
|
||||
write_bits(bits, cursor, encode_data(C64_HEADER_BLOCK_ID));
|
||||
write_bits(bits, cursor, encode_data(headerChecksum));
|
||||
write_bits(bits, cursor, encode_data(encodedSector));
|
||||
write_bits(bits, cursor, encode_data(encodedTrack));
|
||||
write_bits(bits, cursor, encode_data(_formatByte2));
|
||||
write_bits(bits, cursor, encode_data(_formatByte1));
|
||||
write_bits(bits, cursor, encode_data(C64_PADDING));
|
||||
write_bits(bits, cursor, encode_data(C64_PADDING));
|
||||
|
||||
// 3. Write header GAP not GCR
|
||||
for (int i=0; i<9; i++)
|
||||
write_bits(bits, cursor, C64_HEADER_GAP, 1*8); /* header gap */
|
||||
|
||||
// 4. Write Data sync not GCR
|
||||
for (int i=0; i<6; i++)
|
||||
write_bits(bits, cursor, C64_HEADER_DATA_SYNC, 1*8); /* sync */
|
||||
|
||||
// 5. Write data block 325 GCR bytes
|
||||
/*
|
||||
* The 325 byte data block (#5) is GCR encoded and must be decoded to its
|
||||
* normal 260 bytes to be understood. The data block is made up of the following:
|
||||
*
|
||||
* Byte $00 - data block ID ($07)
|
||||
* 01-100 - 256 bytes data
|
||||
* 101 - data block checksum (EOR of $01-100)
|
||||
* 102-103 - $00 ("off" bytes, to make the sector size a multiple of 5)
|
||||
*/
|
||||
|
||||
write_bits(bits, cursor, encode_data(C64_DATA_BLOCK_ID));
|
||||
uint8_t dataChecksum = xorBytes(sector->data);
|
||||
ByteReader br(sector->data);
|
||||
int i = 0;
|
||||
for (i = 0; i < C64_SECTOR_LENGTH; i++)
|
||||
{
|
||||
uint8_t val = br.read_8();
|
||||
write_bits(bits, cursor, encode_data(val));
|
||||
}
|
||||
write_bits(bits, cursor, encode_data(dataChecksum));
|
||||
write_bits(bits, cursor, encode_data(C64_PADDING));
|
||||
write_bits(bits, cursor, encode_data(C64_PADDING));
|
||||
|
||||
//6. Write inter-sector gap 9 - 12 bytes nor gcr
|
||||
for (int i=0; i<9; i++)
|
||||
write_bits(bits, cursor, C64_INTER_SECTOR_GAP, 1*8); /* sync */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Fluxmap> Commodore64Encoder::encode(
|
||||
int physicalTrack, int physicalSide, const SectorSet& allSectors)
|
||||
{
|
||||
/* The format ID Character # 1 and # 2 are in the .d64 image only present
|
||||
* in track 18 sector zero which contains the BAM info in byte 162 and 163.
|
||||
* it is written in every header of every sector and track. headers are not
|
||||
* stored in a d64 disk image so we have to get it from track 18 which
|
||||
* contains the BAM.
|
||||
*/
|
||||
|
||||
const auto& sectorData = allSectors.get(C64_BAM_TRACK*2, 0, 0); //Read de BAM to get the DISK ID bytes
|
||||
if (sectorData)
|
||||
{
|
||||
ByteReader br(sectorData->data);
|
||||
br.seek(162); //goto position of the first Disk ID Byte
|
||||
_formatByte1 = br.read_8();
|
||||
_formatByte2 = br.read_8();
|
||||
}
|
||||
else
|
||||
_formatByte1 = _formatByte2 = 0;
|
||||
|
||||
int logicalTrack = physicalTrack / 2;
|
||||
double clockRateUs = clockRateUsForTrack(logicalTrack) * _config.clock_compensation_factor();
|
||||
|
||||
int bitsPerRevolution = 200000.0 / clockRateUs;
|
||||
|
||||
std::vector<bool> bits(bitsPerRevolution);
|
||||
unsigned cursor = 0;
|
||||
|
||||
fillBitmapTo(bits, cursor, _config.post_index_gap_us() / clockRateUs, { true, false });
|
||||
lastBit = false;
|
||||
|
||||
unsigned numSectors = sectorsForTrack(logicalTrack);
|
||||
unsigned writtenSectors = 0;
|
||||
for (int sectorId=0; sectorId<numSectors; sectorId++)
|
||||
{
|
||||
const auto& sectorData = allSectors.get(physicalTrack, physicalSide, sectorId);
|
||||
if (sectorData)
|
||||
{
|
||||
writeSector(bits, cursor, sectorData);
|
||||
writtenSectors++;
|
||||
}
|
||||
}
|
||||
if (writtenSectors == 0)
|
||||
return std::unique_ptr<Fluxmap>();
|
||||
|
||||
if (cursor >= bits.size())
|
||||
Error() << fmt::format("track data overrun by {} bits", cursor - bits.size());
|
||||
fillBitmapTo(bits, cursor, bits.size(), { true, false });
|
||||
|
||||
std::unique_ptr<Fluxmap> fluxmap(new Fluxmap);
|
||||
fluxmap->appendBits(bits, clockRateUs*1e3);
|
||||
return fluxmap;
|
||||
}
|
||||
|
||||
// vim: sw=4 ts=4 et
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
|
||||
class Sector;
|
||||
class Fluxmap;
|
||||
class F85DecoderProto;
|
||||
|
||||
class DurangoF85Decoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
DurangoF85Decoder(const F85DecoderProto&) {}
|
||||
virtual ~DurangoF85Decoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
|
||||
4
arch/f85/f85.proto
Normal file
4
arch/f85/f85.proto
Normal file
@@ -0,0 +1,4 @@
|
||||
syntax = "proto2";
|
||||
|
||||
message F85DecoderProto {}
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
class Sector;
|
||||
class Fluxmap;
|
||||
class Track;
|
||||
class Fb100DecoderProto;
|
||||
|
||||
class Fb100Decoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
Fb100Decoder(const Fb100DecoderProto&) {}
|
||||
virtual ~Fb100Decoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
|
||||
4
arch/fb100/fb100.proto
Normal file
4
arch/fb100/fb100.proto
Normal file
@@ -0,0 +1,4 @@
|
||||
syntax = "proto2";
|
||||
|
||||
message Fb100DecoderProto {}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "decoders/fluxmapreader.h"
|
||||
#include "sector.h"
|
||||
#include "record.h"
|
||||
#include "arch/ibm/ibm.pb.h"
|
||||
#include "proto.h"
|
||||
#include <string.h>
|
||||
|
||||
static_assert(std::is_trivially_copyable<IbmIdam>::value,
|
||||
@@ -89,6 +91,11 @@ const FluxMatchers ANY_RECORD_PATTERN(
|
||||
}
|
||||
);
|
||||
|
||||
std::set<unsigned> IbmDecoder::requiredSectors(Track& track) const
|
||||
{
|
||||
return iterate(_config.required_sectors());
|
||||
}
|
||||
|
||||
AbstractDecoder::RecordType IbmDecoder::advanceToNextRecord()
|
||||
{
|
||||
const FluxMatcher* matcher = nullptr;
|
||||
@@ -131,14 +138,14 @@ void IbmDecoder::decodeSectorRecord()
|
||||
br.read_8(); /* skip ID byte */
|
||||
_sector->logicalTrack = br.read_8();
|
||||
_sector->logicalSide = br.read_8();
|
||||
_sector->logicalSector = br.read_8() - _sectorBase;
|
||||
_sector->logicalSector = br.read_8() - _config.sector_id_base();
|
||||
_currentSectorSize = 1 << (br.read_8() + 7);
|
||||
uint16_t wantCrc = br.read_be16();
|
||||
uint16_t gotCrc = crc16(CCITT_POLY, bytes.slice(0, _currentHeaderLength + 5));
|
||||
if (wantCrc == gotCrc)
|
||||
_sector->status = Sector::DATA_MISSING; /* correct but unintuitive */
|
||||
|
||||
if (_ignoreSideByte)
|
||||
if (_config.ignore_side_byte())
|
||||
_sector->logicalSide = _sector->physicalSide;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "crc.h"
|
||||
#include "sectorset.h"
|
||||
#include "writer.h"
|
||||
#include "arch/ibm/ibm.pb.h"
|
||||
#include "fmt/format.h"
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -76,21 +77,6 @@ void IbmEncoder::writeRawBits(uint32_t data, int width)
|
||||
}
|
||||
}
|
||||
|
||||
void IbmEncoder::writeBytes(const Bytes& bytes)
|
||||
{
|
||||
if (_parameters.useFm)
|
||||
encodeFm(_bits, _cursor, bytes);
|
||||
else
|
||||
encodeMfm(_bits, _cursor, bytes, _lastBit);
|
||||
}
|
||||
|
||||
void IbmEncoder::writeBytes(int count, uint8_t byte)
|
||||
{
|
||||
Bytes bytes = { byte };
|
||||
for (int i=0; i<count; i++)
|
||||
writeBytes(bytes);
|
||||
}
|
||||
|
||||
static uint8_t decodeUint16(uint16_t raw)
|
||||
{
|
||||
Bytes b;
|
||||
@@ -99,24 +85,56 @@ static uint8_t decodeUint16(uint16_t raw)
|
||||
return decodeFmMfm(b.toBits())[0];
|
||||
}
|
||||
|
||||
void IbmEncoder::getTrackFormat(IbmEncoderProto::TrackdataProto& trackdata, unsigned cylinder, unsigned head)
|
||||
{
|
||||
trackdata.Clear();
|
||||
for (const auto& f : _config.trackdata())
|
||||
{
|
||||
if (f.has_cylinder() && (f.cylinder() != cylinder))
|
||||
continue;
|
||||
if (f.has_head() && (f.head() != head))
|
||||
continue;
|
||||
|
||||
trackdata.MergeFrom(f);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Fluxmap> IbmEncoder::encode(
|
||||
int physicalTrack, int physicalSide, const SectorSet& allSectors)
|
||||
{
|
||||
if (_parameters.swapSides)
|
||||
IbmEncoderProto::TrackdataProto trackdata;
|
||||
getTrackFormat(trackdata, physicalTrack, physicalSide);
|
||||
|
||||
auto writeBytes = [&](const Bytes& bytes)
|
||||
{
|
||||
if (trackdata.use_fm())
|
||||
encodeFm(_bits, _cursor, bytes);
|
||||
else
|
||||
encodeMfm(_bits, _cursor, bytes, _lastBit);
|
||||
};
|
||||
|
||||
auto writeFillerBytes = [&](int count, uint8_t byte)
|
||||
{
|
||||
Bytes bytes = { byte };
|
||||
for (int i=0; i<count; i++)
|
||||
writeBytes(bytes);
|
||||
};
|
||||
|
||||
if (trackdata.swap_sides())
|
||||
physicalSide = 1 - physicalSide;
|
||||
double clockRateUs = 1e3 / _parameters.clockRateKhz;
|
||||
if (!_parameters.useFm)
|
||||
double clockRateUs = 1e3 / trackdata.clock_rate_khz();
|
||||
if (!trackdata.use_fm())
|
||||
clockRateUs /= 2.0;
|
||||
int bitsPerRevolution = (_parameters.trackLengthMs * 1000.0) / clockRateUs;
|
||||
int bitsPerRevolution = (trackdata.track_length_ms() * 1000.0) / clockRateUs;
|
||||
_bits.resize(bitsPerRevolution);
|
||||
_cursor = 0;
|
||||
|
||||
uint8_t idamUnencoded = decodeUint16(_parameters.idamByte);
|
||||
uint8_t damUnencoded = decodeUint16(_parameters.damByte);
|
||||
uint8_t idamUnencoded = decodeUint16(trackdata.idam_byte());
|
||||
uint8_t damUnencoded = decodeUint16(trackdata.dam_byte());
|
||||
|
||||
uint8_t sectorSize = 0;
|
||||
{
|
||||
int s = _parameters.sectorSize >> 7;
|
||||
int s = trackdata.sector_size() >> 7;
|
||||
while (s > 1)
|
||||
{
|
||||
s >>= 1;
|
||||
@@ -124,32 +142,35 @@ std::unique_ptr<Fluxmap> IbmEncoder::encode(
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t gapFill = _parameters.useFm ? 0x00 : 0x4e;
|
||||
uint8_t gapFill = trackdata.use_fm() ? 0x00 : 0x4e;
|
||||
|
||||
writeBytes(_parameters.gap0, gapFill);
|
||||
if (_parameters.emitIam)
|
||||
writeFillerBytes(trackdata.gap0(), gapFill);
|
||||
if (trackdata.emit_iam())
|
||||
{
|
||||
writeBytes(_parameters.useFm ? 6 : 12, 0x00);
|
||||
if (!_parameters.useFm)
|
||||
writeFillerBytes(trackdata.use_fm() ? 6 : 12, 0x00);
|
||||
if (!trackdata.use_fm())
|
||||
{
|
||||
for (int i=0; i<3; i++)
|
||||
writeRawBits(MFM_IAM_SEPARATOR, 16);
|
||||
}
|
||||
writeRawBits(_parameters.useFm ? FM_IAM_RECORD : MFM_IAM_RECORD, 16);
|
||||
writeBytes(_parameters.gap1, gapFill);
|
||||
writeRawBits(trackdata.use_fm() ? FM_IAM_RECORD : MFM_IAM_RECORD, 16);
|
||||
writeFillerBytes(trackdata.gap1(), gapFill);
|
||||
}
|
||||
|
||||
bool first = true;
|
||||
for (char sectorChar : _parameters.sectorSkew)
|
||||
for (char sectorChar : trackdata.sector_skew())
|
||||
{
|
||||
int sectorId = charToInt(sectorChar);
|
||||
if (!first)
|
||||
writeBytes(_parameters.gap3, gapFill);
|
||||
writeFillerBytes(trackdata.gap3(), gapFill);
|
||||
first = false;
|
||||
|
||||
const auto& sectorData = allSectors.get(physicalTrack, physicalSide, sectorId);
|
||||
if (!sectorData)
|
||||
Error() << fmt::format("format tried to find sector {} which wasn't in the input file", sectorId);
|
||||
{
|
||||
/* If there are any missing sectors, this is an empty track. */
|
||||
return std::unique_ptr<Fluxmap>();
|
||||
}
|
||||
|
||||
/* Writing the sector and data records are fantastically annoying.
|
||||
* The CRC is calculated from the *very start* of the record, and
|
||||
@@ -163,8 +184,8 @@ std::unique_ptr<Fluxmap> IbmEncoder::encode(
|
||||
Bytes header;
|
||||
ByteWriter bw(header);
|
||||
|
||||
writeBytes(_parameters.useFm ? 6 : 12, 0x00);
|
||||
if (!_parameters.useFm)
|
||||
writeFillerBytes(trackdata.use_fm() ? 6 : 12, 0x00);
|
||||
if (!trackdata.use_fm())
|
||||
{
|
||||
for (int i=0; i<3; i++)
|
||||
bw.write_8(MFM_RECORD_SEPARATOR_BYTE);
|
||||
@@ -172,53 +193,53 @@ std::unique_ptr<Fluxmap> IbmEncoder::encode(
|
||||
bw.write_8(idamUnencoded);
|
||||
bw.write_8(sectorData->logicalTrack);
|
||||
bw.write_8(sectorData->logicalSide);
|
||||
bw.write_8(sectorData->logicalSector + _parameters.startSectorId);
|
||||
bw.write_8(sectorData->logicalSector + trackdata.start_sector_id());
|
||||
bw.write_8(sectorSize);
|
||||
uint16_t crc = crc16(CCITT_POLY, header);
|
||||
bw.write_be16(crc);
|
||||
|
||||
int conventionalHeaderStart = 0;
|
||||
if (!_parameters.useFm)
|
||||
if (!trackdata.use_fm())
|
||||
{
|
||||
for (int i=0; i<3; i++)
|
||||
writeRawBits(MFM_RECORD_SEPARATOR, 16);
|
||||
conventionalHeaderStart += 3;
|
||||
|
||||
}
|
||||
writeRawBits(_parameters.idamByte, 16);
|
||||
writeRawBits(trackdata.idam_byte(), 16);
|
||||
conventionalHeaderStart += 1;
|
||||
|
||||
writeBytes(header.slice(conventionalHeaderStart));
|
||||
}
|
||||
|
||||
writeBytes(_parameters.gap2, gapFill);
|
||||
writeFillerBytes(trackdata.gap2(), gapFill);
|
||||
|
||||
{
|
||||
Bytes data;
|
||||
ByteWriter bw(data);
|
||||
|
||||
writeBytes(_parameters.useFm ? 6 : 12, 0x00);
|
||||
if (!_parameters.useFm)
|
||||
writeFillerBytes(trackdata.use_fm() ? 6 : 12, 0x00);
|
||||
if (!trackdata.use_fm())
|
||||
{
|
||||
for (int i=0; i<3; i++)
|
||||
bw.write_8(MFM_RECORD_SEPARATOR_BYTE);
|
||||
}
|
||||
bw.write_8(damUnencoded);
|
||||
|
||||
Bytes truncatedData = sectorData->data.slice(0, _parameters.sectorSize);
|
||||
Bytes truncatedData = sectorData->data.slice(0, trackdata.sector_size());
|
||||
bw += truncatedData;
|
||||
uint16_t crc = crc16(CCITT_POLY, data);
|
||||
bw.write_be16(crc);
|
||||
|
||||
int conventionalHeaderStart = 0;
|
||||
if (!_parameters.useFm)
|
||||
if (!trackdata.use_fm())
|
||||
{
|
||||
for (int i=0; i<3; i++)
|
||||
writeRawBits(MFM_RECORD_SEPARATOR, 16);
|
||||
conventionalHeaderStart += 3;
|
||||
|
||||
}
|
||||
writeRawBits(_parameters.damByte, 16);
|
||||
writeRawBits(trackdata.dam_byte(), 16);
|
||||
conventionalHeaderStart += 1;
|
||||
|
||||
writeBytes(data.slice(conventionalHeaderStart));
|
||||
@@ -228,7 +249,7 @@ std::unique_ptr<Fluxmap> IbmEncoder::encode(
|
||||
if (_cursor >= _bits.size())
|
||||
Error() << "track data overrun";
|
||||
while (_cursor < _bits.size())
|
||||
writeBytes(1, gapFill);
|
||||
writeFillerBytes(1, gapFill);
|
||||
|
||||
std::unique_ptr<Fluxmap> fluxmap(new Fluxmap);
|
||||
fluxmap->appendBits(_bits, clockRateUs*1e3);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "decoders/decoders.h"
|
||||
#include "encoders/encoders.h"
|
||||
#include "arch/ibm/ibm.pb.h"
|
||||
|
||||
/* IBM format (i.e. ordinary PC floppies). */
|
||||
|
||||
@@ -32,51 +33,27 @@ struct IbmIdam
|
||||
class IbmDecoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
IbmDecoder(unsigned sectorBase, bool ignoreSideByte=false,
|
||||
const std::set<unsigned> requiredSectors=std::set<unsigned>()):
|
||||
_sectorBase(sectorBase),
|
||||
_ignoreSideByte(ignoreSideByte),
|
||||
_requiredSectors(requiredSectors)
|
||||
IbmDecoder(const IbmDecoderProto& config):
|
||||
_config(config)
|
||||
{}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
void decodeSectorRecord();
|
||||
void decodeDataRecord();
|
||||
|
||||
std::set<unsigned> requiredSectors(Track& track) const
|
||||
{ return _requiredSectors; }
|
||||
std::set<unsigned> requiredSectors(Track& track) const;
|
||||
|
||||
private:
|
||||
unsigned _sectorBase;
|
||||
bool _ignoreSideByte;
|
||||
std::set<unsigned> _requiredSectors;
|
||||
const IbmDecoderProto& _config;
|
||||
unsigned _currentSectorSize;
|
||||
unsigned _currentHeaderLength;
|
||||
};
|
||||
|
||||
struct IbmParameters
|
||||
{
|
||||
int trackLengthMs;
|
||||
int sectorSize;
|
||||
bool emitIam;
|
||||
int startSectorId;
|
||||
int clockRateKhz;
|
||||
bool useFm;
|
||||
uint16_t idamByte;
|
||||
uint16_t damByte;
|
||||
int gap0;
|
||||
int gap1;
|
||||
int gap2;
|
||||
int gap3;
|
||||
std::string sectorSkew;
|
||||
bool swapSides;
|
||||
};
|
||||
|
||||
class IbmEncoder : public AbstractEncoder
|
||||
{
|
||||
public:
|
||||
IbmEncoder(const IbmParameters& parameters):
|
||||
_parameters(parameters)
|
||||
IbmEncoder(const IbmEncoderProto& config):
|
||||
_config(config)
|
||||
{}
|
||||
|
||||
virtual ~IbmEncoder() {}
|
||||
@@ -86,12 +63,12 @@ public:
|
||||
|
||||
private:
|
||||
void writeRawBits(uint32_t data, int width);
|
||||
void writeBytes(const Bytes& bytes);
|
||||
void writeBytes(int count, uint8_t value);
|
||||
void writeSync();
|
||||
|
||||
void getTrackFormat(IbmEncoderProto::TrackdataProto& format, unsigned track, unsigned side);
|
||||
|
||||
private:
|
||||
IbmParameters _parameters;
|
||||
const IbmEncoderProto& _config;
|
||||
std::vector<bool> _bits;
|
||||
unsigned _cursor;
|
||||
bool _lastBit;
|
||||
|
||||
34
arch/ibm/ibm.proto
Normal file
34
arch/ibm/ibm.proto
Normal file
@@ -0,0 +1,34 @@
|
||||
syntax = "proto2";
|
||||
|
||||
import "lib/common.proto";
|
||||
|
||||
message IbmDecoderProto {
|
||||
optional int32 sector_id_base = 1 [default = 1, (help) = "ID of first sector"];
|
||||
optional bool ignore_side_byte = 2 [default = false, (help) = "ignore side byte in sector header"];
|
||||
optional RangeProto required_sectors = 3 [(help) = "require these sectors to exist for a good read"];
|
||||
}
|
||||
|
||||
message IbmEncoderProto {
|
||||
message TrackdataProto {
|
||||
optional int32 cylinder = 15 [(help) = "if set, the format applies only to this track"];
|
||||
optional int32 head = 16 [(help) = "if set, the format applies only to this head"];
|
||||
|
||||
optional double track_length_ms = 1 [(help) = "length of track"];
|
||||
optional int32 sector_size = 2 [default=512, (help) = "number of bytes per sector"];
|
||||
optional bool emit_iam = 3 [default=true, (help) = "whether to emit an IAM record"];
|
||||
optional int32 start_sector_id = 4 [default=1, (help) = "ID of first sector"];
|
||||
optional double clock_rate_khz = 5 [(help) = "data clock rate"];
|
||||
optional bool use_fm = 6 [default=false, (help) = "whether to use FM encoding rather than MFM"];
|
||||
optional int32 idam_byte = 7 [default=0x5554, (help) = "16-bit raw bit pattern of IDAM byte"];
|
||||
optional int32 dam_byte = 8 [default=0x5545, (help) = "16-bit raw bit pattern of DAM byte"];
|
||||
optional int32 gap0 = 9 [default=80, (help) = "size of gap 1 (the post-index gap)"];
|
||||
optional int32 gap1 = 10 [default=50, (help) = "size of gap 2 (the post-ID gap)"];
|
||||
optional int32 gap2 = 11 [default=22, (help) = "size of gap 3 (the pre-data gap)"];
|
||||
optional int32 gap3 = 12 [default=80, (help) = "size of gap 4 (the post-data or format gap)"];
|
||||
optional string sector_skew = 13 [(help) = "order to emit sectors"];
|
||||
optional bool swap_sides = 14 [default=false, (help) = "swap side bytes when writing"];
|
||||
}
|
||||
|
||||
repeated TrackdataProto trackdata = 1;
|
||||
}
|
||||
|
||||
@@ -15,10 +15,13 @@
|
||||
|
||||
class Sector;
|
||||
class Fluxmap;
|
||||
class MacintoshDecoderProto;
|
||||
class MacintoshEncoderProto;
|
||||
|
||||
class MacintoshDecoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
MacintoshDecoder(const MacintoshDecoderProto&) {}
|
||||
virtual ~MacintoshDecoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
@@ -31,6 +34,7 @@ public:
|
||||
class MacintoshEncoder : public AbstractEncoder
|
||||
{
|
||||
public:
|
||||
MacintoshEncoder(const MacintoshEncoderProto&) {}
|
||||
virtual ~MacintoshEncoder() {}
|
||||
|
||||
public:
|
||||
|
||||
5
arch/macintosh/macintosh.proto
Normal file
5
arch/macintosh/macintosh.proto
Normal file
@@ -0,0 +1,5 @@
|
||||
syntax = "proto2";
|
||||
|
||||
message MacintoshDecoderProto {}
|
||||
message MacintoshEncoderProto {}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
#ifndef ZILOGMCZ_H
|
||||
#define ZILOGMCZ_H
|
||||
#ifndef MICROPOLIS_H
|
||||
#define MICROPOLIS_H
|
||||
|
||||
#define MICROPOLIS_ENCODED_SECTOR_SIZE (1+2+266+6)
|
||||
|
||||
class Sector;
|
||||
class Fluxmap;
|
||||
class MicropolisDecoderProto;
|
||||
|
||||
class MicropolisDecoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
MicropolisDecoder(const MicropolisDecoderProto&) {}
|
||||
virtual ~MicropolisDecoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
|
||||
4
arch/micropolis/micropolis.proto
Normal file
4
arch/micropolis/micropolis.proto
Normal file
@@ -0,0 +1,4 @@
|
||||
syntax = "proto2";
|
||||
|
||||
message MicropolisDecoderProto {}
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
|
||||
#include "decoders/decoders.h"
|
||||
|
||||
class MxDecoderProto;
|
||||
|
||||
class MxDecoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
MxDecoder(const MxDecoderProto&) {}
|
||||
virtual ~MxDecoder() {}
|
||||
|
||||
void beginTrack();
|
||||
|
||||
4
arch/mx/mx.proto
Normal file
4
arch/mx/mx.proto
Normal file
@@ -0,0 +1,4 @@
|
||||
syntax = "proto2";
|
||||
|
||||
message MxDecoderProto {}
|
||||
|
||||
175
arch/northstar/decoder.cc
Normal file
175
arch/northstar/decoder.cc
Normal file
@@ -0,0 +1,175 @@
|
||||
/* Decoder for North Star 10-sector hard-sectored disks.
|
||||
*
|
||||
* Supports both single- and double-density. For the sector format and
|
||||
* checksum algorithm, see pp. 33 of the North Star Double Density Controller
|
||||
* manual:
|
||||
*
|
||||
* http://bitsavers.org/pdf/northstar/boards/Northstar_MDS-A-D_1978.pdf
|
||||
*
|
||||
* North Star disks do not contain any track/head/sector information
|
||||
* encoded in the sector record. For this reason, we have to be absolutely
|
||||
* sure that the hardSectorId is correct.
|
||||
*/
|
||||
|
||||
#include "globals.h"
|
||||
#include "fluxmap.h"
|
||||
#include "decoders/fluxmapreader.h"
|
||||
#include "decoders/decoders.h"
|
||||
#include "sector.h"
|
||||
#include "northstar.h"
|
||||
#include "bytes.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
/*
|
||||
* MFM sectors have 32 bytes of 00's followed by two sync characters,
|
||||
* specified in the North Star MDS manual as 0xFBFB.
|
||||
*
|
||||
* This is true for most disks; however, I found a few disks, including an
|
||||
* original North Star DOS/BASIC v2.2.1 DQ disk) that uses 0xFBnn, where
|
||||
* nn is an incrementing pattern.
|
||||
*
|
||||
* 00 00 00 F B
|
||||
* 0000 0000 0000 0000 0000 0000 0101 0101 0100 0101
|
||||
* A A A A A A 5 5 4 5
|
||||
*/
|
||||
static const FluxPattern MFM_PATTERN(64, 0xAAAAAAAAAAAA5545LL);
|
||||
|
||||
/* FM sectors have 16 bytes of 00's followed by 0xFB.
|
||||
* 00 FB
|
||||
* 0000 0000 1111 1111 1110 1111
|
||||
* A A F F E F
|
||||
*/
|
||||
static const FluxPattern FM_PATTERN(64, 0xAAAAAAAAAAAAFFEFLL);
|
||||
|
||||
const FluxMatchers ANY_SECTOR_PATTERN(
|
||||
{
|
||||
&MFM_PATTERN,
|
||||
&FM_PATTERN,
|
||||
}
|
||||
);
|
||||
|
||||
/* Search for FM or MFM sector record */
|
||||
AbstractDecoder::RecordType NorthstarDecoder::advanceToNextRecord()
|
||||
{
|
||||
nanoseconds_t now = _fmr->tell().ns();
|
||||
|
||||
/* For all but the first sector, seek to the next sector pulse.
|
||||
* The first sector does not contain the sector pulse in the fluxmap.
|
||||
*/
|
||||
if (now != 0) {
|
||||
_fmr->seekToIndexMark();
|
||||
now = _fmr->tell().ns();
|
||||
}
|
||||
|
||||
/* Discard a possible partial sector at the end of the track.
|
||||
* This partial sector could be mistaken for a conflicted sector, if
|
||||
* whatever data read happens to match the checksum of 0, which is
|
||||
* rare, but has been observed on some disks.
|
||||
*/
|
||||
if (now > (_fmr->getDuration() - 21e6)) {
|
||||
_fmr->seekToIndexMark();
|
||||
return(UNKNOWN_RECORD);
|
||||
}
|
||||
|
||||
int msSinceIndex = std::round(now / 1e6);
|
||||
|
||||
const FluxMatcher* matcher = nullptr;
|
||||
|
||||
/* Note that the seekToPattern ignores the sector pulses, so if
|
||||
* a sector is not found for some reason, the seek will advance
|
||||
* past one or more sector pulses. For this reason, calculate
|
||||
* _hardSectorId after the sector header is found.
|
||||
*/
|
||||
_sector->clock = _fmr->seekToPattern(ANY_SECTOR_PATTERN, matcher);
|
||||
|
||||
int sectorFoundTimeRaw = std::round((_fmr->tell().ns()) / 1e6);
|
||||
int sectorFoundTime;
|
||||
|
||||
/* Round time to the nearest 20ms */
|
||||
if ((sectorFoundTimeRaw % 20) < 10) {
|
||||
sectorFoundTime = (sectorFoundTimeRaw / 20) * 20;
|
||||
}
|
||||
else {
|
||||
sectorFoundTime = ((sectorFoundTimeRaw + 20) / 20) * 20;
|
||||
}
|
||||
|
||||
/* Calculate the sector ID based on time since the index */
|
||||
_hardSectorId = (sectorFoundTime / 20) % 10;
|
||||
|
||||
// std::cout << fmt::format(
|
||||
// "Sector ID {}: hole at {}ms, sector start at {}ms",
|
||||
// _hardSectorId, msSinceIndex, sectorFoundTimeRaw) << std::endl;
|
||||
|
||||
if (matcher == &MFM_PATTERN) {
|
||||
_sectorType = SECTOR_TYPE_MFM;
|
||||
readRawBits(48);
|
||||
return SECTOR_RECORD;
|
||||
}
|
||||
|
||||
if (matcher == &FM_PATTERN) {
|
||||
_sectorType = SECTOR_TYPE_FM;
|
||||
readRawBits(48);
|
||||
return SECTOR_RECORD;
|
||||
}
|
||||
|
||||
return UNKNOWN_RECORD;
|
||||
}
|
||||
|
||||
/* Checksum is initially 0.
|
||||
* For each data byte, XOR with the current checksum.
|
||||
* Rotate checksum left, carrying bit 7 to bit 0.
|
||||
*/
|
||||
uint8_t northstarChecksum(const Bytes& bytes) {
|
||||
ByteReader br(bytes);
|
||||
uint8_t checksum = 0;
|
||||
|
||||
while (!br.eof()) {
|
||||
checksum ^= br.read_8();
|
||||
checksum = ((checksum << 1) | ((checksum >> 7)));
|
||||
}
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
void NorthstarDecoder::decodeSectorRecord()
|
||||
{
|
||||
unsigned recordSize, payloadSize, headerSize;
|
||||
|
||||
if (_sectorType == SECTOR_TYPE_MFM) {
|
||||
recordSize = NORTHSTAR_ENCODED_SECTOR_SIZE_DD;
|
||||
payloadSize = NORTHSTAR_PAYLOAD_SIZE_DD;
|
||||
headerSize = NORTHSTAR_HEADER_SIZE_DD;
|
||||
}
|
||||
else {
|
||||
recordSize = NORTHSTAR_ENCODED_SECTOR_SIZE_SD;
|
||||
payloadSize = NORTHSTAR_PAYLOAD_SIZE_SD;
|
||||
headerSize = NORTHSTAR_HEADER_SIZE_SD;
|
||||
}
|
||||
|
||||
auto rawbits = readRawBits(recordSize * 16);
|
||||
auto bytes = decodeFmMfm(rawbits).slice(0, recordSize);
|
||||
ByteReader br(bytes);
|
||||
uint8_t sync_char;
|
||||
|
||||
_sector->logicalSide = _sector->physicalSide;
|
||||
_sector->logicalSector = _hardSectorId;
|
||||
_sector->logicalTrack = _sector->physicalTrack;
|
||||
|
||||
sync_char = br.read_8(); /* Sync char: 0xFB */
|
||||
if (_sectorType == SECTOR_TYPE_MFM) {
|
||||
sync_char = br.read_8();/* MFM second Sync char, usually 0xFB */
|
||||
}
|
||||
|
||||
_sector->data = br.read(payloadSize);
|
||||
|
||||
uint8_t wantChecksum = br.read_8();
|
||||
uint8_t gotChecksum = northstarChecksum(bytes.slice(headerSize, payloadSize));
|
||||
|
||||
_sector->status = (wantChecksum == gotChecksum) ? Sector::OK : Sector::BAD_CHECKSUM;
|
||||
}
|
||||
|
||||
std::set<unsigned> NorthstarDecoder::requiredSectors(Track& track) const
|
||||
{
|
||||
static std::set<unsigned> sectors = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
return sectors;
|
||||
}
|
||||
130
arch/northstar/encoder.cc
Normal file
130
arch/northstar/encoder.cc
Normal file
@@ -0,0 +1,130 @@
|
||||
#include "globals.h"
|
||||
#include "northstar.h"
|
||||
#include "sectorset.h"
|
||||
|
||||
#define GAP_FILL_SIZE_SD 30
|
||||
#define PRE_HEADER_GAP_FILL_SIZE_SD 9
|
||||
#define GAP_FILL_SIZE_DD 62
|
||||
#define PRE_HEADER_GAP_FILL_SIZE_DD 16
|
||||
|
||||
#define GAP1_FILL_BYTE (0x4F)
|
||||
#define GAP2_FILL_BYTE (0x4F)
|
||||
|
||||
#define TOTAL_SECTOR_BYTES ()
|
||||
|
||||
static void write_sector(std::vector<bool>& bits, unsigned& cursor, const Sector* sector)
|
||||
{
|
||||
int preambleSize = 0;
|
||||
int encodedSectorSize = 0;
|
||||
int gapFillSize = 0;
|
||||
int preHeaderGapFillSize = 0;
|
||||
|
||||
bool doubleDensity;
|
||||
|
||||
switch (sector->data.size()) {
|
||||
case NORTHSTAR_PAYLOAD_SIZE_SD:
|
||||
preambleSize = NORTHSTAR_PREAMBLE_SIZE_SD;
|
||||
encodedSectorSize = PRE_HEADER_GAP_FILL_SIZE_SD + NORTHSTAR_ENCODED_SECTOR_SIZE_SD + GAP_FILL_SIZE_SD;
|
||||
gapFillSize = GAP_FILL_SIZE_SD;
|
||||
preHeaderGapFillSize = PRE_HEADER_GAP_FILL_SIZE_SD;
|
||||
doubleDensity = false;
|
||||
break;
|
||||
case NORTHSTAR_PAYLOAD_SIZE_DD:
|
||||
preambleSize = NORTHSTAR_PREAMBLE_SIZE_DD;
|
||||
encodedSectorSize = PRE_HEADER_GAP_FILL_SIZE_DD + NORTHSTAR_ENCODED_SECTOR_SIZE_DD + GAP_FILL_SIZE_DD;
|
||||
gapFillSize = GAP_FILL_SIZE_DD;
|
||||
preHeaderGapFillSize = PRE_HEADER_GAP_FILL_SIZE_DD;
|
||||
doubleDensity = true;
|
||||
break;
|
||||
default:
|
||||
Error() << "unsupported sector size --- you must pick 256 or 512";
|
||||
break;
|
||||
}
|
||||
|
||||
int fullSectorSize = preambleSize + encodedSectorSize;
|
||||
auto fullSector = std::make_shared<std::vector<uint8_t>>();
|
||||
fullSector->reserve(fullSectorSize);
|
||||
|
||||
/* sector gap after index pulse */
|
||||
for (int i = 0; i < preHeaderGapFillSize; i++)
|
||||
fullSector->push_back(GAP1_FILL_BYTE);
|
||||
|
||||
/* sector preamble */
|
||||
for (int i = 0; i < preambleSize; i++)
|
||||
fullSector->push_back(0);
|
||||
|
||||
Bytes sectorData;
|
||||
if (sector->data.size() == encodedSectorSize)
|
||||
sectorData = sector->data;
|
||||
else {
|
||||
ByteWriter writer(sectorData);
|
||||
writer.write_8(0xFB); /* sync character */
|
||||
if (doubleDensity == true) {
|
||||
writer.write_8(0xFB); /* Double-density has two sync characters */
|
||||
}
|
||||
writer += sector->data;
|
||||
if (doubleDensity == true) {
|
||||
writer.write_8(northstarChecksum(sectorData.slice(2)));
|
||||
} else {
|
||||
writer.write_8(northstarChecksum(sectorData.slice(1)));
|
||||
}
|
||||
}
|
||||
for (uint8_t b : sectorData)
|
||||
fullSector->push_back(b);
|
||||
|
||||
if (sector->logicalSector != 9) {
|
||||
/* sector postamble */
|
||||
for (int i = 0; i < gapFillSize; i++)
|
||||
fullSector->push_back(GAP2_FILL_BYTE);
|
||||
|
||||
if (fullSector->size() != fullSectorSize)
|
||||
Error() << "sector mismatched length (" << sector->data.size() << ") expected: " << fullSector->size() << " got " << fullSectorSize;
|
||||
} else {
|
||||
/* sector postamble */
|
||||
for (int i = 0; i < gapFillSize; i++)
|
||||
fullSector->push_back(GAP2_FILL_BYTE);
|
||||
}
|
||||
|
||||
bool lastBit = false;
|
||||
|
||||
if (doubleDensity == true) {
|
||||
encodeMfm(bits, cursor, fullSector, lastBit);
|
||||
}
|
||||
else {
|
||||
encodeFm(bits, cursor, fullSector);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Fluxmap> NorthstarEncoder::encode(
|
||||
int physicalTrack, int physicalSide, const SectorSet& allSectors)
|
||||
{
|
||||
int bitsPerRevolution = 100000;
|
||||
double clockRateUs = 4.00;
|
||||
|
||||
if ((physicalTrack < 0) || (physicalTrack >= 35))
|
||||
return std::unique_ptr<Fluxmap>();
|
||||
|
||||
const auto& sector = allSectors.get(physicalTrack, physicalSide, 0);
|
||||
|
||||
if (sector->data.size() == NORTHSTAR_PAYLOAD_SIZE_SD) {
|
||||
bitsPerRevolution /= 2; // FM
|
||||
} else {
|
||||
clockRateUs /= 2.00;
|
||||
}
|
||||
|
||||
std::vector<bool> bits(bitsPerRevolution);
|
||||
unsigned cursor = 0;
|
||||
|
||||
for (int sectorId = 0; sectorId < 10; sectorId++)
|
||||
{
|
||||
const auto& sectorData = allSectors.get(physicalTrack, physicalSide, sectorId);
|
||||
write_sector(bits, cursor, sectorData);
|
||||
}
|
||||
|
||||
if (cursor > bits.size())
|
||||
Error() << "track data overrun";
|
||||
|
||||
std::unique_ptr<Fluxmap> fluxmap(new Fluxmap);
|
||||
fluxmap->appendBits(bits, clockRateUs * 1e3);
|
||||
return fluxmap;
|
||||
}
|
||||
72
arch/northstar/northstar.h
Normal file
72
arch/northstar/northstar.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef NORTHSTAR_H
|
||||
#define NORTHSTAR_H
|
||||
|
||||
/* Northstar floppies are 10-hard sectored disks with a sector format as follows:
|
||||
*
|
||||
* |----------------------------------|
|
||||
* | SYNC Byte | Payload | Checksum |
|
||||
* |------------+----------+----------|
|
||||
* | 1 (0xFB) | 256 (SD) | 1 |
|
||||
* | 2 (0xFBFB) | 512 (DD) | |
|
||||
* |----------------------------------|
|
||||
*
|
||||
*/
|
||||
|
||||
#include "decoders/decoders.h"
|
||||
#include "encoders/encoders.h"
|
||||
|
||||
#define NORTHSTAR_PREAMBLE_SIZE_SD (16)
|
||||
#define NORTHSTAR_PREAMBLE_SIZE_DD (32)
|
||||
#define NORTHSTAR_HEADER_SIZE_SD (1)
|
||||
#define NORTHSTAR_HEADER_SIZE_DD (2)
|
||||
#define NORTHSTAR_PAYLOAD_SIZE_SD (256)
|
||||
#define NORTHSTAR_PAYLOAD_SIZE_DD (512)
|
||||
#define NORTHSTAR_CHECKSUM_SIZE (1)
|
||||
#define NORTHSTAR_ENCODED_SECTOR_SIZE_SD (NORTHSTAR_HEADER_SIZE_SD + NORTHSTAR_PAYLOAD_SIZE_SD + NORTHSTAR_CHECKSUM_SIZE)
|
||||
#define NORTHSTAR_ENCODED_SECTOR_SIZE_DD (NORTHSTAR_HEADER_SIZE_DD + NORTHSTAR_PAYLOAD_SIZE_DD + NORTHSTAR_CHECKSUM_SIZE)
|
||||
|
||||
#define SECTOR_TYPE_MFM (0)
|
||||
#define SECTOR_TYPE_FM (1)
|
||||
|
||||
class NorthstarEncoderProto;
|
||||
class NorthstarDecoderProto;
|
||||
|
||||
class NorthstarDecoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
NorthstarDecoder(const NorthstarDecoderProto& config):
|
||||
_config(config)
|
||||
{
|
||||
_sectorType = SECTOR_TYPE_MFM;
|
||||
}
|
||||
|
||||
virtual ~NorthstarDecoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
void decodeSectorRecord();
|
||||
std::set<unsigned> requiredSectors(Track& track) const;
|
||||
|
||||
private:
|
||||
const NorthstarDecoderProto& _config;
|
||||
uint8_t _sectorType;
|
||||
uint8_t _hardSectorId;
|
||||
};
|
||||
|
||||
class NorthstarEncoder : public AbstractEncoder
|
||||
{
|
||||
public:
|
||||
NorthstarEncoder(const NorthstarEncoderProto& config):
|
||||
_config(config)
|
||||
{}
|
||||
|
||||
virtual ~NorthstarEncoder() {}
|
||||
std::unique_ptr<Fluxmap> encode(int physicalTrack, int physicalSide, const SectorSet& allSectors);
|
||||
|
||||
private:
|
||||
const NorthstarEncoderProto& _config;
|
||||
};
|
||||
|
||||
extern FlagGroup northstarEncoderFlags;
|
||||
extern uint8_t northstarChecksum(const Bytes& bytes);
|
||||
|
||||
#endif /* NORTHSTAR */
|
||||
5
arch/northstar/northstar.proto
Normal file
5
arch/northstar/northstar.proto
Normal file
@@ -0,0 +1,5 @@
|
||||
syntax = "proto2";
|
||||
|
||||
message NorthstarDecoderProto {}
|
||||
message NorthstarEncoderProto {}
|
||||
|
||||
@@ -40,7 +40,7 @@ const FluxPattern DATA_RECORD_PATTERN(32, 0x11112245);
|
||||
|
||||
const FluxMatchers ANY_RECORD_PATTERN({ &SECTOR_RECORD_PATTERN, &DATA_RECORD_PATTERN });
|
||||
|
||||
AbstractDecoder::RecordType TiDs990Decoder::advanceToNextRecord()
|
||||
AbstractDecoder::RecordType Tids990Decoder::advanceToNextRecord()
|
||||
{
|
||||
const FluxMatcher* matcher = nullptr;
|
||||
_sector->clock = _fmr->seekToPattern(ANY_RECORD_PATTERN, matcher);
|
||||
@@ -51,7 +51,7 @@ AbstractDecoder::RecordType TiDs990Decoder::advanceToNextRecord()
|
||||
return RecordType::UNKNOWN_RECORD;
|
||||
}
|
||||
|
||||
void TiDs990Decoder::decodeSectorRecord()
|
||||
void Tids990Decoder::decodeSectorRecord()
|
||||
{
|
||||
auto bits = readRawBits(TIDS990_SECTOR_RECORD_SIZE*16);
|
||||
auto bytes = decodeFmMfm(bits).slice(0, TIDS990_SECTOR_RECORD_SIZE);
|
||||
@@ -71,7 +71,7 @@ void TiDs990Decoder::decodeSectorRecord()
|
||||
_sector->status = Sector::DATA_MISSING; /* correct but unintuitive */
|
||||
}
|
||||
|
||||
void TiDs990Decoder::decodeDataRecord()
|
||||
void Tids990Decoder::decodeDataRecord()
|
||||
{
|
||||
auto bits = readRawBits(TIDS990_DATA_RECORD_SIZE*16);
|
||||
auto bytes = decodeFmMfm(bits).slice(0, TIDS990_DATA_RECORD_SIZE);
|
||||
|
||||
@@ -6,55 +6,9 @@
|
||||
#include "crc.h"
|
||||
#include "sectorset.h"
|
||||
#include "writer.h"
|
||||
#include "arch/tids990/tids990.pb.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
FlagGroup tids990EncoderFlags;
|
||||
|
||||
static IntFlag trackLengthMs(
|
||||
{ "--tids990-track-length-ms" },
|
||||
"Length of a track in milliseconds.",
|
||||
166);
|
||||
|
||||
static IntFlag sectorCount(
|
||||
{ "--tids990-sector-count" },
|
||||
"Number of sectors per track.",
|
||||
26);
|
||||
|
||||
static IntFlag clockRateKhz(
|
||||
{ "--tids990-clock-rate-khz" },
|
||||
"Clock rate of data to write.",
|
||||
500);
|
||||
|
||||
static HexIntFlag am1Byte(
|
||||
{ "--tids990-am1-byte" },
|
||||
"16-bit RAW bit pattern to use for the AM1 ID byte",
|
||||
0x2244);
|
||||
|
||||
static HexIntFlag am2Byte(
|
||||
{ "--tids990-am2-byte" },
|
||||
"16-bit RAW bit pattern to use for the AM2 ID byte",
|
||||
0x2245);
|
||||
|
||||
static IntFlag gap1(
|
||||
{ "--tids990-gap1-bytes" },
|
||||
"Size of gap 1 (the post-index gap).",
|
||||
80);
|
||||
|
||||
static IntFlag gap2(
|
||||
{ "--tids990-gap2-bytes" },
|
||||
"Size of gap 2 (the post-ID gap).",
|
||||
21);
|
||||
|
||||
static IntFlag gap3(
|
||||
{ "--tids990-gap3-bytes" },
|
||||
"Size of gap 3 (the post-data or format gap).",
|
||||
51);
|
||||
|
||||
static StringFlag sectorSkew(
|
||||
{ "--tids990-sector-skew" },
|
||||
"Order to emit sectors.",
|
||||
"1mhc72nid83oje94pkfa50lgb6");
|
||||
|
||||
static int charToInt(char c)
|
||||
{
|
||||
if (isdigit(c))
|
||||
@@ -62,7 +16,7 @@ static int charToInt(char c)
|
||||
return 10 + tolower(c) - 'a';
|
||||
}
|
||||
|
||||
void TiDs990Encoder::writeRawBits(uint32_t data, int width)
|
||||
void Tids990Encoder::writeRawBits(uint32_t data, int width)
|
||||
{
|
||||
_cursor += width;
|
||||
_lastBit = data & 1;
|
||||
@@ -75,12 +29,12 @@ void TiDs990Encoder::writeRawBits(uint32_t data, int width)
|
||||
}
|
||||
}
|
||||
|
||||
void TiDs990Encoder::writeBytes(const Bytes& bytes)
|
||||
void Tids990Encoder::writeBytes(const Bytes& bytes)
|
||||
{
|
||||
encodeMfm(_bits, _cursor, bytes, _lastBit);
|
||||
}
|
||||
|
||||
void TiDs990Encoder::writeBytes(int count, uint8_t byte)
|
||||
void Tids990Encoder::writeBytes(int count, uint8_t byte)
|
||||
{
|
||||
Bytes bytes = { byte };
|
||||
for (int i=0; i<count; i++)
|
||||
@@ -95,25 +49,25 @@ static uint8_t decodeUint16(uint16_t raw)
|
||||
return decodeFmMfm(b.toBits())[0];
|
||||
}
|
||||
|
||||
std::unique_ptr<Fluxmap> TiDs990Encoder::encode(
|
||||
std::unique_ptr<Fluxmap> Tids990Encoder::encode(
|
||||
int physicalTrack, int physicalSide, const SectorSet& allSectors)
|
||||
{
|
||||
double clockRateUs = 1e3 / clockRateKhz / 2.0;
|
||||
int bitsPerRevolution = (trackLengthMs * 1000.0) / clockRateUs;
|
||||
double clockRateUs = 1e3 / _config.clock_rate_khz() / 2.0;
|
||||
int bitsPerRevolution = (_config.track_length_ms() * 1000.0) / clockRateUs;
|
||||
_bits.resize(bitsPerRevolution);
|
||||
_cursor = 0;
|
||||
|
||||
uint8_t am1Unencoded = decodeUint16(am1Byte);
|
||||
uint8_t am2Unencoded = decodeUint16(am2Byte);
|
||||
uint8_t am1Unencoded = decodeUint16(_config.am1_byte());
|
||||
uint8_t am2Unencoded = decodeUint16(_config.am2_byte());
|
||||
|
||||
writeBytes(gap1, 0x55);
|
||||
writeBytes(_config.gap1_bytes(), 0x55);
|
||||
|
||||
bool first = true;
|
||||
for (char sectorChar : sectorSkew.get())
|
||||
for (char sectorChar : _config.sector_skew())
|
||||
{
|
||||
int sectorId = charToInt(sectorChar);
|
||||
if (!first)
|
||||
writeBytes(gap3, 0x55);
|
||||
writeBytes(_config.gap3_bytes(), 0x55);
|
||||
first = false;
|
||||
|
||||
const auto& sectorData = allSectors.get(physicalTrack, physicalSide, sectorId);
|
||||
@@ -136,17 +90,17 @@ std::unique_ptr<Fluxmap> TiDs990Encoder::encode(
|
||||
bw.write_8(am1Unencoded);
|
||||
bw.write_8(sectorData->logicalSide << 3);
|
||||
bw.write_8(sectorData->logicalTrack);
|
||||
bw.write_8(sectorCount);
|
||||
bw.write_8(_config.sector_count());
|
||||
bw.write_8(sectorData->logicalSector);
|
||||
bw.write_be16(sectorData->data.size());
|
||||
uint16_t crc = crc16(CCITT_POLY, header);
|
||||
bw.write_be16(crc);
|
||||
|
||||
writeRawBits(am1Byte, 16);
|
||||
writeRawBits(_config.am1_byte(), 16);
|
||||
writeBytes(header.slice(1));
|
||||
}
|
||||
|
||||
writeBytes(gap2, 0x55);
|
||||
writeBytes(_config.gap2_bytes(), 0x55);
|
||||
|
||||
{
|
||||
Bytes data;
|
||||
@@ -159,7 +113,7 @@ std::unique_ptr<Fluxmap> TiDs990Encoder::encode(
|
||||
uint16_t crc = crc16(CCITT_POLY, data);
|
||||
bw.write_be16(crc);
|
||||
|
||||
writeRawBits(am2Byte, 16);
|
||||
writeRawBits(_config.am2_byte(), 16);
|
||||
writeBytes(data.slice(1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,21 +9,27 @@ class Sector;
|
||||
class SectorSet;
|
||||
class Fluxmap;
|
||||
class Track;
|
||||
class Tids990DecoderProto;
|
||||
class Tids990EncoderProto;
|
||||
|
||||
class TiDs990Decoder : public AbstractDecoder
|
||||
class Tids990Decoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
virtual ~TiDs990Decoder() {}
|
||||
Tids990Decoder(const Tids990DecoderProto&) {}
|
||||
virtual ~Tids990Decoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
void decodeSectorRecord();
|
||||
void decodeDataRecord();
|
||||
};
|
||||
|
||||
class TiDs990Encoder : public AbstractEncoder
|
||||
class Tids990Encoder : public AbstractEncoder
|
||||
{
|
||||
public:
|
||||
virtual ~TiDs990Encoder() {}
|
||||
Tids990Encoder(const Tids990EncoderProto& config):
|
||||
_config(config)
|
||||
{}
|
||||
virtual ~Tids990Encoder() {}
|
||||
|
||||
private:
|
||||
void writeRawBits(uint32_t data, int width);
|
||||
@@ -35,6 +41,7 @@ public:
|
||||
std::unique_ptr<Fluxmap> encode(int physicalTrack, int physicalSide, const SectorSet& allSectors);
|
||||
|
||||
private:
|
||||
const Tids990EncoderProto& _config;
|
||||
std::vector<bool> _bits;
|
||||
unsigned _cursor;
|
||||
bool _lastBit;
|
||||
|
||||
26
arch/tids990/tids990.proto
Normal file
26
arch/tids990/tids990.proto
Normal file
@@ -0,0 +1,26 @@
|
||||
syntax = "proto2";
|
||||
|
||||
import "lib/common.proto";
|
||||
|
||||
message Tids990DecoderProto {}
|
||||
message Tids990EncoderProto {
|
||||
optional double track_length_ms = 1 [ default = 166,
|
||||
(help) = "length of a track" ];
|
||||
optional int32 sector_count = 2 [ default = 26,
|
||||
(help) = "number of sectors per track" ];
|
||||
optional double clock_rate_khz = 3 [ default = 500,
|
||||
(help) = "clock rate of data to write" ];
|
||||
optional int32 am1_byte = 4 [ default = 0x2244,
|
||||
(help) = "16-bit RAW bit pattern to use for the AM1 ID byte" ];
|
||||
optional int32 am2_byte = 5 [ default = 0x2245,
|
||||
(help) = "16-bit RAW bit pattern to use for the AM2 ID byte" ];
|
||||
optional int32 gap1_bytes = 6 [ default = 80,
|
||||
(help) = "size of gap 1 (the post-index gap)" ];
|
||||
optional int32 gap2_bytes = 7 [ default = 21,
|
||||
(help) = "size of gap 2 (the post-ID gap)" ];
|
||||
optional int32 gap3_bytes = 8 [ default = 51,
|
||||
(help) = "size of gap 3 (the post-data or format gap)" ];
|
||||
optional string sector_skew = 9 [ default = "1mhc72nid83oje94pkfa50lgb6",
|
||||
(help) = "order to emit sectors" ];
|
||||
}
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
|
||||
class Sector;
|
||||
class Fluxmap;
|
||||
class Victor9kDecoderProto;
|
||||
|
||||
class Victor9kDecoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
Victor9kDecoder(const Victor9kDecoderProto&) {}
|
||||
virtual ~Victor9kDecoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
|
||||
4
arch/victor9k/victor9k.proto
Normal file
4
arch/victor9k/victor9k.proto
Normal file
@@ -0,0 +1,4 @@
|
||||
syntax = "proto2";
|
||||
|
||||
message Victor9kDecoderProto {}
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
|
||||
class Sector;
|
||||
class Fluxmap;
|
||||
class ZilogMczDecoderProto;
|
||||
|
||||
class ZilogMczDecoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
ZilogMczDecoder(const ZilogMczDecoderProto&) {}
|
||||
virtual ~ZilogMczDecoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
|
||||
4
arch/zilogmcz/zilogmcz.proto
Normal file
4
arch/zilogmcz/zilogmcz.proto
Normal file
@@ -0,0 +1,4 @@
|
||||
syntax = "proto2";
|
||||
|
||||
message ZilogMczDecoderProto {}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace agg
|
||||
template<class FilterF> void calculate(const FilterF& filter,
|
||||
bool normalization=true)
|
||||
{
|
||||
filter; // prevent erroneous C4100 in MSVC
|
||||
(void)filter; // prevent erroneous C4100 in MSVC
|
||||
double r = filter.radius();
|
||||
realloc_lut(r);
|
||||
unsigned i;
|
||||
|
||||
49
dep/snowhouse/CMakeLists.txt
Normal file
49
dep/snowhouse/CMakeLists.txt
Normal file
@@ -0,0 +1,49 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
project(snowhouse)
|
||||
|
||||
option(SNOWHOUSE_BUILD_TESTS "Build the Snowhouse tests" OFF)
|
||||
option(SNOWHOUSE_RUN_TESTS "Run the Snowhouse tests" OFF)
|
||||
set(SNOWHOUSE_CXX_STANDARD "C++11" CACHE STRING "The C++ standard the examples are compiled with")
|
||||
set_property(CACHE SNOWHOUSE_CXX_STANDARD PROPERTY STRINGS "C++11" "C++14" "C++17")
|
||||
|
||||
add_library(snowhouse INTERFACE)
|
||||
target_include_directories(snowhouse INTERFACE include)
|
||||
|
||||
if(SNOWHOUSE_CXX_STANDARD STREQUAL "C++11")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
elseif(SNOWHOUSE_CXX_STANDARD STREQUAL "C++14")
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
elseif(SNOWHOUSE_CXX_STANDARD STREQUAL "C++17")
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
else()
|
||||
message(WARNING "C++ standard \"${SNOWHOUSE_CXX_STANDARD}\" not known, falling back to default")
|
||||
endif()
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ./bin)
|
||||
|
||||
if (MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /MP ")
|
||||
else()
|
||||
# Assume GCC-style arguments
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
|
||||
-Wall -Wextra -pedantic -Wdeprecated -Wdeprecated-declarations -Wnon-virtual-dtor \
|
||||
-Wshadow -Wfloat-equal -Wundef -Wendif-labels -Wno-error=unknown-pragmas")
|
||||
endif()
|
||||
|
||||
message(STATUS "C++ compiler flags: ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
if (SNOWHOUSE_BUILD_TESTS)
|
||||
FILE(GLOB SnowhouseSpecSourceFiles example/*.cpp)
|
||||
add_executable(snowhouse-tests ${SnowhouseSpecSourceFiles})
|
||||
target_link_libraries(snowhouse-tests PRIVATE snowhouse)
|
||||
endif()
|
||||
|
||||
if (SNOWHOUSE_BUILD_TESTS AND SNOWHOUSE_RUN_TESTS)
|
||||
add_custom_command(TARGET snowhouse-tests
|
||||
POST_BUILD
|
||||
COMMAND snowhouse-tests
|
||||
WORKING_DIRECTORY ./bin)
|
||||
elseif (SNOWHOUSE_RUN_TESTS)
|
||||
message(WARNING "Unable to run snowhouse tests - set:\n option(SNOWHOUSE_BUILD_TESTS, \"Build the Snowhouse tests\" ON)\nand clear your CMakeCache.txt")
|
||||
endif()
|
||||
23
dep/snowhouse/LICENSE_1_0.txt
Normal file
23
dep/snowhouse/LICENSE_1_0.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
560
dep/snowhouse/README.md
Normal file
560
dep/snowhouse/README.md
Normal file
@@ -0,0 +1,560 @@
|
||||
snowhouse
|
||||
=========
|
||||
[](https://travis-ci.org/banditcpp/snowhouse)
|
||||
[](https://ci.appveyor.com/project/banditcpp/snowhouse)
|
||||
[](https://github.com/banditcpp/snowhouse/actions?query=workflow%3ACI+branch%3Amaster)
|
||||
[](https://www.codacy.com/app/sbeyer/snowhouse?utm_source=github.com&utm_medium=referral&utm_content=banditcpp/snowhouse&utm_campaign=Badge_Grade)
|
||||
|
||||
An assertion library for C++
|
||||
|
||||
Snowhouse is a stand-alone assertion framework for C++.
|
||||
It is a header-only library.
|
||||
|
||||
Snowhouse requires a C++11-compatible compiler since version 5.0.0.
|
||||
Feel free to use Snowhouse with major version 4 if you want to use it
|
||||
in a pre-C++11 setting.
|
||||
Major version 4 is still maintained in the `maint-v4` branch (bug fixes, etc.).
|
||||
|
||||
For inclusion in your projects, you have several options:
|
||||
|
||||
a) You can copy the code and just use it as the license allows.
|
||||
|
||||
b) You can use the `headers-only` branch as a submodule:
|
||||
|
||||
```sh
|
||||
git submodule add -b headers-only https://github.com/banditcpp/snowhouse snowhouse
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
c) If you use CMake >= 3.1 in your project,
|
||||
you can use Snowhouse with the provided library target.
|
||||
Assuming you have cloned the `master` branch into a `snowhouse` subdirectory,
|
||||
your `CMakeLists.txt` might contain lines like the following:
|
||||
|
||||
```cmake
|
||||
add_subdirectory(snowhouse)
|
||||
add_executable(app main.cpp)
|
||||
target_link_libraries(app snowhouse)
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```C++
|
||||
#include <snowhouse/snowhouse.h>
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "Testing that 23 is 23" << std::endl;
|
||||
AssertThat(23, Is().EqualTo(23));
|
||||
|
||||
try
|
||||
{
|
||||
AssertThat(12, Is().LessThan(11).And().GreaterThan(99));
|
||||
}
|
||||
catch (const AssertionException& ex)
|
||||
{
|
||||
std::cout << "Apparently this failed:" << std::endl;
|
||||
std::cout << ex.what() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### Assertions
|
||||
|
||||
Snowhouse uses a constraint-based assertion model that is heavily inspired by the
|
||||
model used in [NUnit](http://nunit.org/). An assertion in Snowhouse is written
|
||||
using the following format:
|
||||
|
||||
```cpp
|
||||
AssertThat(actual_value, <constraint expression>);
|
||||
```
|
||||
|
||||
where `<constraint expression>` is an expression that `actual_value` is
|
||||
evaluated against when the test is executed.
|
||||
|
||||
Constraint expressions come in two basic forms: composite and fluent expressions.
|
||||
|
||||
#### Composite Expressions
|
||||
|
||||
With composite expressions, you can create compact, powerful expressions that
|
||||
combine a set of predefined constraints with ones that you provide yourself.
|
||||
|
||||
Example:
|
||||
|
||||
```cpp
|
||||
AssertThat(length, IsGreaterThan(4) && !Equals(10));
|
||||
```
|
||||
|
||||
Composite expressions can be any combination of constraints and the
|
||||
standard logical C++ operators.
|
||||
|
||||
You can also add your own constraints to be used within composite expressions.
|
||||
|
||||
#### Fluent Expressions
|
||||
|
||||
With fluent expressions, you can create assertions that better convey the intent
|
||||
of a test without exposing implementation-specific details.
|
||||
Fluent expressions aim to help you create tests that are not just by developers
|
||||
for developers, but rather can be read and understood by domain experts.
|
||||
|
||||
Fluent expressions also have the ability to make assertions on the elements in a
|
||||
container in a way you cannot achieve with composite expressions.
|
||||
|
||||
Example:
|
||||
|
||||
```cpp
|
||||
AssertThat(length, Is().GreaterThan(4).And().Not().EqualTo(10));
|
||||
```
|
||||
|
||||
### Basic Constraints
|
||||
|
||||
#### Equality Constraint
|
||||
|
||||
Used to verify equality between actual and expected.
|
||||
|
||||
```cpp
|
||||
AssertThat(x, Equals(12));
|
||||
AssertThat(x, Is().EqualTo(12));
|
||||
```
|
||||
|
||||
#### EqualityWithDelta Constraint
|
||||
|
||||
Used to verify equality between actual and expected,
|
||||
allowing the two to differ by a delta.
|
||||
|
||||
```cpp
|
||||
AssertThat(2.49, EqualsWithDelta(2.5, 0.1));
|
||||
AssertThat(2.49, Is().EqualToWithDelta(2.5, 0.1));
|
||||
```
|
||||
|
||||
#### GreaterThan Constraint
|
||||
|
||||
Used to verify that actual is greater than a value.
|
||||
|
||||
```cpp
|
||||
AssertThat(x, IsGreaterThan(4));
|
||||
AssertThat(x, Is().GreaterThan(4));
|
||||
```
|
||||
|
||||
#### LessThan Constraint
|
||||
|
||||
Used to verify that actual is less than a value.
|
||||
|
||||
```cpp
|
||||
AssertThat(x, IsLessThan(3));
|
||||
AssertThat(x, Is().LessThan(3));
|
||||
```
|
||||
|
||||
#### GreaterThanOrEqualTo Constraint
|
||||
|
||||
Used to verify that actual is greater than or equal to a value.
|
||||
|
||||
```cpp
|
||||
AssertThat(x, IsGreaterThanOrEqualTo(5));
|
||||
AssertThat(x, Is().GreaterThanOrEqualTo(5));
|
||||
```
|
||||
|
||||
#### LessThanOrEqualTo Constraint
|
||||
|
||||
Used to verify that actual is less than or equal to a value.
|
||||
|
||||
```cpp
|
||||
AssertThat(x, IsLessThanOrEqualTo(6));
|
||||
AssertThat(x, Is().LessThanOrEqualTo(6));
|
||||
```
|
||||
|
||||
### Pointer Constraints
|
||||
|
||||
Used to check for `nullptr` equality.
|
||||
|
||||
```cpp
|
||||
AssertThat(x, IsNull());
|
||||
AssertThat(x, Is().Null());
|
||||
```
|
||||
|
||||
### String Constraints
|
||||
|
||||
String assertions in Snowhouse are used to verify the values of
|
||||
STL strings (`std::string`).
|
||||
|
||||
#### Equality Constraints
|
||||
|
||||
Used to verify that actual is equal to an expected value.
|
||||
|
||||
```cpp
|
||||
AssertThat(actual_str, Equals("foo"));
|
||||
AssertThat(actual_str, Is().EqualTo("foo"));
|
||||
```
|
||||
|
||||
#### Contains Constraint
|
||||
|
||||
Used to verify that a string contains a substring.
|
||||
|
||||
```cpp
|
||||
AssertThat(actual_str, Contains("foo"));
|
||||
AssertThat(actual_str, Is().Containing("foo"));
|
||||
```
|
||||
|
||||
#### EndsWith Constraint
|
||||
|
||||
Used to verify that a string ends with an expected substring.
|
||||
|
||||
```cpp
|
||||
AssertThat(actual_str, EndsWith("foo"));
|
||||
AssertThat(actual_str, Is().EndingWith("foo"));
|
||||
```
|
||||
|
||||
#### StartsWith Constraint
|
||||
|
||||
Used to verify that a string starts with an expected substring.
|
||||
|
||||
```cpp
|
||||
AssertThat(actual_str, StartsWith("foo"));
|
||||
AssertThat(actual_str, Is().StartingWith("foo"));
|
||||
```
|
||||
|
||||
#### HasLength Constraint
|
||||
|
||||
Used to verify that a string is of the expected length.
|
||||
|
||||
```cpp
|
||||
AssertThat(actual_str, HasLength(5));
|
||||
AssertThat(actual_str, Is().OfLength(5));
|
||||
```
|
||||
|
||||
### Constraints on Multiline Strings
|
||||
|
||||
If you have a string that contains multiple lines, you can use the collection
|
||||
constraints to make assertions on the content of that string.
|
||||
This may be handy if you have a string that, for instance, represents the
|
||||
resulting content of a file or a network transmission.
|
||||
|
||||
Snowhouse can handle both Windows (CR+LF) and Unix (LF) line endings.
|
||||
|
||||
```cpp
|
||||
std::string lines = "First line\r\nSecond line\r\nThird line";
|
||||
AssertThat(lines, Has().Exactly(1).StartingWith("Second"));
|
||||
```
|
||||
|
||||
### Container Constraints
|
||||
|
||||
The following constraints can be applied to containers in the standard template library.
|
||||
|
||||
#### Contains Constraint
|
||||
|
||||
Used to verify that a container contains an expected value.
|
||||
|
||||
```cpp
|
||||
AssertThat(container, Contains(12));
|
||||
AssertThat(container, Is().Containing(12));
|
||||
```
|
||||
|
||||
#### HasLength Constraint
|
||||
|
||||
Used to verify that a container has the expected length.
|
||||
|
||||
```cpp
|
||||
AssertThat(container, HasLength(3));
|
||||
AssertThat(container, Is().OfLength(3));
|
||||
```
|
||||
|
||||
#### IsEmpty Constraint
|
||||
|
||||
Used to verify that a container is empty.
|
||||
|
||||
```cpp
|
||||
AssertThat(container, IsEmpty());
|
||||
AssertThat(container, Is().Empty());
|
||||
```
|
||||
|
||||
#### All
|
||||
|
||||
Used to verify that all elements of a STL sequence container matches an expectation.
|
||||
|
||||
```cpp
|
||||
AssertThat(container, Has().All().LessThan(5).Or().EqualTo(66));
|
||||
```
|
||||
|
||||
#### AtLeast
|
||||
|
||||
Used to verify that at least a specified amount of elements in a STL sequence
|
||||
container matches an expectation.
|
||||
|
||||
```cpp
|
||||
AssertThat(container, Has().AtLeast(3).StartingWith("foo"));
|
||||
```
|
||||
|
||||
#### AtMost
|
||||
|
||||
Used to verify that at most a specified amount of elements in a STL sequence
|
||||
container matches an expectation.
|
||||
|
||||
```cpp
|
||||
AssertThat(container, Has().AtMost(2).Not().Containing("failed"));
|
||||
```
|
||||
|
||||
#### Exactly
|
||||
|
||||
Used to verify that a STL sequence container has exactly a specified amount
|
||||
of elements that matches an expectation.
|
||||
|
||||
```cpp
|
||||
AssertThat(container, Has().Exactly(3).GreaterThan(10).And().LessThan(20));
|
||||
```
|
||||
|
||||
#### EqualsContainer
|
||||
|
||||
Used to verify that two STL sequence containers are equal.
|
||||
|
||||
```cpp
|
||||
AssertThat(container1, EqualsContainer(container2));
|
||||
AssertThat(container1, Is().EqualToContainer(container2));
|
||||
```
|
||||
|
||||
##### Predicate functions
|
||||
|
||||
You can supply a predicate function or a functor to `EqualsContainer` to
|
||||
customize how to compare the elements in the two containers.
|
||||
|
||||
With a predicate function:
|
||||
|
||||
```cpp
|
||||
static bool are_my_types_equal(const my_type& lhs, const my_type& rhs)
|
||||
{
|
||||
return lhs.my_val_ == rhs.my_val_;
|
||||
}
|
||||
|
||||
AssertThat(container1, EqualsContainer(container2, are_my_types_equal));
|
||||
```
|
||||
|
||||
With a functor as predicate:
|
||||
|
||||
```cpp
|
||||
struct within_delta
|
||||
{
|
||||
within_delta(int delta) : delta_(delta) {}
|
||||
|
||||
bool operator()(const my_type& lhs, const my_type& rhs) const
|
||||
{
|
||||
return abs(lhs.my_val_ - rhs.my_val_) <= delta_;
|
||||
}
|
||||
|
||||
private:
|
||||
int delta_;
|
||||
};
|
||||
|
||||
AssertThat(container1, Is().EqualToContainer(container1, within_delta(1));
|
||||
```
|
||||
|
||||
### Exceptions
|
||||
|
||||
Exception constraints can be used to verify that your code throws the correct exceptions.
|
||||
|
||||
#### AssertThrows
|
||||
|
||||
`AssertThrows` succeeds if the exception thrown by the call is of the supplied
|
||||
type (or one of its subtypes).
|
||||
|
||||
```cpp
|
||||
AssertThrows(std::logic_error, myObject.a_method(42));
|
||||
```
|
||||
|
||||
#### Making Assertions on the Thrown Exceptions
|
||||
|
||||
If `AssertThrows` succeeds, it will store the thrown exception so that you can
|
||||
make more detailed assertions on it.
|
||||
|
||||
```cpp
|
||||
AssertThrows(std::logic_error, myObject.a_method(42));
|
||||
AssertThat(LastException<std::logic_error>().what(), Is().Containing("logic failure"));
|
||||
```
|
||||
|
||||
The `LastException<>` is available in the scope of the call to `AssertThrows`.
|
||||
An exception is not available between specs in order to avoid the result of
|
||||
one spec contaminating another.
|
||||
|
||||
### Custom Constraints
|
||||
|
||||
You can add your own constraints to Snowhouse to create more expressive specifications.
|
||||
|
||||
#### Fulfills Constraints
|
||||
|
||||
By defining the following matcher
|
||||
|
||||
```cpp
|
||||
struct IsEvenNumber
|
||||
{
|
||||
bool Matches(const int actual) const
|
||||
{
|
||||
return (actual % 2) == 0;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stm, const IsEvenNumber& );
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& stm, const IsEvenNumber& )
|
||||
{
|
||||
stm << "An even number";
|
||||
return stm;
|
||||
}
|
||||
```
|
||||
|
||||
You can create the following constraints in Snowhouse:
|
||||
|
||||
```cpp
|
||||
AssertThat(42, Fulfills(IsEvenNumber()));
|
||||
AssertThat(42, Is().Fulfilling(IsEvenNumber()));
|
||||
```
|
||||
|
||||
Your custom matcher should implement a method called `Matches()` that takes
|
||||
a parameter of the type you expect and returns true if the passed parameter
|
||||
fulfills the constraint.
|
||||
|
||||
To get more expressive failure messages, you should also implement the
|
||||
streaming operator as in the example above.
|
||||
|
||||
## Getting better output for your types
|
||||
|
||||
Whenever Snowhouse prints an error message for a type, it will use the
|
||||
stream operator for that type, otherwise it will print "[unsupported type]"
|
||||
as a placeholder.
|
||||
|
||||
```cpp
|
||||
struct MyType { int x; char c; };
|
||||
|
||||
AssertThat(myType, Fulfills(MyConstraint());
|
||||
```
|
||||
|
||||
Will output the following if the constraint fails:
|
||||
|
||||
```
|
||||
Expected: To fulfill my constraint
|
||||
Actual: [unsupported type]
|
||||
```
|
||||
|
||||
If we add a stream operator:
|
||||
|
||||
```cpp
|
||||
std::ostream& operator<<(std::ostream& stream, const MyType& a)
|
||||
{
|
||||
stream << a.c << a.x;
|
||||
return stream;
|
||||
}
|
||||
```
|
||||
|
||||
the output will be a bit more readable:
|
||||
|
||||
```
|
||||
Expected: To fulfill my constraint
|
||||
Actual: f23
|
||||
```
|
||||
|
||||
If it is necessary to print an object in a different manner than the
|
||||
usual output stream operator provides, for example, to output more detailed
|
||||
information, we can use a specialization of the `Stringizer` class template:
|
||||
|
||||
```cpp
|
||||
namespace snowhouse
|
||||
{
|
||||
template<>
|
||||
struct Stringizer<MyType>
|
||||
{
|
||||
static std::string ToString(const MyType& a)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << "MyType(x = " << a.x << ", c = " << int(a.c) << "('" << a.c << "'))";
|
||||
return stream.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
with output:
|
||||
|
||||
```
|
||||
Expected: To fulfill my constraint
|
||||
Actual: MyType(x = 23, c = 102('f'))
|
||||
```
|
||||
|
||||
## Configurable Failure Handlers
|
||||
|
||||
You can provide Snowhouse with custom failure handlers, for example to
|
||||
call `std::terminate` instead of throwing an exception.
|
||||
See `DefaultFailureHandler` for an example of a failure handler.
|
||||
You can derive your own macros with custom failure handlers using
|
||||
`SNOWHOUSE_ASSERT_THAT` and `SNOWHOUSE_ASSERT_THROWS`.
|
||||
See the definitions of `AssertThat` and `AssertThrows` for examples of these.
|
||||
Define `SNOWHOUSE_NO_MACROS` to disable the unprefixed macros `AssertThat`
|
||||
and `AssertThrows`.
|
||||
|
||||
### Example Use Cases
|
||||
|
||||
#### Assert Program State
|
||||
|
||||
Log an error immediately as we may crash if we try to continue.
|
||||
Do not attempt to unwind the stack as we may be inside a destructor
|
||||
or `nothrow` function.
|
||||
We may want to call `std::terminate`, or attempt to muddle along
|
||||
with the rest of the program.
|
||||
|
||||
#### Assert Program State in Safe Builds
|
||||
|
||||
As above, but only in debug builds.
|
||||
|
||||
#### Test Assert
|
||||
|
||||
Assert that a test behaved as expected.
|
||||
Throw an exception and let our testing framework deal with the test failure.
|
||||
|
||||
## Versioning
|
||||
|
||||
Snowhouse uses [Semantic Versioning 2.0.0](http://semver.org/spec/v2.0.0.html) since
|
||||
version 3.0.0.
|
||||
|
||||
The macros `SNOWHOUSE_MAJOR`, `SNOWHOUSE_MINOR` and `SNOWHOUSE_PATCH` are defined
|
||||
accordingly and `SNOWHOUSE_VERSION` contains the version string.
|
||||
Note that in prior versions `SNOWHOUSE_VERSION` was the only defined macro.
|
||||
|
||||
Compatibility-breaking changes since version 3.0.0:
|
||||
|
||||
* Since version 4.0.0, the display of booleans and strings has changed.
|
||||
Booleans are now displayed as `true` or `false`.
|
||||
Strings are put into quotation marks for improved readability.
|
||||
|
||||
* Since version 5.0.0, the support for C++ versions prior to C++11 are dropped.
|
||||
The definition of the macro `SNOWHOUSE_HAS_NULLPTR` is removed.
|
||||
Our exceptions are now derived from the `std::exception` hierarchy,
|
||||
thus their method names changed.
|
||||
|
||||
## Contributing
|
||||
|
||||
The development of Snowhouse takes place on [GitHub](//github.com/banditcpp/snowhouse).
|
||||
|
||||
Snowhouse is licensed under the Boost Software License.
|
||||
See LICENSE_1_0.txt for further information.
|
||||
|
||||
By making available code for inclusion into Snowhouse (e.g., by opening a
|
||||
pull request on GitHub), you guarantee that the code is licensed under the
|
||||
same license as Snowhouse.
|
||||
|
||||
Please make sure to be consistent with the project's coding style.
|
||||
The `.clang-format` file allows easy checking and implementation of the
|
||||
coding style.
|
||||
|
||||
C++ code should comply to C++11.
|
||||
Please use `__cplusplus` guards if you want to use language features of
|
||||
a certain C++ version.
|
||||
|
||||
## Responsibilities
|
||||
|
||||
Snowhouse was originally developed as part of the [Igloo](//github.com/joakimkarlsson/igloo)
|
||||
testing framework by [Joakim Karlsson](//github.com/joakimkarlsson).
|
||||
It has been extracted to be usable in other contexts, for example,
|
||||
[Bandit](//github.com/banditcpp/bandit).
|
||||
|
||||
Snowhouse is maintained by [Stephan Beyer](//github.com/sbeyer) since
|
||||
[October 2016](//twitter.com/JHKarlsson/status/789332548799332352).
|
||||
222
dep/snowhouse/example/basic_assertions.cpp
Normal file
222
dep/snowhouse/example/basic_assertions.cpp
Normal file
@@ -0,0 +1,222 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
static void throwRuntimeError()
|
||||
{
|
||||
throw std::runtime_error("This is expected");
|
||||
}
|
||||
|
||||
struct IgnoreErrors
|
||||
{
|
||||
template<typename ExpectedType, typename ActualType>
|
||||
static void Handle(const ExpectedType&, const ActualType&, const char*, int)
|
||||
{
|
||||
}
|
||||
|
||||
static void Handle(const std::string&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
void BasicAssertions()
|
||||
{
|
||||
describe("Basic assertions");
|
||||
|
||||
it("handles integer equality");
|
||||
{
|
||||
AssertThat(5, Is().EqualTo(5));
|
||||
}
|
||||
|
||||
it("detects integer inequality");
|
||||
{
|
||||
AssertTestFails(AssertThat(5, Is().EqualTo(4)), "equal to 4");
|
||||
}
|
||||
|
||||
it("detects if Not() fails");
|
||||
{
|
||||
AssertTestFails(AssertThat(5, Is().Not().EqualTo(5)), "Expected: not equal to 5\nActual: 5\n");
|
||||
}
|
||||
|
||||
it("handles strings");
|
||||
{
|
||||
AssertThat(std::string("joakim"), Is().EqualTo(std::string("joakim")));
|
||||
}
|
||||
|
||||
it("handles strings without explicit template specialization");
|
||||
{
|
||||
AssertThat("kim", Is().EqualTo("kim"));
|
||||
}
|
||||
|
||||
it("handles GreaterThan()");
|
||||
{
|
||||
AssertThat(5, Is().GreaterThan(4));
|
||||
}
|
||||
|
||||
it("detects when GreaterThan() fails");
|
||||
{
|
||||
AssertTestFails(AssertThat(5, Is().GreaterThan(5)),
|
||||
"Expected: greater than 5\nActual: 5\n");
|
||||
}
|
||||
|
||||
it("handles LessThan()");
|
||||
{
|
||||
AssertThat(5, Is().LessThan(6));
|
||||
}
|
||||
|
||||
it("detects when LessThan() fails");
|
||||
{
|
||||
AssertTestFails(AssertThat(6, Is().LessThan(5)),
|
||||
"Expected: less than 5\nActual: 6\n");
|
||||
}
|
||||
|
||||
it("throws explicit failure message");
|
||||
{
|
||||
AssertTestFails(Assert::Failure("foo"), "foo");
|
||||
}
|
||||
|
||||
it("contains location information");
|
||||
{
|
||||
int line;
|
||||
std::string file;
|
||||
|
||||
try
|
||||
{
|
||||
Assert::That(5, Equals(2), "filename", 32);
|
||||
}
|
||||
catch (const AssertionException& e)
|
||||
{
|
||||
line = e.line();
|
||||
file = e.file();
|
||||
}
|
||||
|
||||
AssertThat(line, Equals(32));
|
||||
AssertThat(file, Equals("filename"));
|
||||
}
|
||||
|
||||
it("ensures exception is thrown");
|
||||
{
|
||||
AssertThrows(std::runtime_error, throwRuntimeError());
|
||||
}
|
||||
|
||||
it("ignores the error");
|
||||
{
|
||||
ConfigurableAssert<IgnoreErrors>::That(1, Equals(2));
|
||||
}
|
||||
|
||||
describe("Assertion expression templates");
|
||||
|
||||
it("handles integer equality");
|
||||
{
|
||||
AssertThat(5, Equals(5));
|
||||
}
|
||||
|
||||
it("detects integer inequality");
|
||||
{
|
||||
AssertTestFails(AssertThat(5, Equals(4)), "equal to 4");
|
||||
}
|
||||
|
||||
it("detects if !Equals() fails");
|
||||
{
|
||||
AssertTestFails(AssertThat(5, !Equals(5)),
|
||||
"Expected: not equal to 5\nActual: 5\n");
|
||||
}
|
||||
|
||||
it("handles strings");
|
||||
{
|
||||
AssertThat(std::string("joakim"), Equals(std::string("joakim")));
|
||||
}
|
||||
|
||||
it("handles strings without explicit template specialization");
|
||||
{
|
||||
AssertThat("kim", Equals("kim"));
|
||||
}
|
||||
|
||||
it("handles IsGreaterThan()");
|
||||
{
|
||||
AssertThat(5, IsGreaterThan(4));
|
||||
}
|
||||
|
||||
it("handles IsGreaterThanOrEqualTo()");
|
||||
{
|
||||
AssertThat(4, IsGreaterThanOrEqualTo(4));
|
||||
AssertThat(5, IsGreaterThanOrEqualTo(4));
|
||||
}
|
||||
|
||||
it("detects when IsGreaterThan() fails");
|
||||
{
|
||||
AssertTestFails(AssertThat(5, IsGreaterThan(5)),
|
||||
"Expected: greater than 5\nActual: 5\n");
|
||||
}
|
||||
|
||||
it("detects when IsGreaterThanOrEqualTo() fails");
|
||||
{
|
||||
AssertTestFails(AssertThat(4, IsGreaterThanOrEqualTo(5)),
|
||||
"Expected: greater than or equal to 5\nActual: 4\n");
|
||||
}
|
||||
|
||||
it("handles IsLessThan()");
|
||||
{
|
||||
AssertThat(5, IsLessThan(6));
|
||||
}
|
||||
|
||||
it("handles IsLessThanOrEqualTo()");
|
||||
{
|
||||
AssertThat(5, IsLessThanOrEqualTo(6));
|
||||
AssertThat(6, IsLessThanOrEqualTo(6));
|
||||
}
|
||||
|
||||
it("detects when IsLessThan() fails");
|
||||
{
|
||||
AssertTestFails(AssertThat(6, IsLessThan(5)),
|
||||
"Expected: less than 5\nActual: 6\n");
|
||||
}
|
||||
|
||||
it("detects when IsLessThanOrEqualTo() fails");
|
||||
{
|
||||
AssertTestFails(AssertThat(6, IsLessThanOrEqualTo(5)),
|
||||
"Expected: less than or equal to 5\nActual: 6\n");
|
||||
}
|
||||
|
||||
it("handles IsNull()");
|
||||
{
|
||||
AssertThat(nullptr, IsNull());
|
||||
}
|
||||
|
||||
it("handles Is().Null()");
|
||||
{
|
||||
AssertThat(nullptr, Is().Null());
|
||||
}
|
||||
|
||||
it("handles !IsNull()");
|
||||
{
|
||||
int anInt = 0;
|
||||
AssertThat(&anInt, !IsNull());
|
||||
}
|
||||
|
||||
it("detects when IsNull() fails (real address)");
|
||||
{
|
||||
int anInt = 0;
|
||||
std::ostringstream message;
|
||||
message << "Expected: equal to nullptr\nActual: " << &anInt << "\n";
|
||||
AssertTestFails(AssertThat(&anInt, IsNull()), message.str());
|
||||
}
|
||||
|
||||
it("detects when Is().Null() fails");
|
||||
{
|
||||
int anInt = 0;
|
||||
std::ostringstream message;
|
||||
message << "Expected: equal to nullptr\nActual: " << &anInt << "\n";
|
||||
AssertTestFails(AssertThat(&anInt, Is().Null()), message.str());
|
||||
}
|
||||
|
||||
it("detects when !IsNull() fails (nullptr)");
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Expected: not equal to nullptr\nActual: nullptr\n";
|
||||
|
||||
AssertTestFails(AssertThat(nullptr, !IsNull()), message.str());
|
||||
}
|
||||
}
|
||||
45
dep/snowhouse/example/boolean_operators.cpp
Normal file
45
dep/snowhouse/example/boolean_operators.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "tests.h"
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
void BooleanOperators()
|
||||
{
|
||||
describe("Boolean operators");
|
||||
|
||||
it("handles IsFalse()");
|
||||
{
|
||||
AssertThat(false, IsFalse());
|
||||
}
|
||||
|
||||
it("handles failing IsFalse()");
|
||||
{
|
||||
AssertTestFails(AssertThat(true, IsFalse()), "Expected: false");
|
||||
}
|
||||
|
||||
it("handles IsTrue()");
|
||||
{
|
||||
AssertThat(true, IsTrue());
|
||||
}
|
||||
|
||||
it("handles failing IsTrue()");
|
||||
{
|
||||
AssertTestFails(AssertThat(false, IsTrue()), "Expected: true");
|
||||
}
|
||||
|
||||
it("handles Is().True()");
|
||||
{
|
||||
AssertThat(true, Is().True());
|
||||
AssertTestFails(AssertThat(false, Is().True()), "Expected: true");
|
||||
}
|
||||
|
||||
it("handles Is().False()");
|
||||
{
|
||||
AssertThat(false, Is().False());
|
||||
AssertTestFails(AssertThat(true, Is().False()), "Expected: false");
|
||||
}
|
||||
|
||||
it("treats assert without constraint as boolean constrains");
|
||||
{
|
||||
Assert::That(true);
|
||||
}
|
||||
}
|
||||
85
dep/snowhouse/example/container_spec.cpp
Normal file
85
dep/snowhouse/example/container_spec.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
struct my_type
|
||||
{
|
||||
explicit my_type(int my_val)
|
||||
: my_val_(my_val)
|
||||
{
|
||||
}
|
||||
|
||||
friend bool operator==(const my_type&, const my_type&);
|
||||
friend bool operator!=(const my_type&, const my_type&);
|
||||
friend std::ostream& operator<<(std::ostream&, const my_type&);
|
||||
|
||||
int my_val_;
|
||||
};
|
||||
|
||||
bool operator==(const my_type& lhs, const my_type& rhs)
|
||||
{
|
||||
return lhs.my_val_ == rhs.my_val_;
|
||||
}
|
||||
|
||||
bool operator!=(const my_type& lhs, const my_type& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const my_type& item)
|
||||
{
|
||||
stream << "(my_type: my_val_=" << item.my_val_ << " )";
|
||||
return stream;
|
||||
}
|
||||
|
||||
static bool are_my_types_equal(const my_type& lhs, const my_type& rhs)
|
||||
{
|
||||
return lhs.my_val_ == rhs.my_val_;
|
||||
}
|
||||
|
||||
void ContainerConstraints()
|
||||
{
|
||||
describe("Container constraints");
|
||||
|
||||
it("is able to compare containers of custom types");
|
||||
{
|
||||
const my_type e[] = {my_type(1), my_type(3)};
|
||||
const std::list<my_type> expected(e, e + sizeof(e) / sizeof(e[0]));
|
||||
std::list<my_type> my_container_;
|
||||
my_container_.push_back(my_type(1));
|
||||
my_container_.push_back(my_type(3));
|
||||
|
||||
AssertThat(my_container_, EqualsContainer(expected));
|
||||
}
|
||||
|
||||
it("handles failing comparisons");
|
||||
{
|
||||
const my_type e[] = {my_type(1), my_type(2)};
|
||||
const std::list<my_type> expected(e, e + sizeof(e) / sizeof(e[0]));
|
||||
std::list<my_type> my_container_;
|
||||
my_container_.push_back(my_type(1));
|
||||
my_container_.push_back(my_type(3));
|
||||
|
||||
AssertTestFails(AssertThat(my_container_, EqualsContainer(expected)),
|
||||
"Expected: [ (my_type: my_val_=1 ), (my_type: my_val_=2 ) ]");
|
||||
}
|
||||
|
||||
it("handles comparison with a predicate function");
|
||||
{
|
||||
const my_type e[] = {my_type(1), my_type(3)};
|
||||
const std::list<my_type> expected(e, e + sizeof(e) / sizeof(e[0]));
|
||||
std::list<my_type> my_container_;
|
||||
my_container_.push_back(my_type(1));
|
||||
my_container_.push_back(my_type(3));
|
||||
|
||||
AssertThat(my_container_, EqualsContainer(expected, are_my_types_equal));
|
||||
AssertThat(my_container_, Is().EqualToContainer(expected, are_my_types_equal));
|
||||
}
|
||||
}
|
||||
61
dep/snowhouse/example/custom_matchers_test.cpp
Normal file
61
dep/snowhouse/example/custom_matchers_test.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
struct IsEvenNumberNoStreamOperator
|
||||
{
|
||||
bool Matches(const int actual) const
|
||||
{
|
||||
return (actual % 2) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct IsEvenNumberWithStreamOperator
|
||||
{
|
||||
bool Matches(const int actual) const
|
||||
{
|
||||
return (actual % 2) == 0;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stm,
|
||||
const IsEvenNumberWithStreamOperator&);
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& stm,
|
||||
const IsEvenNumberWithStreamOperator&)
|
||||
{
|
||||
stm << "An even number";
|
||||
return stm;
|
||||
}
|
||||
|
||||
void CustomMatchers()
|
||||
{
|
||||
describe("Custom matchers");
|
||||
|
||||
it("handles custom matcher");
|
||||
{
|
||||
AssertThat(2, Fulfills(IsEvenNumberNoStreamOperator()));
|
||||
}
|
||||
|
||||
it("handles custom matcher with fluent");
|
||||
{
|
||||
AssertThat(2, Is().Fulfilling(IsEvenNumberNoStreamOperator()));
|
||||
}
|
||||
|
||||
it("outputs correct message when fails");
|
||||
{
|
||||
AssertTestFails(AssertThat(3, Fulfills(IsEvenNumberNoStreamOperator())),
|
||||
"Expected: [unsupported type]\nActual: 3");
|
||||
}
|
||||
|
||||
it("outputs correct message when custom stream operator is defined");
|
||||
{
|
||||
AssertTestFails(AssertThat(3, Fulfills(IsEvenNumberWithStreamOperator())),
|
||||
"Expected: An even number\nActual: 3");
|
||||
}
|
||||
}
|
||||
105
dep/snowhouse/example/exceptions_tests.cpp
Normal file
105
dep/snowhouse/example/exceptions_tests.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
struct ClassWithExceptions
|
||||
{
|
||||
int LogicError()
|
||||
{
|
||||
throw std::logic_error("not logical!");
|
||||
}
|
||||
|
||||
double RangeError()
|
||||
{
|
||||
throw std::range_error("range error!");
|
||||
}
|
||||
|
||||
void NoError()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct ExpectedException : public std::exception
|
||||
{
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return "Description of the exception we expected";
|
||||
}
|
||||
};
|
||||
|
||||
void ExceptionTests()
|
||||
{
|
||||
ClassWithExceptions objectUnderTest;
|
||||
|
||||
describe("Exceptions");
|
||||
|
||||
it("detects exceptions");
|
||||
{
|
||||
AssertThrows(std::exception, objectUnderTest.LogicError());
|
||||
}
|
||||
|
||||
it("asserts on LastException()");
|
||||
{
|
||||
AssertThrows(std::logic_error, objectUnderTest.LogicError());
|
||||
AssertThat(LastException<std::logic_error>().what(), Contains("not logical!"));
|
||||
}
|
||||
|
||||
it("detects when wrong exception is thrown");
|
||||
{
|
||||
AssertTestFails(AssertThrows(std::logic_error, objectUnderTest.RangeError()), "Wrong exception");
|
||||
}
|
||||
|
||||
it("prints expected exception type when wrong exception is thrown");
|
||||
{
|
||||
AssertTestFails(AssertThrows(std::logic_error, objectUnderTest.RangeError()), "Expected std::logic_error");
|
||||
}
|
||||
|
||||
it("has several exception assertions in same spec");
|
||||
{
|
||||
AssertThrows(std::logic_error, objectUnderTest.LogicError());
|
||||
AssertThat(LastException<std::logic_error>().what(), Contains("not logical!"));
|
||||
|
||||
AssertThrows(std::range_error, objectUnderTest.RangeError());
|
||||
AssertThat(LastException<std::range_error>().what(), Contains("range error!"));
|
||||
}
|
||||
|
||||
it("has several exception assertion for the same exception in same spec");
|
||||
{
|
||||
AssertThrows(std::logic_error, objectUnderTest.LogicError());
|
||||
AssertThat(LastException<std::logic_error>().what(), Contains("not logical!"));
|
||||
|
||||
AssertThrows(std::logic_error, objectUnderTest.LogicError());
|
||||
AssertThat(LastException<std::logic_error>().what(), Contains("not logical!"));
|
||||
}
|
||||
|
||||
it("detects when no exception is thrown");
|
||||
{
|
||||
AssertTestFails(AssertThrows(std::logic_error, objectUnderTest.NoError()), "No exception");
|
||||
}
|
||||
|
||||
it("prints expected exception when no exception is thrown");
|
||||
{
|
||||
AssertTestFails(AssertThrows(std::logic_error, objectUnderTest.NoError()), "Expected std::logic_error");
|
||||
}
|
||||
|
||||
it("destroys exceptions when out-of-scope");
|
||||
{
|
||||
{
|
||||
AssertThrows(std::logic_error, objectUnderTest.LogicError());
|
||||
}
|
||||
AssertThrows(AssertionException, LastException<std::logic_error>());
|
||||
AssertThat(LastException<AssertionException>().what(), Contains("No exception was stored"));
|
||||
}
|
||||
|
||||
it("prints description of unwanted exception");
|
||||
{
|
||||
AssertTestFails(AssertThrows(ExpectedException, objectUnderTest.LogicError()), "Expected ExpectedException. Wrong exception was thrown. Description of unwanted exception: not logical!");
|
||||
}
|
||||
}
|
||||
25
dep/snowhouse/example/expression_error_handling.cpp
Normal file
25
dep/snowhouse/example/expression_error_handling.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "tests.h"
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
void ExpressionErrorHandling()
|
||||
{
|
||||
describe("Expression error handling");
|
||||
|
||||
std::vector<int> collection;
|
||||
collection.push_back(1);
|
||||
collection.push_back(2);
|
||||
collection.push_back(3);
|
||||
|
||||
it("reports an invalid All() properly");
|
||||
{
|
||||
AssertTestFails(AssertThat(collection, Has().All()),
|
||||
"The expression after \"all\" operator does not yield any result");
|
||||
}
|
||||
|
||||
it("reports an invalid AtLeast() properly");
|
||||
{
|
||||
AssertTestFails(AssertThat(collection, Has().AtLeast(2)),
|
||||
"The expression after \"at least 2\" operator does not yield any result");
|
||||
}
|
||||
}
|
||||
45
dep/snowhouse/example/main.cpp
Normal file
45
dep/snowhouse/example/main.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "tests.h"
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
void BooleanOperators();
|
||||
void BasicAssertions();
|
||||
void ContainerConstraints();
|
||||
void CustomMatchers();
|
||||
void ExceptionTests();
|
||||
void ExpressionErrorHandling();
|
||||
void MapTests();
|
||||
void OperatorTests();
|
||||
void SequenceContainerTests();
|
||||
void StringLineTests();
|
||||
void StringTests();
|
||||
void StringizeTests();
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "Spec for Snowhouse " SNOWHOUSE_VERSION << std::endl;
|
||||
|
||||
try
|
||||
{
|
||||
BasicAssertions();
|
||||
BooleanOperators();
|
||||
ContainerConstraints();
|
||||
CustomMatchers();
|
||||
ExceptionTests();
|
||||
ExpressionErrorHandling();
|
||||
MapTests();
|
||||
OperatorTests();
|
||||
SequenceContainerTests();
|
||||
StringLineTests();
|
||||
StringTests();
|
||||
StringizeTests();
|
||||
}
|
||||
catch (const AssertionException& e)
|
||||
{
|
||||
std::cout << "Tests failed!" << std::endl;
|
||||
std::cout << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
36
dep/snowhouse/example/map_tests.cpp
Normal file
36
dep/snowhouse/example/map_tests.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "tests.h"
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
void MapTests()
|
||||
{
|
||||
describe("Containing (std::map)");
|
||||
|
||||
std::map<std::string, int> ages;
|
||||
ages["joakim"] = 38;
|
||||
ages["maria"] = 36;
|
||||
ages["hanna"] = 6;
|
||||
ages["moa"] = 4;
|
||||
|
||||
it("determines if key exists");
|
||||
{
|
||||
AssertThat(ages, Is().Containing("joakim"));
|
||||
}
|
||||
|
||||
it("gives a proper message when fails");
|
||||
{
|
||||
AssertTestFails(AssertThat(ages, Is().Not().Containing("hanna")),
|
||||
"Expected: not contains \"hanna\"");
|
||||
}
|
||||
|
||||
it("determines if key exists");
|
||||
{
|
||||
AssertThat(ages, Contains("joakim"));
|
||||
}
|
||||
|
||||
it("gives a proper message when Contains() fails");
|
||||
{
|
||||
AssertTestFails(AssertThat(ages, !Contains("hanna")),
|
||||
"Expected: not contains \"hanna\"");
|
||||
}
|
||||
}
|
||||
132
dep/snowhouse/example/operator_tests.cpp
Normal file
132
dep/snowhouse/example/operator_tests.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
#include "tests.h"
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
void OperatorTests()
|
||||
{
|
||||
describe("Operators");
|
||||
|
||||
it("handles &&");
|
||||
{
|
||||
AssertThat(5, IsLessThan(6) && IsGreaterThan(4));
|
||||
}
|
||||
|
||||
it("handles And()");
|
||||
{
|
||||
AssertThat(5, Is().LessThan(6).And().GreaterThan(4));
|
||||
}
|
||||
|
||||
it("handles failing &&");
|
||||
{
|
||||
AssertTestFails(AssertThat(5, IsLessThan(7) && IsGreaterThan(5)),
|
||||
"less than 7 and greater than 5");
|
||||
}
|
||||
|
||||
it("handles failing And()");
|
||||
{
|
||||
AssertTestFails(AssertThat(5, Is().LessThan(7).And().GreaterThan(5)),
|
||||
"less than 7 and greater than 5");
|
||||
}
|
||||
|
||||
it("handles Or()");
|
||||
{
|
||||
AssertThat(12, Is().LessThan(7).Or().GreaterThan(5));
|
||||
}
|
||||
|
||||
it("handles ||");
|
||||
{
|
||||
AssertThat(12, IsLessThan(7) || IsGreaterThan(5));
|
||||
}
|
||||
|
||||
it("handles failing Or()");
|
||||
{
|
||||
AssertTestFails(AssertThat(67, Is().LessThan(12).Or().GreaterThan(99)),
|
||||
"less than 12 or greater than 99");
|
||||
}
|
||||
|
||||
it("handles failing ||");
|
||||
{
|
||||
AssertTestFails(AssertThat(67, IsLessThan(12) || IsGreaterThan(99)),
|
||||
"less than 12 or greater than 99");
|
||||
}
|
||||
|
||||
it("handles Not()");
|
||||
{
|
||||
AssertThat(5, Is().Not().EqualTo(4));
|
||||
}
|
||||
|
||||
it("handles !");
|
||||
{
|
||||
AssertThat(5, !Equals(4));
|
||||
}
|
||||
|
||||
it("handles failing Not()");
|
||||
{
|
||||
AssertTestFails(AssertThat(12, Is().Not().EqualTo(12)), "not equal to 12");
|
||||
}
|
||||
|
||||
it("handles failing !");
|
||||
{
|
||||
AssertTestFails(AssertThat(12, !Equals(12)), "not equal to 12");
|
||||
}
|
||||
|
||||
it("handles Not() for strings");
|
||||
{
|
||||
AssertThat("joakim", Is().Not().EqualTo("harry"));
|
||||
}
|
||||
|
||||
it("handles failing ! for strings");
|
||||
{
|
||||
AssertThat("joakim", !Equals("harry"));
|
||||
}
|
||||
|
||||
it("handles both left and right associative operators");
|
||||
{
|
||||
AssertThat(5, Is().GreaterThan(4).And().Not().LessThan(3));
|
||||
}
|
||||
|
||||
it("handles both left and right associative operators expression templates");
|
||||
{
|
||||
AssertThat(5, IsGreaterThan(4) && !IsLessThan(3));
|
||||
}
|
||||
|
||||
it("yields error on malformed expression");
|
||||
{
|
||||
AssertTestFails(AssertThat(4, Is().Not()),
|
||||
"The expression contains a \"not\" operator without any operand");
|
||||
}
|
||||
|
||||
it("handles failing EqualsWithDelta() when larger than delta");
|
||||
{
|
||||
AssertTestFails(AssertThat(3.9, EqualsWithDelta(3, 0.5)),
|
||||
"Expected: equal to 3 (+/- 0.5)");
|
||||
}
|
||||
|
||||
it("handles failing EqualsWithDelta() when less than delta");
|
||||
{
|
||||
AssertTestFails(AssertThat(2.49, EqualsWithDelta(3, 0.5)),
|
||||
"Expected: equal to 3 (+/- 0.5)");
|
||||
}
|
||||
|
||||
it("handles EqualsWithDelta()");
|
||||
{
|
||||
AssertThat(2, EqualsWithDelta(1.9, 0.1));
|
||||
}
|
||||
|
||||
it("handles failing Is().EqualToWithDelta() when larger than delta");
|
||||
{
|
||||
AssertTestFails(AssertThat(3.9, Is().EqualToWithDelta(3, 0.5)),
|
||||
"Expected: equal to 3 (+/- 0.5)");
|
||||
}
|
||||
|
||||
it("handles failing Is().EqualToWithDelta() when less than delta");
|
||||
{
|
||||
AssertTestFails(AssertThat(2.49, Is().EqualToWithDelta(3, 0.5)),
|
||||
"Expected: equal to 3 (+/- 0.5)");
|
||||
}
|
||||
|
||||
it("handles Is().EqualToWithDelta()");
|
||||
{
|
||||
AssertThat(2, Is().EqualToWithDelta(1.9, 0.1));
|
||||
}
|
||||
}
|
||||
288
dep/snowhouse/example/sequence_container_tests.cpp
Normal file
288
dep/snowhouse/example/sequence_container_tests.cpp
Normal file
@@ -0,0 +1,288 @@
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <array>
|
||||
#include <forward_list>
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
static const char* ExpectedActual = "\nActual: [ 1, 2, 3, 5, 8 ]";
|
||||
|
||||
template<typename T>
|
||||
static void insert_numbers(T& container)
|
||||
{
|
||||
container.push_back(1);
|
||||
container.push_back(2);
|
||||
container.push_back(3);
|
||||
container.push_back(5);
|
||||
container.push_back(8);
|
||||
}
|
||||
|
||||
template<>
|
||||
void insert_numbers(std::multiset<int>& container)
|
||||
{
|
||||
container.insert(1);
|
||||
container.insert(2);
|
||||
container.insert(3);
|
||||
container.insert(5);
|
||||
container.insert(8);
|
||||
}
|
||||
|
||||
template<>
|
||||
void insert_numbers(std::set<int>& container)
|
||||
{
|
||||
container.insert(1);
|
||||
container.insert(2);
|
||||
container.insert(3);
|
||||
container.insert(5);
|
||||
container.insert(8);
|
||||
}
|
||||
|
||||
template<>
|
||||
void insert_numbers(std::array<int, 5>& container)
|
||||
{
|
||||
container[0] = 1;
|
||||
container[1] = 2;
|
||||
container[2] = 3;
|
||||
container[3] = 5;
|
||||
container[4] = 8;
|
||||
}
|
||||
|
||||
template<>
|
||||
void insert_numbers(std::forward_list<int>& container)
|
||||
{
|
||||
container.push_front(8);
|
||||
container.push_front(5);
|
||||
container.push_front(3);
|
||||
container.push_front(2);
|
||||
container.push_front(1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void TestHasAll(const T& container)
|
||||
{
|
||||
it("handles All()");
|
||||
{
|
||||
AssertThat(container, Has().All().GreaterThan(1).Or().LessThan(4));
|
||||
}
|
||||
|
||||
it("handles failing All()");
|
||||
{
|
||||
AssertTestFails(AssertThat(container, Has().All().GreaterThan(4)), std::string("Expected: all greater than 4") + ExpectedActual);
|
||||
}
|
||||
|
||||
it("handles invalid expression after All()");
|
||||
{
|
||||
AssertTestFails(AssertThat(container, Has().All().Not()), "The expression contains a \"not\" operator without any operand");
|
||||
}
|
||||
|
||||
it("handles no expression after All()");
|
||||
{
|
||||
AssertTestFails(AssertThat(container, Has().All()), "The expression after \"all\" operator does not yield any result");
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void TestHasAll(const std::forward_list<int>&)
|
||||
{
|
||||
// The constraint is size-based but there is no size() method available
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void TestLength(const T& container)
|
||||
{
|
||||
it("handles HasLength()");
|
||||
{
|
||||
AssertThat(container, HasLength(5));
|
||||
}
|
||||
|
||||
it("handles failing HasLength()");
|
||||
{
|
||||
AssertTestFails(AssertThat(container, HasLength(7)), std::string("of length 7") + ExpectedActual);
|
||||
}
|
||||
|
||||
it("handles Is().OfLength()");
|
||||
{
|
||||
AssertThat(container, Is().OfLength(5));
|
||||
}
|
||||
|
||||
it("handles failing Is().OfLength()");
|
||||
{
|
||||
AssertTestFails(AssertThat(container, Is().OfLength(7)), std::string("of length 7") + ExpectedActual);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void TestLength(const std::forward_list<int>&)
|
||||
{
|
||||
// There is no size() method available
|
||||
}
|
||||
|
||||
template<typename T, typename TEmpty>
|
||||
static void TestEmpty(const T& container, const TEmpty& is_empty)
|
||||
{
|
||||
it("handles IsEmpty()");
|
||||
{
|
||||
AssertThat(is_empty, IsEmpty());
|
||||
}
|
||||
|
||||
it("handles failing IsEmpty()");
|
||||
{
|
||||
AssertTestFails(AssertThat(container, IsEmpty()), "empty");
|
||||
}
|
||||
|
||||
it("handles Is().Empty()");
|
||||
{
|
||||
AssertThat(is_empty, Is().Empty());
|
||||
}
|
||||
|
||||
it("handles failing Is().Empty()");
|
||||
{
|
||||
AssertTestFails(AssertThat(container, Is().Empty()), "empty");
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void TestEmpty(const T& container)
|
||||
{
|
||||
T is_empty;
|
||||
TestEmpty(container, is_empty);
|
||||
}
|
||||
|
||||
template<>
|
||||
void TestEmpty(const std::array<int, 5>& container)
|
||||
{
|
||||
std::array<int, 0> is_empty;
|
||||
TestEmpty(container, is_empty);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void SequenceContainerActual()
|
||||
{
|
||||
T container;
|
||||
insert_numbers(container);
|
||||
|
||||
TestHasAll(container);
|
||||
|
||||
it("handles AtLeast()");
|
||||
{
|
||||
AssertThat(container, Has().AtLeast(1).LessThan(5));
|
||||
}
|
||||
|
||||
it("handles failing AtLeast()");
|
||||
{
|
||||
AssertTestFails(AssertThat(container, Has().AtLeast(2).LessThan(2)), std::string("Expected: at least 2 less than 2") + ExpectedActual);
|
||||
}
|
||||
|
||||
it("handles Exactly()");
|
||||
{
|
||||
AssertThat(container, Has().Exactly(1).EqualTo(3));
|
||||
}
|
||||
|
||||
it("handles failing Exactly()");
|
||||
{
|
||||
AssertTestFails(AssertThat(container, Has().Exactly(2).EqualTo(3)), std::string("Expected: exactly 2 equal to 3") + ExpectedActual);
|
||||
}
|
||||
|
||||
it("handles AtMost()");
|
||||
{
|
||||
AssertThat(container, Has().AtMost(1).EqualTo(5));
|
||||
}
|
||||
|
||||
it("handles failing AtMost()");
|
||||
{
|
||||
AssertTestFails(AssertThat(container, Has().AtMost(1).EqualTo(3).Or().EqualTo(5)), std::string("Expected: at most 1 equal to 3 or equal to 5") + ExpectedActual);
|
||||
}
|
||||
|
||||
it("handles None()");
|
||||
{
|
||||
AssertThat(container, Has().None().EqualTo(666));
|
||||
}
|
||||
|
||||
it("handles failing None()");
|
||||
{
|
||||
AssertTestFails(AssertThat(container, Has().None().EqualTo(5)), std::string("Expected: none equal to 5") + ExpectedActual);
|
||||
}
|
||||
|
||||
it("handles Contains()");
|
||||
{
|
||||
AssertThat(container, Contains(3));
|
||||
}
|
||||
|
||||
it("detects failing Contains()");
|
||||
{
|
||||
AssertTestFails(AssertThat(container, Contains(99)), std::string("contains 99") + ExpectedActual);
|
||||
}
|
||||
|
||||
it("handles Is().Containing()");
|
||||
{
|
||||
AssertThat(container, Is().Containing(3));
|
||||
}
|
||||
|
||||
it("detects failing Is().Containing()");
|
||||
{
|
||||
AssertTestFails(AssertThat(container, Is().Containing(99)), std::string("contains 99") + ExpectedActual);
|
||||
}
|
||||
|
||||
TestLength(container);
|
||||
|
||||
TestEmpty(container);
|
||||
|
||||
it("handles EqualsContainer()");
|
||||
{
|
||||
std::list<int> expected;
|
||||
expected.assign(container.begin(), container.end());
|
||||
|
||||
AssertThat(container, EqualsContainer(expected));
|
||||
}
|
||||
|
||||
it("handles failing EqualsContainer()");
|
||||
{
|
||||
const int e[] = {4, 2, 4};
|
||||
std::list<int> expected(e, e + sizeof(e) / sizeof(e[0]));
|
||||
|
||||
AssertTestFails(AssertThat(container, EqualsContainer(expected)), "Expected: [ 4, 2, 4 ]");
|
||||
}
|
||||
|
||||
it("handles Is().EqualToContainer()");
|
||||
{
|
||||
std::list<int> expected;
|
||||
expected.assign(container.begin(), container.end());
|
||||
|
||||
AssertThat(container, Is().EqualToContainer(expected));
|
||||
}
|
||||
|
||||
it("handles failing Is().EqualToContainer()");
|
||||
{
|
||||
const int e[] = {4, 2, 4};
|
||||
std::list<int> expected(e, e + sizeof(e) / sizeof(e[0]));
|
||||
|
||||
AssertTestFails(AssertThat(container, Is().EqualToContainer(expected)), "Expected: [ 4, 2, 4 ]");
|
||||
}
|
||||
}
|
||||
|
||||
void SequenceContainerTests()
|
||||
{
|
||||
describe("Sequence containers (std::vector)");
|
||||
SequenceContainerActual<std::vector<int>>();
|
||||
|
||||
describe("Sequence containers (std::list)");
|
||||
SequenceContainerActual<std::list<int>>();
|
||||
|
||||
describe("Sequence containers (std::deque)");
|
||||
SequenceContainerActual<std::deque<int>>();
|
||||
|
||||
describe("Sequence containers (std::set)");
|
||||
SequenceContainerActual<std::set<int>>();
|
||||
|
||||
describe("Sequence containers (std::multiset)");
|
||||
SequenceContainerActual<std::multiset<int>>();
|
||||
|
||||
describe("Sequence containers (std::array)");
|
||||
SequenceContainerActual<std::array<int, 5>>();
|
||||
|
||||
describe("Sequence containers (std::forward_list)");
|
||||
SequenceContainerActual<std::forward_list<int>>();
|
||||
}
|
||||
173
dep/snowhouse/example/string_line_tests.cpp
Normal file
173
dep/snowhouse/example/string_line_tests.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
#include "tests.h"
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
void StringLineTests()
|
||||
{
|
||||
describe("String lines");
|
||||
|
||||
it("asserts that at least one line in a stream matches");
|
||||
{
|
||||
AssertThat("First line\n", Has().AtLeast(1).EqualTo("First line"));
|
||||
}
|
||||
|
||||
it("detects when assertion fails");
|
||||
{
|
||||
AssertTestFails(AssertThat("First line\n", Has().AtLeast(1).EqualTo("Second line")), "Expected: at least 1 equal to \"Second line\"");
|
||||
}
|
||||
|
||||
it("handles line missing newline");
|
||||
{
|
||||
AssertThat("First line", Has().AtLeast(1).EqualTo("First line"));
|
||||
}
|
||||
|
||||
it("handles several lines");
|
||||
{
|
||||
std::string lines = "First line\nSecond line";
|
||||
AssertThat(lines, Has().Exactly(2).EndingWith("line"));
|
||||
}
|
||||
|
||||
it("handles Windows line endings");
|
||||
{
|
||||
std::string lines = "First line\r\nSecond line\r\nThird line";
|
||||
AssertThat(lines, Has().Exactly(3).EndingWith("line"));
|
||||
}
|
||||
|
||||
it("matches beginning of lines with Windows line endings");
|
||||
{
|
||||
std::string lines = "First line\nSecond line\r\nThird line";
|
||||
AssertThat(lines, Has().Exactly(1).StartingWith("Second"));
|
||||
}
|
||||
|
||||
it("handles empty lines when using Windows line endings");
|
||||
{
|
||||
std::string lines = "\r\nSecond line\r\n\r\n";
|
||||
AssertThat(lines, Has().Exactly(2).OfLength(0));
|
||||
}
|
||||
|
||||
it("handles last line missing newline for Windows line endings");
|
||||
{
|
||||
std::string lines = "First line\r\nSecond line";
|
||||
AssertThat(lines, Has().Exactly(2).EndingWith("line"));
|
||||
}
|
||||
|
||||
it("handles all empty lines");
|
||||
{
|
||||
AssertThat("\n\n\n\n\n\n", Has().Exactly(6).OfLength(0));
|
||||
}
|
||||
|
||||
it("handles all empty lines with Windows line endings");
|
||||
{
|
||||
AssertThat("\r\n\r\n\r\n", Has().Exactly(3).OfLength(0));
|
||||
}
|
||||
|
||||
describe("StringLineParser");
|
||||
|
||||
it("parses an empty string");
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
|
||||
StringLineParser::Parse("", res);
|
||||
|
||||
AssertThat(res, HasLength(0));
|
||||
}
|
||||
|
||||
it("parses a single line");
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
|
||||
StringLineParser::Parse("Simple line", res);
|
||||
|
||||
AssertThat(res, HasLength(1));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("Simple line"));
|
||||
}
|
||||
|
||||
it("parses two lines");
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
|
||||
StringLineParser::Parse("One line\nTwo lines", res);
|
||||
|
||||
AssertThat(res, HasLength(2));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("One line"));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("Two lines"));
|
||||
}
|
||||
|
||||
it("parses three lines");
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
|
||||
StringLineParser::Parse("One line\nTwo lines\nThree lines", res);
|
||||
|
||||
AssertThat(res, HasLength(3));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("One line"));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("Two lines"));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("Three lines"));
|
||||
}
|
||||
|
||||
it("handles string ending with newline");
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
StringLineParser::Parse("One line\n", res);
|
||||
AssertThat(res, HasLength(1));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("One line"));
|
||||
}
|
||||
|
||||
it("handles single line with Windows line ending");
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
StringLineParser::Parse("One line\r\n", res);
|
||||
AssertThat(res, HasLength(1));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("One line"));
|
||||
}
|
||||
|
||||
it("handles two lines with Windows line endings");
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
StringLineParser::Parse("One line\r\nTwo lines", res);
|
||||
AssertThat(res, HasLength(2));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("One line"));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("Two lines"));
|
||||
}
|
||||
|
||||
it("handles empty line with newline");
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
StringLineParser::Parse("\n", res);
|
||||
AssertThat(res, Is().OfLength(1).And().Exactly(1).OfLength(0));
|
||||
}
|
||||
|
||||
it("handles two empty lines");
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
StringLineParser::Parse("\n\n", res);
|
||||
AssertThat(res, HasLength(2));
|
||||
AssertThat(res, Has().Exactly(2).OfLength(0));
|
||||
}
|
||||
|
||||
it("handles two empty lines with Windows line endings");
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
StringLineParser::Parse("\r\n\r\n", res);
|
||||
AssertThat(res, HasLength(2));
|
||||
AssertThat(res, Has().Exactly(2).OfLength(0));
|
||||
}
|
||||
|
||||
it("handles carriage return only");
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
StringLineParser::Parse("One line\rTwo lines", res);
|
||||
AssertThat(res, HasLength(2));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("One line"));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("Two lines"));
|
||||
}
|
||||
|
||||
it("handles carriage return only at end of string");
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
StringLineParser::Parse("One line\r\nTwo lines\r", res);
|
||||
AssertThat(res, HasLength(2));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("One line"));
|
||||
AssertThat(res, Has().Exactly(1).EqualTo("Two lines"));
|
||||
}
|
||||
}
|
||||
78
dep/snowhouse/example/string_tests.cpp
Normal file
78
dep/snowhouse/example/string_tests.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "tests.h"
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
void StringTests()
|
||||
{
|
||||
describe("Strings");
|
||||
|
||||
it("handles string Contains()");
|
||||
{
|
||||
AssertThat("abcdef", Contains("bcde"));
|
||||
}
|
||||
|
||||
it("handles match at beginning of string");
|
||||
{
|
||||
AssertThat("abcdef", Contains("a"));
|
||||
}
|
||||
|
||||
it("detects failing Contains()");
|
||||
{
|
||||
AssertTestFails(AssertThat("abcdef", Contains("hello")), "contains \"hello\"");
|
||||
}
|
||||
|
||||
it("handles string StartsWith()");
|
||||
{
|
||||
AssertThat("abcdef", StartsWith("abc"));
|
||||
}
|
||||
|
||||
it("handles string EndsWith()");
|
||||
{
|
||||
AssertThat("abcdef", EndsWith("def"));
|
||||
}
|
||||
|
||||
it("handles operators for strings");
|
||||
{
|
||||
AssertThat("abcdef", StartsWith("ab") && EndsWith("ef"));
|
||||
}
|
||||
|
||||
it("handles strings with multiple operators");
|
||||
{
|
||||
AssertThat("abcdef", StartsWith("ab") && !EndsWith("qwqw"));
|
||||
}
|
||||
|
||||
it("handles HasLength()");
|
||||
{
|
||||
AssertThat("12345", HasLength(5));
|
||||
}
|
||||
|
||||
it("handles failing HasLength()");
|
||||
{
|
||||
AssertTestFails(AssertThat("1234", HasLength(5)), "of length 5");
|
||||
}
|
||||
|
||||
it("handles IsEmpty()");
|
||||
{
|
||||
AssertThat("", IsEmpty());
|
||||
}
|
||||
|
||||
it("handles failing IsEmpty()");
|
||||
{
|
||||
AssertTestFails(AssertThat("not empty", IsEmpty()), "empty");
|
||||
}
|
||||
|
||||
it("handles weird long expressions");
|
||||
{
|
||||
AssertThat("12345", HasLength(5) && StartsWith("123") && !EndsWith("zyxxy"));
|
||||
}
|
||||
|
||||
it("handles std::string");
|
||||
{
|
||||
AssertThat("12345", Contains(std::string("23")));
|
||||
}
|
||||
|
||||
it("handles simple char");
|
||||
{
|
||||
AssertThat("12345", StartsWith('1'));
|
||||
}
|
||||
}
|
||||
127
dep/snowhouse/example/stringize_tests.cpp
Normal file
127
dep/snowhouse/example/stringize_tests.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
#include "tests.h"
|
||||
|
||||
using namespace snowhouse;
|
||||
|
||||
namespace
|
||||
{
|
||||
// No overload for operator<<(std::ostream&) or specialization of snowhouse::Stringizer
|
||||
struct WithoutStreamOperator
|
||||
{
|
||||
explicit WithoutStreamOperator(int id)
|
||||
: m_id(id)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const WithoutStreamOperator& rhs) const
|
||||
{
|
||||
return m_id == rhs.m_id;
|
||||
}
|
||||
|
||||
int m_id;
|
||||
};
|
||||
|
||||
// Has operator<<(std::ostream&)
|
||||
struct WithStreamOperator : public WithoutStreamOperator
|
||||
{
|
||||
explicit WithStreamOperator(int id)
|
||||
: WithoutStreamOperator(id)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const WithStreamOperator& a)
|
||||
{
|
||||
stream << a.m_id;
|
||||
return stream;
|
||||
}
|
||||
|
||||
// Has no operator<<(std::ostream&), but a specialization of snowhouse::Stringizer
|
||||
struct WithoutStreamOperatorButWithStringizer : public WithoutStreamOperator
|
||||
{
|
||||
explicit WithoutStreamOperatorButWithStringizer(int id)
|
||||
: WithoutStreamOperator(id)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<>
|
||||
struct Stringizer<WithoutStreamOperatorButWithStringizer>
|
||||
{
|
||||
static std::string ToString(const WithoutStreamOperatorButWithStringizer& value)
|
||||
{
|
||||
return snowhouse::Stringize(value.m_id);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void StringizeTests()
|
||||
{
|
||||
describe("Stringize");
|
||||
|
||||
it("handles types with stream operators");
|
||||
{
|
||||
WithStreamOperator a(12);
|
||||
WithStreamOperator b(13);
|
||||
AssertTestFails(AssertThat(a, Is().EqualTo(b)), "Expected: equal to 13\nActual: 12");
|
||||
}
|
||||
|
||||
it("handles types without stream operators");
|
||||
{
|
||||
WithoutStreamOperator a(12);
|
||||
WithoutStreamOperator b(13);
|
||||
AssertTestFails(AssertThat(a, Is().EqualTo(b)), "Expected: equal to [unsupported type]\nActual: [unsupported type]");
|
||||
}
|
||||
|
||||
it("handles types with traits");
|
||||
{
|
||||
WithoutStreamOperatorButWithStringizer a(12);
|
||||
WithoutStreamOperatorButWithStringizer b(13);
|
||||
AssertTestFails(AssertThat(a, Is().EqualTo(b)), "Expected: equal to 13\nActual: 12");
|
||||
}
|
||||
|
||||
it("provides bools as true or false");
|
||||
{
|
||||
AssertTestFails(AssertThat(false, Is().True()), "Expected: true\nActual: false");
|
||||
}
|
||||
|
||||
it("provides strings in quotation marks");
|
||||
{
|
||||
AssertTestFails(AssertThat("wrong", Is().EqualTo("right")), "Expected: equal to \"right\"\nActual: \"wrong\"");
|
||||
}
|
||||
|
||||
describe("Stringize expression templates");
|
||||
|
||||
it("handles types with stream operators");
|
||||
{
|
||||
WithStreamOperator a(12);
|
||||
WithStreamOperator b(13);
|
||||
AssertTestFails(AssertThat(a, Equals(b)), "Expected: equal to 13\nActual: 12");
|
||||
}
|
||||
|
||||
it("handles types without stream operators");
|
||||
{
|
||||
WithoutStreamOperator a(12);
|
||||
WithoutStreamOperator b(13);
|
||||
AssertTestFails(AssertThat(a, Equals(b)), "Expected: equal to [unsupported type]\nActual: [unsupported type]");
|
||||
}
|
||||
|
||||
it("handles types with traits");
|
||||
{
|
||||
WithoutStreamOperatorButWithStringizer a(12);
|
||||
WithoutStreamOperatorButWithStringizer b(13);
|
||||
AssertTestFails(AssertThat(a, Equals(b)), "Expected: equal to 13\nActual: 12");
|
||||
}
|
||||
|
||||
it("provides bools as true or false");
|
||||
{
|
||||
AssertTestFails(AssertThat(true, IsFalse()), "Expected: false\nActual: true");
|
||||
}
|
||||
|
||||
it("provides strings in quotation marks");
|
||||
{
|
||||
AssertTestFails(AssertThat("wrong", Equals("right")), "Expected: equal to \"right\"\nActual: \"wrong\"");
|
||||
}
|
||||
}
|
||||
31
dep/snowhouse/example/tests.h
Normal file
31
dep/snowhouse/example/tests.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef SNOWHOUSE_EXAMPLES_TEST_H
|
||||
#define SNOWHOUSE_EXAMPLES_TEST_H
|
||||
|
||||
#include <snowhouse/snowhouse.h>
|
||||
|
||||
// clang-format off
|
||||
#define AssertTestFails(assertion, expected_error_text) \
|
||||
std::string SNOWHOUSE_INTERNAL_expected_error = "Test did not fail"; \
|
||||
try \
|
||||
{ \
|
||||
assertion; \
|
||||
} \
|
||||
catch (const AssertionException& exception_from_snowhouse_assertion) \
|
||||
{ \
|
||||
SNOWHOUSE_INTERNAL_expected_error = exception_from_snowhouse_assertion.what(); \
|
||||
} \
|
||||
AssertThat(SNOWHOUSE_INTERNAL_expected_error, Is().Containing(expected_error_text));
|
||||
// clang-format on
|
||||
|
||||
inline void describe(const char* title)
|
||||
{
|
||||
std::cout << std::endl
|
||||
<< title << ":" << std::endl;
|
||||
}
|
||||
|
||||
inline void it(const char* title)
|
||||
{
|
||||
std::cout << " - " << title << std::endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
116
dep/snowhouse/include/snowhouse/assert.h
Normal file
116
dep/snowhouse/include/snowhouse/assert.h
Normal file
@@ -0,0 +1,116 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_ASSERT_H
|
||||
#define SNOWHOUSE_ASSERT_H
|
||||
|
||||
#include "assertionexception.h"
|
||||
#include "fluent/expressionbuilder.h"
|
||||
|
||||
// clang-format off
|
||||
#define SNOWHOUSE_ASSERT_THAT(P1, P2, FAILURE_HANDLER) \
|
||||
::snowhouse::ConfigurableAssert<FAILURE_HANDLER>::That((P1), (P2), __FILE__, __LINE__)
|
||||
|
||||
#ifndef SNOWHOUSE_NO_MACROS
|
||||
# define AssertThat(P1, P2) \
|
||||
SNOWHOUSE_ASSERT_THAT((P1), (P2), ::snowhouse::DefaultFailureHandler)
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
struct DefaultFailureHandler
|
||||
{
|
||||
template<typename ExpectedType, typename ActualType>
|
||||
static void Handle(const ExpectedType& expected, const ActualType& actual, const char* file_name, int line_number)
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
||||
str << "Expected: " << snowhouse::Stringize(expected) << std::endl;
|
||||
str << "Actual: " << snowhouse::Stringize(actual) << std::endl;
|
||||
|
||||
throw AssertionException(str.str(), file_name, line_number);
|
||||
}
|
||||
|
||||
static void Handle(const std::string& message)
|
||||
{
|
||||
throw AssertionException(message);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename FailureHandler>
|
||||
struct ConfigurableAssert
|
||||
{
|
||||
template<typename ActualType, typename ConstraintListType>
|
||||
static void That(const ActualType& actual, ExpressionBuilder<ConstraintListType> expression, const char* file_name = "", int line_number = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
ResultStack result;
|
||||
OperatorStack operators;
|
||||
expression.Evaluate(result, operators, actual);
|
||||
|
||||
while (!operators.empty())
|
||||
{
|
||||
ConstraintOperator* op = operators.top();
|
||||
op->PerformOperation(result);
|
||||
operators.pop();
|
||||
}
|
||||
|
||||
if (result.empty())
|
||||
{
|
||||
throw InvalidExpressionException("The expression did not yield any result");
|
||||
}
|
||||
|
||||
if (!result.top())
|
||||
{
|
||||
FailureHandler::Handle(expression, actual, file_name, line_number);
|
||||
}
|
||||
}
|
||||
catch (const InvalidExpressionException& e)
|
||||
{
|
||||
FailureHandler::Handle("Malformed expression: \"" + snowhouse::Stringize(expression) + "\"\n" + e.what());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ConstraintListType>
|
||||
static void That(const char* actual, ExpressionBuilder<ConstraintListType> expression, const char* file_name = "", int line_number = 0)
|
||||
{
|
||||
return That(std::string(actual), expression, file_name, line_number);
|
||||
}
|
||||
|
||||
template<typename ActualType, typename ExpressionType>
|
||||
static void That(const ActualType& actual, const ExpressionType& expression, const char* file_name = "", int line_number = 0)
|
||||
{
|
||||
if (!expression(actual))
|
||||
{
|
||||
FailureHandler::Handle(expression, actual, file_name, line_number);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ExpressionType>
|
||||
static void That(const char* actual, const ExpressionType& expression, const char* file_name = "", int line_number = 0)
|
||||
{
|
||||
return That(std::string(actual), expression, file_name, line_number);
|
||||
}
|
||||
|
||||
static void That(bool actual)
|
||||
{
|
||||
if (!actual)
|
||||
{
|
||||
FailureHandler::Handle("Expected: true\nActual: false");
|
||||
}
|
||||
}
|
||||
|
||||
static void Failure(const std::string& message)
|
||||
{
|
||||
FailureHandler::Handle(message);
|
||||
}
|
||||
};
|
||||
|
||||
using Assert = ConfigurableAssert<DefaultFailureHandler>;
|
||||
}
|
||||
|
||||
#endif
|
||||
44
dep/snowhouse/include/snowhouse/assertionexception.h
Normal file
44
dep/snowhouse/include/snowhouse/assertionexception.h
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_ASSERTIONEXCEPTION_H
|
||||
#define SNOWHOUSE_ASSERTIONEXCEPTION_H
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
struct AssertionException : public std::runtime_error
|
||||
{
|
||||
explicit AssertionException(const std::string& message, const std::string& filename, unsigned int line_number)
|
||||
: std::runtime_error(message), m_file(filename), m_line(line_number)
|
||||
{
|
||||
}
|
||||
|
||||
explicit AssertionException(const std::string& message)
|
||||
: AssertionException(message, "", 0)
|
||||
{
|
||||
}
|
||||
|
||||
std::string file() const
|
||||
{
|
||||
return m_file;
|
||||
}
|
||||
|
||||
unsigned int line() const
|
||||
{
|
||||
return m_line;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_file;
|
||||
unsigned int m_line;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
23
dep/snowhouse/include/snowhouse/constraints/constraints.h
Normal file
23
dep/snowhouse/include/snowhouse/constraints/constraints.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_CONSTRAINTS_H
|
||||
#define SNOWHOUSE_CONSTRAINTS_H
|
||||
|
||||
#include "containsconstraint.h"
|
||||
#include "endswithconstraint.h"
|
||||
#include "equalsconstraint.h"
|
||||
#include "haslengthconstraint.h"
|
||||
#include "isemptyconstraint.h"
|
||||
#include "isgreaterthanconstraint.h"
|
||||
#include "isgreaterthanorequaltoconstraint.h"
|
||||
#include "islessthanconstraint.h"
|
||||
#include "islessthanorequaltoconstraint.h"
|
||||
#include "startswithconstraint.h"
|
||||
#include "fulfillsconstraint.h"
|
||||
#include "equalswithdeltaconstraint.h"
|
||||
#include "equalscontainerconstraint.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_CONTAINSCONSTRAINT_H
|
||||
#define SNOWHOUSE_CONTAINSCONSTRAINT_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
#include "expressions/expression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ContainerType>
|
||||
struct find_in_container_traits
|
||||
{
|
||||
template<typename ExpectedType>
|
||||
static bool find(const ContainerType& container, const ExpectedType& expected)
|
||||
{
|
||||
return std::find(container.begin(), container.end(), expected) != container.end();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename KeyType, typename ValueType>
|
||||
struct find_in_container_traits<std::map<KeyType, ValueType>>
|
||||
{
|
||||
template<typename ExpectedType>
|
||||
static bool find(const std::map<KeyType, ValueType>& container, const ExpectedType& expected)
|
||||
{
|
||||
return container.find(expected) != container.end();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ExpectedType>
|
||||
struct ContainsConstraint : Expression<ContainsConstraint<ExpectedType>>
|
||||
{
|
||||
ContainsConstraint(const ExpectedType& expected)
|
||||
: m_expected(expected)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
return find_in_container_traits<ActualType>::find(actual, m_expected);
|
||||
}
|
||||
|
||||
bool operator()(const std::string& actual) const
|
||||
{
|
||||
return actual.find(m_expected) != std::string::npos;
|
||||
}
|
||||
|
||||
ExpectedType m_expected;
|
||||
};
|
||||
|
||||
template<typename ExpectedType>
|
||||
inline ContainsConstraint<ExpectedType> Contains(const ExpectedType& expected)
|
||||
{
|
||||
return ContainsConstraint<ExpectedType>(expected);
|
||||
}
|
||||
|
||||
inline ContainsConstraint<std::string> Contains(const char* expected)
|
||||
{
|
||||
return ContainsConstraint<std::string>(expected);
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
struct Stringizer<ContainsConstraint<ExpectedType>>
|
||||
{
|
||||
static std::string ToString(const ContainsConstraint<ExpectedType>& constraint)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << "contains " << snowhouse::Stringize(constraint.m_expected);
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_ENDSWITHCONSTRAINT_H
|
||||
#define SNOWHOUSE_ENDSWITHCONSTRAINT_H
|
||||
|
||||
#include "expressions/expression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ExpectedType>
|
||||
struct EndsWithConstraint : Expression<EndsWithConstraint<ExpectedType>>
|
||||
{
|
||||
EndsWithConstraint(const ExpectedType& expected)
|
||||
: m_expected(expected)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(const std::string& actual) const
|
||||
{
|
||||
size_t expectedPos = actual.length() - m_expected.length();
|
||||
return actual.find(m_expected) == expectedPos;
|
||||
}
|
||||
|
||||
ExpectedType m_expected;
|
||||
};
|
||||
|
||||
template<typename ExpectedType>
|
||||
inline EndsWithConstraint<ExpectedType> EndsWith(const ExpectedType& expected)
|
||||
{
|
||||
return EndsWithConstraint<ExpectedType>(expected);
|
||||
}
|
||||
|
||||
inline EndsWithConstraint<std::string> EndsWith(const char* expected)
|
||||
{
|
||||
return EndsWithConstraint<std::string>(expected);
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
struct Stringizer<EndsWithConstraint<ExpectedType>>
|
||||
{
|
||||
static std::string ToString(const EndsWithConstraint<ExpectedType>& constraint)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << "ends with " << snowhouse::Stringize(constraint.m_expected);
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_EQUALSCONSTRAINT_H
|
||||
#define SNOWHOUSE_EQUALSCONSTRAINT_H
|
||||
|
||||
#include "expressions/expression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ExpectedType>
|
||||
struct EqualsConstraint : Expression<EqualsConstraint<ExpectedType>>
|
||||
{
|
||||
EqualsConstraint(const ExpectedType& expected)
|
||||
: m_expected(expected)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
return (m_expected == actual);
|
||||
}
|
||||
|
||||
ExpectedType m_expected;
|
||||
};
|
||||
|
||||
template<typename ExpectedType>
|
||||
inline EqualsConstraint<ExpectedType> Equals(const ExpectedType& expected)
|
||||
{
|
||||
return EqualsConstraint<ExpectedType>(expected);
|
||||
}
|
||||
|
||||
inline EqualsConstraint<std::string> Equals(const char* expected)
|
||||
{
|
||||
return EqualsConstraint<std::string>(expected);
|
||||
}
|
||||
|
||||
inline EqualsConstraint<bool> IsFalse()
|
||||
{
|
||||
return EqualsConstraint<bool>(false);
|
||||
}
|
||||
|
||||
inline EqualsConstraint<bool> IsTrue()
|
||||
{
|
||||
return EqualsConstraint<bool>(true);
|
||||
}
|
||||
|
||||
inline EqualsConstraint<std::nullptr_t> IsNull()
|
||||
{
|
||||
return EqualsConstraint<std::nullptr_t>(nullptr);
|
||||
}
|
||||
|
||||
template<>
|
||||
struct Stringizer<EqualsConstraint<bool>>
|
||||
{
|
||||
static std::string ToString(const EqualsConstraint<bool>& constraint)
|
||||
{
|
||||
return constraint.m_expected ? "true" : "false";
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ExpectedType>
|
||||
struct Stringizer<EqualsConstraint<ExpectedType>>
|
||||
{
|
||||
static std::string ToString(const EqualsConstraint<ExpectedType>& constraint)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << "equal to " << snowhouse::Stringize(constraint.m_expected);
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_EQUALSCONTAINERCONSTRAINT_H
|
||||
#define SNOWHOUSE_EQUALSCONTAINERCONSTRAINT_H
|
||||
|
||||
#include "expressions/expression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
namespace constraint_internal
|
||||
{
|
||||
template<typename T>
|
||||
inline bool default_comparer(const T& lhs, const T& rhs)
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ExpectedType, typename BinaryPredicate>
|
||||
struct EqualsContainerConstraint : Expression<EqualsContainerConstraint<ExpectedType, BinaryPredicate>>
|
||||
{
|
||||
EqualsContainerConstraint(const ExpectedType& expected, const BinaryPredicate predicate)
|
||||
: m_expected(expected), m_predicate(predicate)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
typename ActualType::const_iterator actual_it;
|
||||
typename ExpectedType::const_iterator expected_it;
|
||||
|
||||
for (actual_it = actual.begin(), expected_it = m_expected.begin(); actual_it != actual.end() && expected_it != m_expected.end(); ++actual_it, ++expected_it)
|
||||
{
|
||||
if (!m_predicate(*actual_it, *expected_it))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return actual_it == actual.end() && expected_it == m_expected.end();
|
||||
}
|
||||
|
||||
const ExpectedType m_expected;
|
||||
const BinaryPredicate m_predicate;
|
||||
};
|
||||
|
||||
template<typename ExpectedType>
|
||||
inline EqualsContainerConstraint<ExpectedType, bool (*)(const typename ExpectedType::value_type&, const typename ExpectedType::value_type&)> EqualsContainer(const ExpectedType& expected)
|
||||
{
|
||||
return EqualsContainerConstraint<ExpectedType, bool (*)(const typename ExpectedType::value_type&, const typename ExpectedType::value_type&)>(expected, constraint_internal::default_comparer);
|
||||
}
|
||||
|
||||
template<typename ExpectedType, typename BinaryPredicate>
|
||||
inline EqualsContainerConstraint<ExpectedType, BinaryPredicate> EqualsContainer(const ExpectedType& expected, const BinaryPredicate predicate)
|
||||
{
|
||||
return EqualsContainerConstraint<ExpectedType, BinaryPredicate>(expected, predicate);
|
||||
}
|
||||
|
||||
template<typename ExpectedType, typename BinaryPredicate>
|
||||
struct Stringizer<EqualsContainerConstraint<ExpectedType, BinaryPredicate>>
|
||||
{
|
||||
static std::string ToString(const EqualsContainerConstraint<ExpectedType, BinaryPredicate>& constraint)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << snowhouse::Stringize(constraint.m_expected);
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_EQUALSWITHDELTACONSTRAINT_H
|
||||
#define SNOWHOUSE_EQUALSWITHDELTACONSTRAINT_H
|
||||
|
||||
#include "expressions/expression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ExpectedType, typename DeltaType>
|
||||
struct EqualsWithDeltaConstraint : Expression<EqualsWithDeltaConstraint<ExpectedType, DeltaType>>
|
||||
{
|
||||
EqualsWithDeltaConstraint(const ExpectedType& expected, const DeltaType& delta)
|
||||
: m_expected(expected), m_delta(delta)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
return ((m_expected <= (actual + m_delta)) && (m_expected >= (actual - m_delta)));
|
||||
}
|
||||
|
||||
ExpectedType m_expected;
|
||||
DeltaType m_delta;
|
||||
};
|
||||
|
||||
template<typename ExpectedType, typename DeltaType>
|
||||
inline EqualsWithDeltaConstraint<ExpectedType, DeltaType> EqualsWithDelta(const ExpectedType& expected, const DeltaType& delta)
|
||||
{
|
||||
return EqualsWithDeltaConstraint<ExpectedType, DeltaType>(expected, delta);
|
||||
}
|
||||
|
||||
template<typename ExpectedType, typename DeltaType>
|
||||
struct Stringizer<EqualsWithDeltaConstraint<ExpectedType, DeltaType>>
|
||||
{
|
||||
static std::string ToString(const EqualsWithDeltaConstraint<ExpectedType, DeltaType>& constraint)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << "equal to " << snowhouse::Stringize(constraint.m_expected) << " (+/- " << snowhouse::Stringize(constraint.m_delta) << ")";
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_ANDEXPRESSION_H
|
||||
#define SNOWHOUSE_ANDEXPRESSION_H
|
||||
|
||||
#include "../../stringize.h"
|
||||
#include "expression_fwd.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename LeftExpression, typename RightExpression>
|
||||
struct AndExpression : Expression<AndExpression<LeftExpression, RightExpression>>
|
||||
{
|
||||
AndExpression(const LeftExpression& left, const RightExpression& right)
|
||||
: m_left(left), m_right(right)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
return (m_left(actual) && m_right(actual));
|
||||
}
|
||||
|
||||
LeftExpression m_left;
|
||||
RightExpression m_right;
|
||||
};
|
||||
|
||||
template<typename LeftExpression, typename RightExpression>
|
||||
struct Stringizer<AndExpression<LeftExpression, RightExpression>>
|
||||
{
|
||||
static std::string ToString(const AndExpression<LeftExpression, RightExpression>& expression)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << Stringize(expression.m_left) << " and " << Stringize(expression.m_right);
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_EXPRESSION_H
|
||||
#define SNOWHOUSE_EXPRESSION_H
|
||||
|
||||
#include "notexpression.h"
|
||||
#include "andexpression.h"
|
||||
#include "orexpression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename T>
|
||||
struct Expression
|
||||
{
|
||||
NotExpression<T> operator!() const
|
||||
{
|
||||
return NotExpression<T>(static_cast<const T&>(*this));
|
||||
}
|
||||
|
||||
template<typename Right>
|
||||
AndExpression<T, Right> operator&&(const Right& right) const
|
||||
{
|
||||
return AndExpression<T, Right>(static_cast<const T&>(*this), right);
|
||||
}
|
||||
|
||||
template<typename Right>
|
||||
OrExpression<T, Right> operator||(const Right& right) const
|
||||
{
|
||||
return OrExpression<T, Right>(static_cast<const T&>(*this), right);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_EXPRESSION_FWD_H
|
||||
#define SNOWHOUSE_EXPRESSION_FWD_H
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename T>
|
||||
struct Expression;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_NOTEXPRESSION_H
|
||||
#define SNOWHOUSE_NOTEXPRESSION_H
|
||||
|
||||
#include "../../stringize.h"
|
||||
#include "expression_fwd.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ExpressionType>
|
||||
struct NotExpression : Expression<NotExpression<ExpressionType>>
|
||||
{
|
||||
explicit NotExpression(const ExpressionType& expression)
|
||||
: m_expression(expression)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
return !m_expression(actual);
|
||||
}
|
||||
|
||||
ExpressionType m_expression;
|
||||
};
|
||||
|
||||
template<typename ExpressionType>
|
||||
struct Stringizer<NotExpression<ExpressionType>>
|
||||
{
|
||||
static std::string ToString(const NotExpression<ExpressionType>& expression)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << "not " << snowhouse::Stringize(expression.m_expression);
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_OREXPRESSION_H
|
||||
#define SNOWHOUSE_OREXPRESSION_H
|
||||
|
||||
#include "../../stringize.h"
|
||||
#include "expression_fwd.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename LeftExpression, typename RightExpression>
|
||||
struct OrExpression : Expression<OrExpression<LeftExpression, RightExpression>>
|
||||
{
|
||||
OrExpression(const LeftExpression& left, const RightExpression& right)
|
||||
: m_left(left), m_right(right)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
return (m_left(actual) || m_right(actual));
|
||||
}
|
||||
|
||||
LeftExpression m_left;
|
||||
RightExpression m_right;
|
||||
};
|
||||
|
||||
template<typename LeftExpression, typename RightExpression>
|
||||
struct Stringizer<OrExpression<LeftExpression, RightExpression>>
|
||||
{
|
||||
static std::string ToString(const OrExpression<LeftExpression, RightExpression>& expression)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << snowhouse::Stringize(expression.m_left) << " or " << snowhouse::Stringize(expression.m_right);
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_FULFILLSCONSTRAINT_H
|
||||
#define SNOWHOUSE_FULFILLSCONSTRAINT_H
|
||||
|
||||
#include "expressions/expression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename MatcherType>
|
||||
struct FulfillsConstraint : Expression<FulfillsConstraint<MatcherType>>
|
||||
{
|
||||
FulfillsConstraint(const MatcherType& matcher)
|
||||
: m_matcher(matcher)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
return m_matcher.Matches(actual);
|
||||
}
|
||||
|
||||
MatcherType m_matcher;
|
||||
};
|
||||
|
||||
template<typename MatcherType>
|
||||
inline FulfillsConstraint<MatcherType> Fulfills(const MatcherType& matcher)
|
||||
{
|
||||
return FulfillsConstraint<MatcherType>(matcher);
|
||||
}
|
||||
|
||||
template<typename MatcherType>
|
||||
struct Stringizer<FulfillsConstraint<MatcherType>>
|
||||
{
|
||||
static std::string ToString(const FulfillsConstraint<MatcherType>& constraint)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << snowhouse::Stringize(constraint.m_matcher);
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_HASLENGTHCONSTRAINT_H
|
||||
#define SNOWHOUSE_HASLENGTHCONSTRAINT_H
|
||||
|
||||
#include "expressions/expression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ExpectedType>
|
||||
struct HasLengthConstraint : Expression<HasLengthConstraint<ExpectedType>>
|
||||
{
|
||||
HasLengthConstraint(const ExpectedType& expected)
|
||||
: m_expected(expected)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
using SizeType = typename ActualType::size_type;
|
||||
SizeType expectedSize = static_cast<SizeType>(m_expected);
|
||||
return (actual.size() == expectedSize);
|
||||
}
|
||||
|
||||
ExpectedType m_expected;
|
||||
};
|
||||
|
||||
template<typename ExpectedType>
|
||||
inline HasLengthConstraint<ExpectedType> HasLength(const ExpectedType& expected)
|
||||
{
|
||||
return HasLengthConstraint<ExpectedType>(expected);
|
||||
}
|
||||
|
||||
inline HasLengthConstraint<std::string> HasLength(const char* expected)
|
||||
{
|
||||
return HasLengthConstraint<std::string>(expected);
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
struct Stringizer<HasLengthConstraint<ExpectedType>>
|
||||
{
|
||||
static std::string ToString(const HasLengthConstraint<ExpectedType>& constraint)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << "of length " << snowhouse::Stringize(constraint.m_expected);
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2017 Stephan Beyer
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_ISEMPTYCONSTRAINT_H
|
||||
#define SNOWHOUSE_ISEMPTYCONSTRAINT_H
|
||||
|
||||
#include "expressions/expression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
struct IsEmptyConstraint : Expression<IsEmptyConstraint>
|
||||
{
|
||||
// The ignored default argument is a workaround to make this class
|
||||
// compatible to ConstraintAdapterType
|
||||
IsEmptyConstraint(int = 0)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
return actual.empty();
|
||||
}
|
||||
};
|
||||
|
||||
inline IsEmptyConstraint IsEmpty()
|
||||
{
|
||||
return IsEmptyConstraint();
|
||||
}
|
||||
|
||||
template<>
|
||||
struct Stringizer<IsEmptyConstraint>
|
||||
{
|
||||
static std::string ToString(const IsEmptyConstraint&)
|
||||
{
|
||||
return "empty";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_ISGREATERTHANCONSTRAINT_H
|
||||
#define SNOWHOUSE_ISGREATERTHANCONSTRAINT_H
|
||||
|
||||
#include "expressions/expression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ExpectedType>
|
||||
struct IsGreaterThanConstraint : Expression<IsGreaterThanConstraint<ExpectedType>>
|
||||
{
|
||||
IsGreaterThanConstraint(const ExpectedType& expected)
|
||||
: m_expected(expected)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
return (actual > m_expected);
|
||||
}
|
||||
|
||||
ExpectedType m_expected;
|
||||
};
|
||||
|
||||
template<typename ExpectedType>
|
||||
inline IsGreaterThanConstraint<ExpectedType> IsGreaterThan(const ExpectedType& expected)
|
||||
{
|
||||
return IsGreaterThanConstraint<ExpectedType>(expected);
|
||||
}
|
||||
|
||||
inline IsGreaterThanConstraint<std::string> IsGreaterThan(const char* expected)
|
||||
{
|
||||
return IsGreaterThanConstraint<std::string>(expected);
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
struct Stringizer<IsGreaterThanConstraint<ExpectedType>>
|
||||
{
|
||||
static std::string ToString(const IsGreaterThanConstraint<ExpectedType>& constraint)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << "greater than " << snowhouse::Stringize(constraint.m_expected);
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_ISGREATERTHANOREQUALTOCONSTRAINT_H
|
||||
#define SNOWHOUSE_ISGREATERTHANOREQUALTOCONSTRAINT_H
|
||||
|
||||
#include "expressions/expression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ExpectedType>
|
||||
struct IsGreaterThanOrEqualToConstraint : Expression<IsGreaterThanOrEqualToConstraint<ExpectedType>>
|
||||
{
|
||||
IsGreaterThanOrEqualToConstraint(const ExpectedType& expected)
|
||||
: m_expected(expected)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
return (actual >= m_expected);
|
||||
}
|
||||
|
||||
ExpectedType m_expected;
|
||||
};
|
||||
|
||||
template<typename ExpectedType>
|
||||
inline IsGreaterThanOrEqualToConstraint<ExpectedType> IsGreaterThanOrEqualTo(const ExpectedType& expected)
|
||||
{
|
||||
return IsGreaterThanOrEqualToConstraint<ExpectedType>(expected);
|
||||
}
|
||||
|
||||
inline IsGreaterThanOrEqualToConstraint<std::string> IsGreaterThanOrEqualTo(const char* expected)
|
||||
{
|
||||
return IsGreaterThanOrEqualToConstraint<std::string>(expected);
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
struct Stringizer<IsGreaterThanOrEqualToConstraint<ExpectedType>>
|
||||
{
|
||||
static std::string ToString(const IsGreaterThanOrEqualToConstraint<ExpectedType>& constraint)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << "greater than or equal to " << snowhouse::Stringize(constraint.m_expected);
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_ISLESSTHANCONSTRAINT_H
|
||||
#define SNOWHOUSE_ISLESSTHANCONSTRAINT_H
|
||||
|
||||
#include "expressions/expression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ExpectedType>
|
||||
struct IsLessThanConstraint : Expression<IsLessThanConstraint<ExpectedType>>
|
||||
{
|
||||
IsLessThanConstraint(const ExpectedType& expected)
|
||||
: m_expected(expected)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
return (actual < m_expected);
|
||||
}
|
||||
|
||||
ExpectedType m_expected;
|
||||
};
|
||||
|
||||
template<typename ExpectedType>
|
||||
inline IsLessThanConstraint<ExpectedType> IsLessThan(const ExpectedType& expected)
|
||||
{
|
||||
return IsLessThanConstraint<ExpectedType>(expected);
|
||||
}
|
||||
|
||||
inline IsLessThanConstraint<std::string> IsLessThan(const char* expected)
|
||||
{
|
||||
return IsLessThanConstraint<std::string>(expected);
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
struct Stringizer<IsLessThanConstraint<ExpectedType>>
|
||||
{
|
||||
static std::string ToString(const IsLessThanConstraint<ExpectedType>& constraint)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << "less than " << snowhouse::Stringize(constraint.m_expected);
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_ISLESSTHANOREQUALTOCONSTRAINT_H
|
||||
#define SNOWHOUSE_ISLESSTHANOREQUALTOCONSTRAINT_H
|
||||
|
||||
#include "expressions/expression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ExpectedType>
|
||||
struct IsLessThanOrEqualToConstraint : Expression<IsLessThanOrEqualToConstraint<ExpectedType>>
|
||||
{
|
||||
IsLessThanOrEqualToConstraint(const ExpectedType& expected)
|
||||
: m_expected(expected)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
bool operator()(const ActualType& actual) const
|
||||
{
|
||||
return (actual <= m_expected);
|
||||
}
|
||||
|
||||
ExpectedType m_expected;
|
||||
};
|
||||
|
||||
template<typename ExpectedType>
|
||||
inline IsLessThanOrEqualToConstraint<ExpectedType> IsLessThanOrEqualTo(const ExpectedType& expected)
|
||||
{
|
||||
return IsLessThanOrEqualToConstraint<ExpectedType>(expected);
|
||||
}
|
||||
|
||||
inline IsLessThanOrEqualToConstraint<std::string> IsLessThanOrEqualTo(const char* expected)
|
||||
{
|
||||
return IsLessThanOrEqualToConstraint<std::string>(expected);
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
struct Stringizer<IsLessThanOrEqualToConstraint<ExpectedType>>
|
||||
{
|
||||
static std::string ToString(const IsLessThanOrEqualToConstraint<ExpectedType>& constraint)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << "less than or equal to " << snowhouse::Stringize(constraint.m_expected);
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_STARTSWITHCONSTRAINT_H
|
||||
#define SNOWHOUSE_STARTSWITHCONSTRAINT_H
|
||||
|
||||
#include "expressions/expression.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ExpectedType>
|
||||
struct StartsWithConstraint : Expression<StartsWithConstraint<ExpectedType>>
|
||||
{
|
||||
StartsWithConstraint(const ExpectedType& expected)
|
||||
: m_expected(expected)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(const std::string& actual) const
|
||||
{
|
||||
return actual.find(m_expected) == 0;
|
||||
}
|
||||
|
||||
ExpectedType m_expected;
|
||||
};
|
||||
|
||||
template<typename ExpectedType>
|
||||
inline StartsWithConstraint<ExpectedType> StartsWith(const ExpectedType& expected)
|
||||
{
|
||||
return StartsWithConstraint<ExpectedType>(expected);
|
||||
}
|
||||
|
||||
inline StartsWithConstraint<std::string> StartsWith(const char* expected)
|
||||
{
|
||||
return StartsWithConstraint<std::string>(expected);
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
struct Stringizer<StartsWithConstraint<ExpectedType>>
|
||||
{
|
||||
static std::string ToString(const StartsWithConstraint<ExpectedType>& constraint)
|
||||
{
|
||||
std::ostringstream builder;
|
||||
builder << "starts with " << snowhouse::Stringize(constraint.m_expected);
|
||||
|
||||
return builder.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
134
dep/snowhouse/include/snowhouse/exceptions.h
Normal file
134
dep/snowhouse/include/snowhouse/exceptions.h
Normal file
@@ -0,0 +1,134 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_EXCEPTIONS_H
|
||||
#define SNOWHOUSE_EXCEPTIONS_H
|
||||
|
||||
#include "assert.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ExceptionType>
|
||||
struct ExceptionStorage
|
||||
{
|
||||
static void last_exception(ExceptionType*** e, bool clear = false)
|
||||
{
|
||||
static ExceptionType* last = nullptr;
|
||||
if (clear && last)
|
||||
{
|
||||
delete last;
|
||||
return;
|
||||
}
|
||||
|
||||
*e = &last;
|
||||
silly_warning_about_unused_arg(e);
|
||||
}
|
||||
|
||||
static ExceptionType*** silly_warning_about_unused_arg(ExceptionType*** e)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
static void store(const ExceptionType& e)
|
||||
{
|
||||
ExceptionType** last = nullptr;
|
||||
last_exception(&last);
|
||||
if (*last)
|
||||
{
|
||||
delete *last;
|
||||
*last = nullptr;
|
||||
}
|
||||
|
||||
*last = new ExceptionType(e);
|
||||
}
|
||||
|
||||
void compiler_thinks_i_am_unused()
|
||||
{
|
||||
}
|
||||
|
||||
~ExceptionStorage()
|
||||
{
|
||||
ExceptionType** e = nullptr;
|
||||
last_exception(&e);
|
||||
if (*e)
|
||||
{
|
||||
delete *e;
|
||||
*e = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ExceptionType>
|
||||
inline ExceptionType& LastException()
|
||||
{
|
||||
ExceptionType** e = nullptr;
|
||||
ExceptionStorage<ExceptionType>::last_exception(&e);
|
||||
if (*e == nullptr)
|
||||
{
|
||||
Assert::Failure("No exception was stored");
|
||||
}
|
||||
|
||||
return **e;
|
||||
}
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
#define SNOWHOUSE_CONCAT2(a, b) a##b
|
||||
#define SNOWHOUSE_CONCAT(a, b) SNOWHOUSE_CONCAT2(a, b)
|
||||
#define SNOWHOUSE_LINESUFFIX(a) SNOWHOUSE_CONCAT(a, __LINE__)
|
||||
#define SNOWHOUSE_TEMPVAR(a) SNOWHOUSE_CONCAT(SNOWHOUSE_, SNOWHOUSE_LINESUFFIX(a ## _))
|
||||
|
||||
#define SNOWHOUSE_ASSERT_THROWS(EXCEPTION_TYPE, METHOD, FAILURE_HANDLER_TYPE) \
|
||||
::snowhouse::ExceptionStorage<EXCEPTION_TYPE> SNOWHOUSE_TEMPVAR(storage); \
|
||||
SNOWHOUSE_TEMPVAR(storage).compiler_thinks_i_am_unused(); \
|
||||
bool SNOWHOUSE_TEMPVAR(wrong_exception) = false; \
|
||||
bool SNOWHOUSE_TEMPVAR(no_exception) = false; \
|
||||
bool SNOWHOUSE_TEMPVAR(more_info) = true; \
|
||||
std::string SNOWHOUSE_TEMPVAR(info_string); \
|
||||
try \
|
||||
{ \
|
||||
METHOD; \
|
||||
SNOWHOUSE_TEMPVAR(no_exception) = true; \
|
||||
} \
|
||||
catch (const EXCEPTION_TYPE& SNOWHOUSE_TEMPVAR(catched_exception)) \
|
||||
{ \
|
||||
::snowhouse::ExceptionStorage<EXCEPTION_TYPE>::store(SNOWHOUSE_TEMPVAR(catched_exception)); \
|
||||
} \
|
||||
catch (...) \
|
||||
{ \
|
||||
SNOWHOUSE_TEMPVAR(wrong_exception) = true; \
|
||||
if (auto eptr = std::current_exception()) { \
|
||||
try { \
|
||||
std::rethrow_exception(eptr); \
|
||||
} catch (const std::exception& e) { \
|
||||
SNOWHOUSE_TEMPVAR(more_info) = true; \
|
||||
SNOWHOUSE_TEMPVAR(info_string) = e.what(); \
|
||||
} catch (...) {} \
|
||||
} \
|
||||
} \
|
||||
if (SNOWHOUSE_TEMPVAR(no_exception)) \
|
||||
{ \
|
||||
::std::ostringstream SNOWHOUSE_TEMPVAR(stm); \
|
||||
SNOWHOUSE_TEMPVAR(stm) << "Expected " #EXCEPTION_TYPE ". No exception was thrown."; \
|
||||
::snowhouse::ConfigurableAssert<FAILURE_HANDLER_TYPE>::Failure(SNOWHOUSE_TEMPVAR(stm).str()); \
|
||||
} \
|
||||
if (SNOWHOUSE_TEMPVAR(wrong_exception)) \
|
||||
{ \
|
||||
::std::ostringstream SNOWHOUSE_TEMPVAR(stm); \
|
||||
SNOWHOUSE_TEMPVAR(stm) << "Expected " #EXCEPTION_TYPE ". Wrong exception was thrown."; \
|
||||
if (SNOWHOUSE_TEMPVAR(more_info)) { \
|
||||
SNOWHOUSE_TEMPVAR(stm) << " Description of unwanted exception: " << SNOWHOUSE_TEMPVAR(info_string); \
|
||||
} \
|
||||
::snowhouse::ConfigurableAssert<FAILURE_HANDLER_TYPE>::Failure(SNOWHOUSE_TEMPVAR(stm).str()); \
|
||||
} \
|
||||
do {} while (false)
|
||||
|
||||
#ifndef SNOWHOUSE_NO_MACROS
|
||||
# define AssertThrows(EXCEPTION_TYPE, METHOD) \
|
||||
SNOWHOUSE_ASSERT_THROWS(EXCEPTION_TYPE, (METHOD), ::snowhouse::DefaultFailureHandler)
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
#endif
|
||||
42
dep/snowhouse/include/snowhouse/fluent/constraintadapter.h
Normal file
42
dep/snowhouse/include/snowhouse/fluent/constraintadapter.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_CONSTRAINTADAPTER_H
|
||||
#define SNOWHOUSE_CONSTRAINTADAPTER_H
|
||||
|
||||
#include "../stringize.h"
|
||||
#include "constraintlist.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ConstraintType>
|
||||
struct ConstraintAdapter
|
||||
{
|
||||
explicit ConstraintAdapter(const ConstraintType& constraint)
|
||||
: m_constraint(constraint)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ConstraintListType, typename ActualType>
|
||||
void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
|
||||
{
|
||||
result.push(m_constraint(actual));
|
||||
EvaluateConstraintList(list.m_tail, result, operators, actual);
|
||||
}
|
||||
|
||||
ConstraintType m_constraint;
|
||||
};
|
||||
|
||||
template<typename ConstraintType>
|
||||
struct Stringizer<ConstraintAdapter<ConstraintType>>
|
||||
{
|
||||
static std::string ToString(const ConstraintAdapter<ConstraintType>& constraintAdapter)
|
||||
{
|
||||
return snowhouse::Stringize(constraintAdapter.m_constraint);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
102
dep/snowhouse/include/snowhouse/fluent/constraintlist.h
Normal file
102
dep/snowhouse/include/snowhouse/fluent/constraintlist.h
Normal file
@@ -0,0 +1,102 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_CONSTRAINTLIST_H
|
||||
#define SNOWHOUSE_CONSTRAINTLIST_H
|
||||
|
||||
#include <stack>
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
struct ConstraintOperator;
|
||||
using ResultStack = std::stack<bool>;
|
||||
using OperatorStack = std::stack<ConstraintOperator*>;
|
||||
|
||||
template<typename HT, typename TT>
|
||||
struct ConstraintList
|
||||
{
|
||||
using HeadType = HT;
|
||||
using TailType = TT;
|
||||
|
||||
ConstraintList(const HeadType& head, const TailType& tail)
|
||||
: m_head(head), m_tail(tail)
|
||||
{
|
||||
}
|
||||
|
||||
HeadType m_head;
|
||||
TailType m_tail;
|
||||
};
|
||||
|
||||
struct Nil
|
||||
{
|
||||
Nil()
|
||||
{
|
||||
}
|
||||
|
||||
Nil(const Nil&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// ---- These structs defines the resulting types of list concatenation operations
|
||||
template<typename L1, typename L2>
|
||||
struct type_concat
|
||||
{
|
||||
using t = ConstraintList<typename L1::HeadType, typename type_concat<typename L1::TailType, L2>::t>;
|
||||
};
|
||||
|
||||
template<typename L2>
|
||||
struct type_concat<Nil, L2>
|
||||
{
|
||||
using t = L2;
|
||||
};
|
||||
|
||||
template<typename L3>
|
||||
inline L3 tr_concat(const Nil&, const Nil&)
|
||||
{
|
||||
return Nil();
|
||||
}
|
||||
|
||||
// ---- These structs define the concatenation operations.
|
||||
|
||||
template<typename LeftList, typename RightList, typename ResultList>
|
||||
struct ListConcat
|
||||
{
|
||||
static ResultList Concatenate(const LeftList& left, const RightList& right)
|
||||
{
|
||||
return ResultList(left.m_head, ListConcat<typename LeftList::TailType, RightList, typename type_concat<typename LeftList::TailType, RightList>::t>::Concatenate(left.m_tail, right));
|
||||
}
|
||||
};
|
||||
|
||||
// Concatenating an empty list with a second list yields the second list
|
||||
template<typename RightList, typename ResultList>
|
||||
struct ListConcat<Nil, RightList, ResultList>
|
||||
{
|
||||
static ResultList Concatenate(const Nil&, const RightList& right)
|
||||
{
|
||||
return right;
|
||||
}
|
||||
};
|
||||
|
||||
// Concatenating two empty lists yields an empty list
|
||||
template<typename ResultList>
|
||||
struct ListConcat<Nil, Nil, ResultList>
|
||||
{
|
||||
static ResultList Concatenate(const Nil&, const Nil&)
|
||||
{
|
||||
return Nil();
|
||||
}
|
||||
};
|
||||
|
||||
// ---- The concatenation operation
|
||||
|
||||
template<typename L1, typename L2>
|
||||
inline typename type_concat<L1, L2>::t Concatenate(const L1& list1, const L2& list2)
|
||||
{
|
||||
return ListConcat<L1, L2, typename type_concat<L1, L2>::t>::Concatenate(list1, list2);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
365
dep/snowhouse/include/snowhouse/fluent/expressionbuilder.h
Normal file
365
dep/snowhouse/include/snowhouse/fluent/expressionbuilder.h
Normal file
@@ -0,0 +1,365 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_EXPRESSIONBUILDER_H
|
||||
#define SNOWHOUSE_EXPRESSIONBUILDER_H
|
||||
|
||||
#include "../constraints/constraints.h"
|
||||
#include "constraintadapter.h"
|
||||
#include "operators/andoperator.h"
|
||||
#include "operators/notoperator.h"
|
||||
#include "operators/oroperator.h"
|
||||
#include "operators/collections/alloperator.h"
|
||||
#include "operators/collections/noneoperator.h"
|
||||
#include "operators/collections/atleastoperator.h"
|
||||
#include "operators/collections/exactlyoperator.h"
|
||||
#include "operators/collections/atmostoperator.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
// ---- Evaluation of list of constraints
|
||||
|
||||
template<typename ConstraintListType, typename ActualType>
|
||||
inline void EvaluateConstraintList(ConstraintListType& constraint_list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
|
||||
{
|
||||
constraint_list.m_head.Evaluate(constraint_list, result, operators, actual);
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
inline void EvaluateConstraintList(Nil&, ResultStack&, OperatorStack&, const ActualType&)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ConstraintListType>
|
||||
struct ExpressionBuilder
|
||||
{
|
||||
explicit ExpressionBuilder(const ConstraintListType& list)
|
||||
: m_constraint_list(list)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsConstraint<ExpectedType>>, Nil>>::t>
|
||||
EqualTo(const ExpectedType& expected)
|
||||
{
|
||||
using ConstraintAdapterType = ConstraintAdapter<EqualsConstraint<ExpectedType>>;
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
|
||||
ConstraintAdapterType constraint(expected);
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
template<typename ExpectedType, typename DeltaType>
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsWithDeltaConstraint<ExpectedType, DeltaType>>, Nil>>::t>
|
||||
EqualToWithDelta(const ExpectedType& expected, const DeltaType& delta)
|
||||
{
|
||||
using ConstraintAdapterType = ConstraintAdapter<EqualsWithDeltaConstraint<ExpectedType, DeltaType>>;
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
|
||||
ConstraintAdapterType constraint(EqualsWithDeltaConstraint<ExpectedType, DeltaType>(expected, delta));
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
template<typename MatcherType>
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<FulfillsConstraint<MatcherType>>, Nil>>::t>
|
||||
Fulfilling(const MatcherType& matcher)
|
||||
{
|
||||
using ConstraintAdapterType = ConstraintAdapter<FulfillsConstraint<MatcherType>>;
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
|
||||
ConstraintAdapterType constraint(matcher);
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsConstraint<bool>>, Nil>>::t>
|
||||
False()
|
||||
{
|
||||
return EqualTo<bool>(false);
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsConstraint<bool>>, Nil>>::t>
|
||||
True()
|
||||
{
|
||||
return EqualTo<bool>(true);
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsConstraint<std::nullptr_t>>, Nil>>::t>
|
||||
Null()
|
||||
{
|
||||
return EqualTo<std::nullptr_t>(nullptr);
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsConstraint<std::string>>, Nil>>::t>
|
||||
EqualTo(const char* expected)
|
||||
{
|
||||
return EqualTo<std::string>(std::string(expected));
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<IsGreaterThanConstraint<ExpectedType>>, Nil>>::t>
|
||||
GreaterThan(const ExpectedType& expected)
|
||||
{
|
||||
using ConstraintAdapterType = ConstraintAdapter<IsGreaterThanConstraint<ExpectedType>>;
|
||||
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
ConstraintAdapterType constraint(expected);
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<IsGreaterThanOrEqualToConstraint<ExpectedType>>, Nil>>::t>
|
||||
GreaterThanOrEqualTo(const ExpectedType& expected)
|
||||
{
|
||||
using ConstraintAdapterType = ConstraintAdapter<IsGreaterThanOrEqualToConstraint<ExpectedType>>;
|
||||
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
ConstraintAdapterType constraint(expected);
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<IsLessThanConstraint<ExpectedType>>, Nil>>::t>
|
||||
LessThan(const ExpectedType& expected)
|
||||
{
|
||||
using ConstraintAdapterType = ConstraintAdapter<IsLessThanConstraint<ExpectedType>>;
|
||||
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
ConstraintAdapterType constraint(expected);
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<IsLessThanOrEqualToConstraint<ExpectedType>>, Nil>>::t>
|
||||
LessThanOrEqualTo(const ExpectedType& expected)
|
||||
{
|
||||
using ConstraintAdapterType = ConstraintAdapter<IsLessThanOrEqualToConstraint<ExpectedType>>;
|
||||
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
ConstraintAdapterType constraint(expected);
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<ContainsConstraint<ExpectedType>>, Nil>>::t>
|
||||
Containing(const ExpectedType& expected)
|
||||
{
|
||||
using ConstraintAdapterType = ConstraintAdapter<ContainsConstraint<ExpectedType>>;
|
||||
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
ConstraintAdapterType constraint(expected);
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<ContainsConstraint<std::string>>, Nil>>::t>
|
||||
Containing(const char* expected)
|
||||
{
|
||||
return Containing<std::string>(std::string(expected));
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EndsWithConstraint<ExpectedType>>, Nil>>::t>
|
||||
EndingWith(const ExpectedType& expected)
|
||||
{
|
||||
using ConstraintAdapterType = ConstraintAdapter<EndsWithConstraint<ExpectedType>>;
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
|
||||
ConstraintAdapterType constraint(expected);
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EndsWithConstraint<std::string>>, Nil>>::t>
|
||||
EndingWith(const char* expected)
|
||||
{
|
||||
return EndingWith(std::string(expected));
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<StartsWithConstraint<ExpectedType>>, Nil>>::t>
|
||||
StartingWith(const ExpectedType& expected)
|
||||
{
|
||||
using ConstraintAdapterType = ConstraintAdapter<StartsWithConstraint<ExpectedType>>;
|
||||
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
ConstraintAdapterType constraint(expected);
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<StartsWithConstraint<std::string>>, Nil>>::t>
|
||||
StartingWith(const char* expected)
|
||||
{
|
||||
return StartingWith(std::string(expected));
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<HasLengthConstraint<ExpectedType>>, Nil>>::t>
|
||||
OfLength(const ExpectedType& expected)
|
||||
{
|
||||
using ConstraintAdapterType = ConstraintAdapter<HasLengthConstraint<ExpectedType>>;
|
||||
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
ConstraintAdapterType constraint(expected);
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<IsEmptyConstraint>, Nil>>::t>
|
||||
Empty()
|
||||
{
|
||||
using ConstraintAdapterType = ConstraintAdapter<IsEmptyConstraint>;
|
||||
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
ConstraintAdapterType constraint(0);
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
template<typename ExpectedType>
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsContainerConstraint<ExpectedType, bool (*)(const typename ExpectedType::value_type&, const typename ExpectedType::value_type&)>>, Nil>>::t>
|
||||
EqualToContainer(const ExpectedType& expected)
|
||||
{
|
||||
using DefaultBinaryPredicateType = bool (*)(const typename ExpectedType::value_type&, const typename ExpectedType::value_type&);
|
||||
using ConstraintAdapterType = ConstraintAdapter<EqualsContainerConstraint<ExpectedType, DefaultBinaryPredicateType>>;
|
||||
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
ConstraintAdapterType constraint(EqualsContainerConstraint<ExpectedType, DefaultBinaryPredicateType>(expected, constraint_internal::default_comparer<typename ExpectedType::value_type>));
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
template<typename ExpectedType, typename BinaryPredicate>
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsContainerConstraint<ExpectedType, BinaryPredicate>>, Nil>>::t>
|
||||
EqualToContainer(const ExpectedType& expected, const BinaryPredicate predicate)
|
||||
{
|
||||
using ConstraintAdapterType = ConstraintAdapter<EqualsContainerConstraint<ExpectedType, BinaryPredicate>>;
|
||||
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil>>::t>;
|
||||
ConstraintAdapterType constraint(EqualsContainerConstraint<ExpectedType, BinaryPredicate>(expected, predicate));
|
||||
ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
using AndOperatorNode = ConstraintList<AndOperator, Nil>;
|
||||
using OrOperatorNode = ConstraintList<OrOperator, Nil>;
|
||||
using NotOperatorNode = ConstraintList<NotOperator, Nil>;
|
||||
using AllOperatorNode = ConstraintList<AllOperator, Nil>;
|
||||
using AtLeastOperatorNode = ConstraintList<AtLeastOperator, Nil>;
|
||||
using ExactlyOperatorNode = ConstraintList<ExactlyOperator, Nil>;
|
||||
using AtMostOperatorNode = ConstraintList<AtMostOperator, Nil>;
|
||||
using NoneOperatorNode = ConstraintList<NoneOperator, Nil>;
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, AllOperatorNode>::t> All()
|
||||
{
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, AllOperatorNode>::t>;
|
||||
AllOperator op;
|
||||
AllOperatorNode node(op, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, AtLeastOperatorNode>::t> AtLeast(unsigned int expected)
|
||||
{
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, AtLeastOperatorNode>::t>;
|
||||
AtLeastOperator op(expected);
|
||||
AtLeastOperatorNode node(op, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, ExactlyOperatorNode>::t> Exactly(unsigned int expected)
|
||||
{
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, ExactlyOperatorNode>::t>;
|
||||
ExactlyOperator op(expected);
|
||||
ExactlyOperatorNode node(op, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, AtMostOperatorNode>::t> AtMost(unsigned int expected)
|
||||
{
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, AtMostOperatorNode>::t>;
|
||||
AtMostOperator op(expected);
|
||||
AtMostOperatorNode node(op, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, NoneOperatorNode>::t> None()
|
||||
{
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, NoneOperatorNode>::t>;
|
||||
NoneOperator op;
|
||||
NoneOperatorNode node(op, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, AndOperatorNode>::t> And()
|
||||
{
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, AndOperatorNode>::t>;
|
||||
AndOperator op;
|
||||
AndOperatorNode node(op, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, OrOperatorNode>::t> Or()
|
||||
{
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, OrOperatorNode>::t>;
|
||||
OrOperator op;
|
||||
OrOperatorNode node(op, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
ExpressionBuilder<typename type_concat<ConstraintListType, NotOperatorNode>::t> Not()
|
||||
{
|
||||
using BuilderType = ExpressionBuilder<typename type_concat<ConstraintListType, NotOperatorNode>::t>;
|
||||
NotOperator op;
|
||||
NotOperatorNode node(op, Nil());
|
||||
return BuilderType(Concatenate(m_constraint_list, node));
|
||||
}
|
||||
|
||||
template<typename ActualType>
|
||||
void Evaluate(ResultStack& result, OperatorStack& operators, const ActualType& actual)
|
||||
{
|
||||
EvaluateConstraintList(m_constraint_list, result, operators, actual);
|
||||
}
|
||||
|
||||
ConstraintListType m_constraint_list;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline void StringizeConstraintList(const T& list, std::ostringstream& stm)
|
||||
{
|
||||
if (stm.tellp() > 0)
|
||||
stm << " ";
|
||||
|
||||
stm << snowhouse::Stringize(list.m_head);
|
||||
StringizeConstraintList(list.m_tail, stm);
|
||||
}
|
||||
|
||||
inline void StringizeConstraintList(const Nil&, std::ostringstream&)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ConstraintListType>
|
||||
struct Stringizer<ExpressionBuilder<ConstraintListType>>
|
||||
{
|
||||
static std::string ToString(const ExpressionBuilder<ConstraintListType>& builder)
|
||||
{
|
||||
std::ostringstream stm;
|
||||
StringizeConstraintList(builder.m_constraint_list, stm);
|
||||
|
||||
return stm.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
24
dep/snowhouse/include/snowhouse/fluent/fluent.h
Normal file
24
dep/snowhouse/include/snowhouse/fluent/fluent.h
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_FLUENT_H
|
||||
#define SNOWHOUSE_FLUENT_H
|
||||
|
||||
#include "expressionbuilder.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
inline ExpressionBuilder<Nil> Is()
|
||||
{
|
||||
return ExpressionBuilder<Nil>(Nil());
|
||||
}
|
||||
|
||||
inline ExpressionBuilder<Nil> Has()
|
||||
{
|
||||
return ExpressionBuilder<Nil>(Nil());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_ANDOPERATOR_H
|
||||
#define SNOWHOUSE_ANDOPERATOR_H
|
||||
|
||||
#include "constraintoperator.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
struct AndOperator : public ConstraintOperator
|
||||
{
|
||||
template<typename ConstraintListType, typename ActualType>
|
||||
void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
|
||||
{
|
||||
EvaluateOperatorsWithLessOrEqualPrecedence(*this, operators, result);
|
||||
|
||||
operators.push(this);
|
||||
|
||||
EvaluateConstraintList(list.m_tail, result, operators, actual);
|
||||
}
|
||||
|
||||
void PerformOperation(ResultStack& result) override
|
||||
{
|
||||
if (result.size() < 2)
|
||||
{
|
||||
throw InvalidExpressionException("The expression contains an \"and\" operator with too few operands");
|
||||
}
|
||||
|
||||
bool right = result.top();
|
||||
result.pop();
|
||||
bool left = result.top();
|
||||
result.pop();
|
||||
|
||||
result.push(left && right);
|
||||
}
|
||||
|
||||
int Precedence() const override
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Stringizer<AndOperator>
|
||||
{
|
||||
static std::string ToString(const AndOperator&)
|
||||
{
|
||||
return "and";
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_ALLOPERATOR_H
|
||||
#define SNOWHOUSE_ALLOPERATOR_H
|
||||
|
||||
#include "collectionoperator.h"
|
||||
#include "collectionconstraintevaluator.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
struct AllOperator : public CollectionOperator
|
||||
{
|
||||
template<typename ConstraintListType, typename ActualType>
|
||||
void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
|
||||
{
|
||||
unsigned int passed_elements = CollectionConstraintEvaluator<ConstraintListType, ActualType>::Evaluate(*this, list, result, operators, actual);
|
||||
|
||||
result.push(passed_elements == actual.size());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Stringizer<AllOperator>
|
||||
{
|
||||
static std::string ToString(const AllOperator&)
|
||||
{
|
||||
return "all";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_ATLEASTOPERATOR_H
|
||||
#define SNOWHOUSE_ATLEASTOPERATOR_H
|
||||
|
||||
#include "collectionoperator.h"
|
||||
#include "collectionconstraintevaluator.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
struct AtLeastOperator : public CollectionOperator
|
||||
{
|
||||
explicit AtLeastOperator(unsigned int expected)
|
||||
: m_expected(expected)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ConstraintListType, typename ActualType>
|
||||
void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
|
||||
{
|
||||
unsigned int passed_elements = CollectionConstraintEvaluator<ConstraintListType, ActualType>::Evaluate(*this, list, result, operators, actual);
|
||||
|
||||
result.push(passed_elements >= m_expected);
|
||||
}
|
||||
|
||||
unsigned int m_expected;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Stringizer<AtLeastOperator>
|
||||
{
|
||||
static std::string ToString(const AtLeastOperator& op)
|
||||
{
|
||||
std::ostringstream stm;
|
||||
stm << "at least " << op.m_expected;
|
||||
return stm.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_ATMOSTOPERATOR_H
|
||||
#define SNOWHOUSE_ATMOSTOPERATOR_H
|
||||
|
||||
#include "collectionoperator.h"
|
||||
#include "collectionconstraintevaluator.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
struct AtMostOperator : public CollectionOperator
|
||||
{
|
||||
explicit AtMostOperator(unsigned int expected)
|
||||
: m_expected(expected)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ConstraintListType, typename ActualType>
|
||||
void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
|
||||
{
|
||||
unsigned int passed_elements = CollectionConstraintEvaluator<ConstraintListType, ActualType>::Evaluate(*this, list, result, operators, actual);
|
||||
|
||||
result.push(passed_elements <= m_expected);
|
||||
}
|
||||
|
||||
unsigned int m_expected;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Stringizer<AtMostOperator>
|
||||
{
|
||||
static std::string ToString(const AtMostOperator& op)
|
||||
{
|
||||
std::ostringstream stm;
|
||||
stm << "at most " << op.m_expected;
|
||||
return stm.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,110 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_COLLECTIONCONSTRAINTEVALUATOR_H
|
||||
#define SNOWHOUSE_COLLECTIONCONSTRAINTEVALUATOR_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../constraintoperator.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
template<typename ConstraintListType, typename ActualType>
|
||||
struct CollectionConstraintEvaluator
|
||||
{
|
||||
static unsigned int Evaluate(const ConstraintOperator& op,
|
||||
ConstraintListType& expression, ResultStack& result,
|
||||
OperatorStack& operators, const ActualType& actual)
|
||||
{
|
||||
ConstraintOperator::EvaluateOperatorsWithLessOrEqualPrecedence(op,
|
||||
operators, result);
|
||||
|
||||
unsigned int passed_elements = 0;
|
||||
for (const auto& member : actual)
|
||||
{
|
||||
if (ConstraintOperator::EvaluateElementAgainstRestOfExpression(expression, member))
|
||||
{
|
||||
++passed_elements;
|
||||
}
|
||||
}
|
||||
|
||||
return passed_elements;
|
||||
}
|
||||
};
|
||||
|
||||
struct StringLineParser
|
||||
{
|
||||
static void Parse(const std::string& str, std::vector<std::string>& res)
|
||||
{
|
||||
size_t start = 0;
|
||||
size_t newline = FindNewline(str, start);
|
||||
|
||||
while (newline != std::string::npos)
|
||||
{
|
||||
StoreLine(str, start, newline, res);
|
||||
start = MoveToNextLine(str, newline);
|
||||
newline = FindNewline(str, start);
|
||||
}
|
||||
|
||||
if (start < str.size())
|
||||
{
|
||||
StoreLine(str, start, std::string::npos, res);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static size_t FindNewline(const std::string& str, size_t start)
|
||||
{
|
||||
return str.find_first_of("\r\n", start);
|
||||
}
|
||||
|
||||
static void StoreLine(const std::string& str, size_t start, size_t end,
|
||||
std::vector<std::string>& res)
|
||||
{
|
||||
std::string line = str.substr(start, end - start);
|
||||
res.push_back(line);
|
||||
}
|
||||
|
||||
static size_t MoveToNextLine(const std::string& str, size_t newline)
|
||||
{
|
||||
if (str.find("\r\n", newline) == newline)
|
||||
{
|
||||
return newline + 2;
|
||||
}
|
||||
|
||||
if (str.find('\n', newline) == newline)
|
||||
{
|
||||
return newline + 1;
|
||||
}
|
||||
|
||||
if (str.find('\r', newline) == newline)
|
||||
{
|
||||
return newline + 1;
|
||||
}
|
||||
|
||||
std::ostringstream stm;
|
||||
stm << "This string seems to contain an invalid line ending at position "
|
||||
<< newline << ":" << std::endl
|
||||
<< str << std::endl;
|
||||
throw InvalidExpressionException(stm.str());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ConstraintListType>
|
||||
struct CollectionConstraintEvaluator<ConstraintListType, std::string>
|
||||
{
|
||||
static unsigned int Evaluate(const ConstraintOperator& op,
|
||||
ConstraintListType& expression, ResultStack& result,
|
||||
OperatorStack& operators, const std::string& actual)
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
StringLineParser::Parse(actual, lines);
|
||||
return CollectionConstraintEvaluator<ConstraintListType, std::vector<std::string>>::Evaluate(op, expression, result, operators, lines);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef SNOWHOUSE_COLLECTIONOPERATOR_H
|
||||
#define SNOWHOUSE_COLLECTIONOPERATOR_H
|
||||
|
||||
#include "../constraintoperator.h"
|
||||
|
||||
namespace snowhouse
|
||||
{
|
||||
struct CollectionOperator : public ConstraintOperator
|
||||
{
|
||||
void PerformOperation(ResultStack&) override
|
||||
{
|
||||
}
|
||||
|
||||
int Precedence() const override
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user