Compare commits
	
		
			572 Commits
		
	
	
		
			92d85d1145
			...
			david/clar
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e009f68fbe | |||
| 671fa54f6f | |||
| 517432679b | |||
| b31c01f724 | |||
| f41213f13f | |||
| 28be7c4650 | |||
| 2f340b13b2 | |||
| 312c818866 | |||
| 0d69d0c4a2 | |||
| 81a0b8c820 | |||
| 172b5aee90 | |||
| 2b5338a9df | |||
| 8a430faf4c | |||
| e59382dd60 | |||
| 3006e77ef3 | |||
| 59c112a69c | |||
| 31b39982c5 | |||
| 5476417be2 | |||
| e03be694c2 | |||
| 490c0368bc | |||
| a24fc407c5 | |||
| e38b85b4f4 | |||
| f7c3c02c4c | |||
| 8f0f1fea39 | |||
| 2f36a3f6f0 | |||
| 07e5bf9054 | |||
| aacff3daf9 | |||
| e27eee50f0 | |||
| fd610454d6 | |||
| e61d4647b5 | |||
| c275c5f5e6 | |||
| fbf49ba511 | |||
| 92f74b27d1 | |||
| 934f0c9232 | |||
| ee9a3e1152 | |||
| 16886cdf1c | |||
| 08b9508d83 | |||
| 69bd968f98 | |||
| 4e7dc66610 | |||
| bea0cf5a0c | |||
| c7bc2a954f | |||
| 7372036a0a | |||
| 7461d832b6 | |||
| 6052798fea | |||
| fae1e73e54 | |||
| 51f2905c9c | |||
| 0c866d1b96 | |||
| fdf39d1a25 | |||
| a523a75e4b | |||
| cdaa64ed3f | |||
| 801d35c823 | |||
| 37b5fcc0f7 | |||
| f5f2c3bee6 | |||
| f6ef2b5acb | |||
| bf958a4a6e | |||
| 6a70e478a6 | |||
| 671b8edaad | |||
| 952637a1ea | |||
| 7569698e95 | |||
| 21713ba945 | |||
| 73273b6fa7 | |||
| 9f040392c7 | |||
| f4f7e5d053 | |||
| f847289bd4 | |||
| 94b0020d15 | |||
| c54c0bad38 | |||
| b9ffae0269 | |||
| 003f3e01c6 | |||
| 9028e74af0 | |||
| f5ccab5f2c | |||
| c27726a4a9 | |||
| 37cfa927d1 | |||
| 0efed70b57 | |||
| baf5fa3199 | |||
| bd24a775b2 | |||
| 857587c18b | |||
| eb3d53c955 | |||
| 14d58f3f5b | |||
| 5f2397903a | |||
| 58e0ecb469 | |||
| 8838bf420e | |||
| bddc544d7c | |||
| a9437191bf | |||
| 9d8da7ccda | |||
| 394b568e72 | |||
| 78e9f70db6 | |||
| 12e5623fe6 | |||
| cfdfb0a8c9 | |||
| 56e665301f | |||
| 7415ce4bd9 | |||
| 05f42150a1 | |||
| 8ea2bc6934 | |||
| c780924122 | |||
| 8c538560ca | |||
| c3e75bdb55 | |||
| 4419dff299 | |||
| e78c405046 | |||
| 6b7c5d896e | |||
| a33a73d73a | |||
| 536999c070 | |||
| e1cfcc8b5f | |||
| 514cb97835 | |||
| 4b5218c4f1 | |||
| 2ca77173d3 | |||
| cce5f52f96 | |||
| b55993294a | |||
| d8f847d707 | |||
| a5535ef59a | |||
| 8419b137e5 | |||
| ed1160ec74 | |||
| 1e21778059 | |||
| 78379f58c8 | |||
| 4322f720ba | |||
| 26f1a6051f | |||
| c4c1d4777b | |||
| fab012d3e7 | |||
| a90380f377 | |||
| 312097a799 | |||
| a40198ab8d | |||
| 52d8c0bdc8 | |||
| c19d7f4ea3 | |||
| 159b7e7ee7 | |||
| c93eec4f05 | |||
| e7e7a22390 | |||
| 26d5048e67 | |||
| 3b8f97cc41 | |||
| f1e68e0a04 | |||
| d6e4ab7a24 | |||
| 2000b2deee | |||
| 7d92400f6d | |||
| cb304ecf28 | |||
| ea17377700 | |||
| c424bde06d | |||
| ee7d5c6d51 | |||
| 99247cee32 | |||
| 7b8ddc189a | |||
| a6814030ee | |||
| 9937a01042 | |||
| abcf2adc56 | |||
| 05f9023550 | |||
| 5ba0bcf963 | |||
| 3ccadba2f5 | |||
| 00e52b6491 | |||
| ae40487990 | |||
| 84b612c693 | |||
| 3c2a6b047e | |||
| 626da322d9 | |||
| 0de428a2e5 | |||
| 8a52df4f76 | |||
| efec6eb3c8 | |||
| 56eeb24900 | |||
| ae81f6b3de | |||
| c1108301c0 | |||
| 83fbe6ac74 | |||
| 80b452833f | |||
| 0fa394333b | |||
| cae7535034 | |||
| df87832324 | |||
| d585794cbe | |||
| 209658549c | |||
| 02383a4aed | |||
| 185a76282a | |||
| b722b4f701 | |||
| 459ab5aad9 | |||
| 565f621cfc | |||
| 9589ca9148 | |||
| 164db5007b | |||
| cbfb167d29 | |||
| e7b83be867 | |||
| 649da5fca8 | |||
| aa095f7680 | |||
| bb99c99f01 | |||
| 7f0dcdd280 | |||
| 6029ad5d47 | |||
| 26fe266b09 | |||
| 091eda7b44 | |||
| 9676ea5978 | |||
| de8ac10653 | |||
| 88a6cd59f3 | |||
| cd43fb7f38 | |||
| 136f422401 | |||
| e773d6f0ee | |||
| 7da2f68d30 | |||
| d20889aef1 | |||
| 50c8302f4a | |||
| d8195d300d | |||
| a8c1387d5a | |||
| ff1e8f260b | |||
| d4329981e7 | |||
| 0003454311 | |||
| 8c6b2234ec | |||
| aad4b8a44c | |||
| 7cab133127 | |||
| 640ac85de4 | |||
| b8d7658626 | |||
| 2503bb3b2c | |||
| e5dd448fe7 | |||
| 4770bb6a93 | |||
| c0bac696dc | |||
| 95f7c33419 | |||
| 535d8876d3 | |||
| 845e433221 | |||
| 5169a607cf | |||
| 8f03af99a7 | |||
| ee63a4a1e4 | |||
| ac29f7a0f2 | |||
| 89ae226b1d | |||
| 477834ac04 | |||
| 97b707b61c | |||
| e86180e842 | |||
| 035ba8810f | |||
| f1c2113dd3 | |||
| 56b79f414d | |||
| 844656d557 | |||
| 849aceb86d | |||
| eef51a6d2b | |||
| c84b85102c | |||
| 3fe62464c3 | |||
| db55fc722f | |||
| 2094450898 | |||
| 889bec04b1 | |||
| ac1e34d4cd | |||
| 55ed75f44d | |||
| 2751872c59 | |||
| 2a3cd35cc4 | |||
| b66f459f75 | |||
| 3910f4e77c | |||
| c0e96216ae | |||
| f9512d72e8 | |||
| b7f2c169ec | |||
| 1e5057d6e6 | |||
| c6255e3224 | |||
| 02230ef619 | |||
| 9b6b60e4d1 | |||
| b9a26ab61e | |||
| a521887ddd | |||
| 5ca7e2f226 | |||
| 125a235dd1 | |||
| 91a7129f8f | |||
| df48a232ec | |||
| ab11b885e6 | |||
| 36fc25fb7e | |||
| 4803cca334 | |||
| 6bd74611cd | |||
| c3f9cf9a64 | |||
| 646ab1283f | |||
| 74cf055610 | |||
| 0d8ba1b154 | |||
| 20edbb7f38 | |||
| 6febc7cc73 | |||
| b94d6b5061 | |||
| b3952cabbc | |||
| 2ffc11b04e | |||
| 96cace2cbb | |||
| 472f5702bd | |||
| c0ac4345d3 | |||
| fbebf4ef83 | |||
| 20513f7749 | |||
| 25a7873ea2 | |||
| d0a32e247e | |||
| 03d4a5736e | |||
| a2e41e6527 | |||
| 40a7caff90 | |||
| 26fc5565e8 | |||
| 388541ce32 | |||
| 6c194667b9 | |||
| 62d0579f40 | |||
| 202595b2a6 | |||
| cb21ff3f04 | |||
| 2a8e3c2dc4 | |||
| 998066d377 | |||
| fefb876fe7 | |||
| 5979e9885e | |||
| a17abe4639 | |||
| d62f913855 | |||
| 12bb7475fc | |||
| df2c7e2b67 | |||
| 713aec887b | |||
| 3089cd7afc | |||
| 00638bc812 | |||
| e002109829 | |||
| b4798fd2ab | |||
| 3c804bf62a | |||
| d39d552bd9 | |||
| b7202a2b0d | |||
| 4e27a4c1f5 | |||
| 4ef31762d0 | |||
| 8b22a8f339 | |||
| d45ff05bcd | |||
| 671dd86206 | |||
| 0abadc1850 | |||
| 4e068d628c | |||
| 4461f99fa4 | |||
| cd1f4bdaa3 | |||
| 4728699585 | |||
| 105a1e5559 | |||
| 1bc18e34a8 | |||
| fb8d295fcb | |||
| 8459d3baea | |||
| 804d78e116 | |||
| 5351e9aa0a | |||
| b5954f15c5 | |||
| 5dce9dd377 | |||
| 0570f76236 | |||
| e22b658a67 | |||
| 56b9cb6ebf | |||
| eaa9a2415e | |||
| 95256a9a0d | |||
| 2286238abc | |||
| 13f0bf57e4 | |||
| 8eb1ac215b | |||
| e132f2fd1b | |||
| 12f6b22c8b | |||
| 6c858e0c4e | |||
| c6b58f7c63 | |||
| a22aafaf96 | |||
| 6298ac3a21 | |||
| cd63afacfe | |||
| 2859183742 | |||
| 8d04af691e | |||
| 055165974e | |||
| be51838775 | |||
| 1207dadee8 | |||
| 109e1898cc | |||
| a24bf7ffb9 | |||
| 046834c2b9 | |||
| f840240aac | |||
| cfa91d3d39 | |||
| f7a7a66a6a | |||
| 5145595d57 | |||
| f01d303381 | |||
| 098c8cb844 | |||
| 04ad0f0264 | |||
| 695e7a4561 | |||
| 7d53028faf | |||
| 6c34198f58 | |||
| 7e3e046109 | |||
| f63c58169f | |||
| e40b11246d | |||
| 161194c8b2 | |||
| 48603ea2c5 | |||
| e2f2a17315 | |||
| e8a0ce88c5 | |||
| 82e2ea747f | |||
| ff666eda9b | |||
| 0d8b82ba49 | |||
| 5598dfdd87 | |||
| 6ef462adcc | |||
| 9511cb5719 | |||
| 1cc1d561e2 | |||
| d15a0df7da | |||
| e1282b6bae | |||
| 5fe7c14ccb | |||
| 42165ba2d6 | |||
| 1af4da43ad | |||
| 4fa879a09e | |||
| fd8f1a29c6 | |||
| 9fda2763ba | |||
| cda23ac4af | |||
| c36b244dd3 | |||
| 335d278f5e | |||
| f987b02c65 | |||
| 3c056276c1 | |||
| 87e2fdefcf | |||
| 672b92b363 | |||
| 762a6517b2 | |||
| d141154a45 | |||
| 6170647c0c | |||
| 48e45c7dd6 | |||
| 5d3d9229b7 | |||
| d54e93d836 | |||
| 830f8fe3e4 | |||
| 7b638538aa | |||
| 2016f6e605 | |||
| 240effd305 | |||
| 6bc629e02c | |||
| f6f2acd67b | |||
| 0146d38405 | |||
| 75d8e7bb89 | |||
| 6b53eaf6b1 | |||
| 16c32273ac | |||
| 1567a6e29d | |||
| 89d543bcbc | |||
| d68e64931b | |||
| 1cbc576286 | |||
| 500b93562c | |||
| 800ca85176 | |||
| cc466a9f1d | |||
| 9d1155843e | |||
| a2139c09b2 | |||
| a3e5f27ab8 | |||
| 643f95ec80 | |||
| 6924147686 | |||
| 6e2b4fa7b4 | |||
| 4e5c749918 | |||
| 66229de77f | |||
| 7eb37c5318 | |||
| 7a21b20711 | |||
| 894be237f2 | |||
| 92e9d9cbfc | |||
| b29b9a9b3a | |||
| 721f844214 | |||
| a3d6a58cc8 | |||
| e598e7fe27 | |||
| ba9e720f9f | |||
| 8e816a261f | |||
| 5b9929ab3d | |||
| ceb54b3f1b | |||
| 8764444758 | |||
| ce9a0b1fdb | |||
| f7a468ea1e | |||
| 861d177a27 | |||
| 3936756b36 | |||
| 3e78ec3fe5 | |||
| 3c3d53b40c | |||
| 151d7c5736 | |||
| 4e4d8d2c3f | |||
| 03d1fd2857 | |||
| 6701decc91 | |||
| 6cff526647 | |||
| dd50bd0249 | |||
| 55a1660242 | |||
| ed365dfef5 | |||
| 23a09e4a13 | |||
| b69e7ebb98 | |||
| 418d6e3f22 | |||
| c44d8678cb | |||
| eb4cd7106d | |||
| d259770f32 | |||
| 80bad608f7 | |||
| 2bce9a2baf | |||
| 791b7746f3 | |||
| 842e3587fd | |||
| 318e79004b | |||
| 9f338a7429 | |||
| 645e48af7b | |||
| ef92c8df13 | |||
| 849d50be8e | |||
| 845092f114 | |||
| 75819a1797 | |||
| d66da85753 | |||
| 98ddb08abd | |||
| 8d1701b0bb | |||
| 1048e522fd | |||
| ee59da4aa3 | |||
| 1ba64cb5d8 | |||
| 462bebf6dd | |||
| e3f84c4e75 | |||
| 6837a0556d | |||
| ede2c8ca37 | |||
| f50367f7d5 | |||
| e758e03d2b | |||
| 835e3270ce | |||
| 480dd5ece4 | |||
| dba6bb5800 | |||
| 40a456e54a | |||
| bf5be00c12 | |||
| dc7c2559d6 | |||
| a75c4a11d3 | |||
| 347a165762 | |||
| fd64bfae13 | |||
| aaeec20ac9 | |||
| 37030f9c11 | |||
| 462f2bca4c | |||
| dc72500b98 | |||
| 962fe8bc22 | |||
| 305eb62647 | |||
| 4754359a21 | |||
| dc07f3d58b | |||
| fcdcfd10d1 | |||
| b74f6a7ace | |||
| ac7e5be187 | |||
| ed910c0beb | |||
| 345fb03857 | |||
| 9881253f2a | |||
| 96d27eecd1 | |||
| 28ebe93b77 | |||
| e849e7a3dd | |||
| e6777b0ad7 | |||
| c488c336de | |||
| 003f97201f | |||
| d85a10af84 | |||
| ff05d860c4 | |||
| 7679403742 | |||
| c51a45e1ba | |||
| a6e24ff2b6 | |||
| e0ec9e0c5f | |||
| 9a42a9b9d9 | |||
| 03a05c511e | |||
| bd91137d27 | |||
| 161640fa11 | |||
| 2b7d12945e | |||
| e42126c956 | |||
| 36942cca18 | |||
| b14f1d5000 | |||
| 1bf4f246c2 | |||
| edda8e010e | |||
| 3308b4dd72 | |||
| 27f4703a9a | |||
| 6af00d9a2e | |||
| 86b9f9316e | |||
| a0ed1b3f62 | |||
| 8dad624b21 | |||
| dc6605fd48 | |||
| c78d3cf638 | |||
| cee4f65d4a | |||
| cd3eeeef14 | |||
| 287d42f2b9 | |||
| dbbaaa46b9 | |||
| 9b8a8c4e46 | |||
| e44fa288fd | |||
| e13c6e812b | |||
| cb55b31afa | |||
| ab3f9e1627 | |||
| 8f25ef96ff | |||
| e13eebaf0b | |||
| 114f5c6685 | |||
| df44fe235b | |||
| 72f4db3d5e | |||
| 8a9ff971a1 | |||
| 5a8da59df1 | |||
| afa3a13d41 | |||
| 6522cf8a43 | |||
| f772e48b36 | |||
| 13bfe88195 | |||
| 5025475414 | |||
| 3c7652efc2 | |||
| 941bc71348 | |||
| bfe890ae00 | |||
| ab5bc1adb6 | |||
| abf7548ab5 | |||
| e2682b5ef7 | |||
| 792ad41499 | |||
| e4ae23e114 | |||
| 67187d5ec5 | |||
| 3271a37115 | |||
| ea9f50de8d | |||
| ea3c5e03fb | |||
| c8c4177d60 | |||
| 76b540e3b8 | |||
| 2062748676 | |||
| 135f0e4ce8 | |||
| cb16687641 | |||
| cb3ef0e79d | |||
| 0a62d90065 | |||
| ba7e3929e9 | |||
| 36c4022b56 | |||
| e22b25e54c | |||
| c6efabaa1d | |||
| 1f6fefdb68 | |||
| 1e34f91ebd | |||
| 35cb2ece9f | |||
| 66cd5c4a7e | |||
| 0daf938f76 | |||
| b90ab27a65 | |||
| c711f4358e | |||
| 84cb03d807 | |||
| 945a55f94a | |||
| 2173b12c67 | |||
| aa970b1fc0 | |||
| 6ad79b305c | |||
| a7cf267385 | |||
| 1a9f0d49e7 | |||
| a1b5b56553 | |||
| 256be6dae0 | |||
| cc10631b55 | |||
| 829dc0298e | |||
| e8a1ff0643 | |||
| bdfb5e972a | |||
| 396fecab5b | |||
| 5373b63cca | |||
| 8b655c40b9 | 
							
								
								
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					sample_project text eol=lf
 | 
				
			||||||
@@ -4,7 +4,7 @@ on: [push]
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
  build:
 | 
					  build:
 | 
				
			||||||
    runs-on: nostalgia
 | 
					    runs-on: olympic
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Check out repository code
 | 
					      - name: Check out repository code
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
@@ -17,3 +17,10 @@ jobs:
 | 
				
			|||||||
      - run: make purge configure-release
 | 
					      - run: make purge configure-release
 | 
				
			||||||
      - run: make build
 | 
					      - run: make build
 | 
				
			||||||
      - run: make test
 | 
					      - run: make test
 | 
				
			||||||
 | 
					      - run: make install
 | 
				
			||||||
 | 
					      - run: mv dist/linux-x86_64-release nostalgia-linux-x86_64
 | 
				
			||||||
 | 
					      - run: tar cf nostalgia-linux-x86_64.tar nostalgia-linux-x86_64
 | 
				
			||||||
 | 
					      - uses: actions/upload-artifact@v3
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          name: nostalgia-linux-x86_64
 | 
				
			||||||
 | 
					          path: nostalgia-linux-x86_64.tar
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -6,12 +6,14 @@
 | 
				
			|||||||
.mypy_cache
 | 
					.mypy_cache
 | 
				
			||||||
.stfolder
 | 
					.stfolder
 | 
				
			||||||
.stignore
 | 
					.stignore
 | 
				
			||||||
scripts/__pycache__
 | 
					.vs
 | 
				
			||||||
 | 
					util/scripts/__pycache__
 | 
				
			||||||
pyenv
 | 
					pyenv
 | 
				
			||||||
CMakeLists.txt.user
 | 
					CMakeLists.txt.user
 | 
				
			||||||
ROM.oxfs
 | 
					ROM.oxfs
 | 
				
			||||||
Session.vim
 | 
					Session.vim
 | 
				
			||||||
build
 | 
					build
 | 
				
			||||||
 | 
					cmake-build-*
 | 
				
			||||||
compile_commands.json
 | 
					compile_commands.json
 | 
				
			||||||
dist
 | 
					dist
 | 
				
			||||||
graph_info.json
 | 
					graph_info.json
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,4 +2,4 @@
 | 
				
			|||||||
source:
 | 
					source:
 | 
				
			||||||
- src
 | 
					- src
 | 
				
			||||||
copyright_notice: |-
 | 
					copyright_notice: |-
 | 
				
			||||||
  Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
					  Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,44 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "version": "0.2.1",
 | 
					 | 
				
			||||||
  "defaults": {},
 | 
					 | 
				
			||||||
  "configurations": [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      "type": "default",
 | 
					 | 
				
			||||||
      "project": "CMakeLists.txt",
 | 
					 | 
				
			||||||
      "projectTarget": "nostalgia.exe (Install)",
 | 
					 | 
				
			||||||
      "name": "nostalgia.exe (Install)",
 | 
					 | 
				
			||||||
      "args": [
 | 
					 | 
				
			||||||
        "${projectDir}/sample_project"
 | 
					 | 
				
			||||||
      ]
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      "type": "default",
 | 
					 | 
				
			||||||
      "project": "CMakeLists.txt",
 | 
					 | 
				
			||||||
      "projectTarget": "nostalgia.exe",
 | 
					 | 
				
			||||||
      "name": "nostalgia.exe",
 | 
					 | 
				
			||||||
      "args": [
 | 
					 | 
				
			||||||
        "${projectDir}/sample_project"
 | 
					 | 
				
			||||||
      ]
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      "type": "default",
 | 
					 | 
				
			||||||
      "project": "CMakeLists.txt",
 | 
					 | 
				
			||||||
      "projectTarget": "nostalgia-studio.exe (Install)",
 | 
					 | 
				
			||||||
      "name": "nostalgia-studio.exe (Install)",
 | 
					 | 
				
			||||||
      "args": [
 | 
					 | 
				
			||||||
        "-profile",
 | 
					 | 
				
			||||||
        "${projectDir}/src/nostalgia/studio/nostalgia-studio-dev.json"
 | 
					 | 
				
			||||||
      ]
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      "type": "default",
 | 
					 | 
				
			||||||
      "project": "CMakeLists.txt",
 | 
					 | 
				
			||||||
      "projectTarget": "nostalgia-studio.exe",
 | 
					 | 
				
			||||||
      "name": "nostalgia-studio.exe",
 | 
					 | 
				
			||||||
      "args": [
 | 
					 | 
				
			||||||
        "-profile",
 | 
					 | 
				
			||||||
        "${projectDir}/src/nostalgia/studio/nostalgia-studio-dev.json"
 | 
					 | 
				
			||||||
      ]
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  ]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										77
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,35 +1,68 @@
 | 
				
			|||||||
BC_VAR_PROJECT_NAME=nostalgia
 | 
					BC_VAR_PROJECT_NAME=nostalgia
 | 
				
			||||||
BC_VAR_PROJECT_NAME_CAP=Nostalgia
 | 
					BC_VAR_PROJECT_NAME_CAP=Nostalgia
 | 
				
			||||||
 | 
					BC_VAR_DEVENV_ROOT=util
 | 
				
			||||||
BUILDCORE_PATH=deps/buildcore
 | 
					BUILDCORE_PATH=deps/buildcore
 | 
				
			||||||
include ${BUILDCORE_PATH}/base.mk
 | 
					include ${BUILDCORE_PATH}/base.mk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(BC_VAR_OS),darwin)
 | 
					ifeq ($(BC_VAR_OS),darwin)
 | 
				
			||||||
	NOSTALGIA_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio.app/Contents/MacOS/${BC_VAR_PROJECT_NAME_CAP}Studio
 | 
						PROJECT_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio.app/Contents/MacOS/${BC_VAR_PROJECT_NAME_CAP}Studio
 | 
				
			||||||
	MGBA=/Applications/mGBA.app/Contents/MacOS/mGBA
 | 
						MGBA=/Applications/mGBA.app/Contents/MacOS/mGBA
 | 
				
			||||||
else
 | 
					else
 | 
				
			||||||
	NOSTALGIA_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio
 | 
						PROJECT_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio
 | 
				
			||||||
	MGBA=mgba-qt
 | 
						MGBA=mgba-qt
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					PROJECT_PLAYER=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: pkg-gba
 | 
					.PHONY: pkg-gba
 | 
				
			||||||
pkg-gba: build
 | 
					pkg-gba: build-pack build-gba-player
 | 
				
			||||||
	${BC_CMD_ENVRUN} ${BC_PY3} ./scripts/pkg-gba.py sample_project ${BC_VAR_PROJECT_NAME}
 | 
						${BC_CMD_ENVRUN} ${BC_PY3} ./util/scripts/pkg-gba.py sample_project ${BC_VAR_PROJECT_NAME_CAP}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: pkg-mac
 | 
				
			||||||
 | 
					pkg-mac: install
 | 
				
			||||||
 | 
						${BC_CMD_ENVRUN} ${BC_PY3} ./util/scripts/pkg-dmg.py NostalgiaStudio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: generate-studio-rsrc
 | 
				
			||||||
 | 
					generate-studio-rsrc:
 | 
				
			||||||
 | 
						${BC_CMD_ENVRUN} ${BC_PY3} ./util/scripts/file-to-cpp.py --rsrc src/olympic/studio/applib/src/rsrc.json
 | 
				
			||||||
 | 
						${BC_CMD_ENVRUN} ${BC_PY3} ./util/scripts/file-to-cpp.py --rsrc src/nostalgia/studio/rsrc.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: build-gba-player
 | 
				
			||||||
 | 
					build-gba-player:
 | 
				
			||||||
 | 
						cmake --build ./build/gba-*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: build-player
 | 
				
			||||||
 | 
					build-player:
 | 
				
			||||||
 | 
						${BC_CMD_CMAKE_BUILD} ${BC_VAR_BUILD_PATH} ${BC_VAR_PROJECT_NAME_CAP}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: build-pack
 | 
				
			||||||
 | 
					build-pack:
 | 
				
			||||||
 | 
						cmake --build ./build/${BC_VAR_CURRENT_BUILD} --target ${BC_VAR_PROJECT_NAME}-pack
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: run
 | 
					.PHONY: run
 | 
				
			||||||
run: build
 | 
					run: build-player
 | 
				
			||||||
	./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME} sample_project
 | 
						${PROJECT_PLAYER} sample_project
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: build-studio
 | 
				
			||||||
 | 
					build-studio:
 | 
				
			||||||
 | 
						cmake --build ./build/${BC_VAR_CURRENT_BUILD} --target ${BC_VAR_PROJECT_NAME_CAP}Studio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: run-studio
 | 
					.PHONY: run-studio
 | 
				
			||||||
run-studio: build
 | 
					run-studio: build-studio
 | 
				
			||||||
	${NOSTALGIA_STUDIO}
 | 
						${PROJECT_STUDIO}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: gba-run
 | 
					.PHONY: gba-run
 | 
				
			||||||
gba-run: pkg-gba
 | 
					gba-run: pkg-gba
 | 
				
			||||||
	${MGBA} ${BC_VAR_PROJECT_NAME}.gba
 | 
						${MGBA} ${BC_VAR_PROJECT_NAME_CAP}.gba
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: debug
 | 
					.PHONY: debug
 | 
				
			||||||
debug: build
 | 
					debug: build
 | 
				
			||||||
	${BC_CMD_HOST_DEBUGGER} ./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME} sample_project
 | 
						${BC_CMD_HOST_DEBUGGER} ${PROJECT_PLAYER} sample_project
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: debug-studio
 | 
					.PHONY: debug-studio
 | 
				
			||||||
debug-studio: build
 | 
					debug-studio: build
 | 
				
			||||||
	${BC_CMD_HOST_DEBUGGER} ${NOSTALGIA_STUDIO}
 | 
						${BC_CMD_HOST_DEBUGGER} ${PROJECT_STUDIO}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: configure-gba
 | 
					.PHONY: configure-gba
 | 
				
			||||||
configure-gba:
 | 
					configure-gba:
 | 
				
			||||||
@@ -38,3 +71,25 @@ configure-gba:
 | 
				
			|||||||
.PHONY: configure-gba-debug
 | 
					.PHONY: configure-gba-debug
 | 
				
			||||||
configure-gba-debug:
 | 
					configure-gba-debug:
 | 
				
			||||||
	${BC_CMD_SETUP_BUILD} --toolchain=deps/gbabuildcore/cmake/modules/GBA.cmake --target=gba --current_build=0 --build_type=debug --build_root=${BC_VAR_BUILD_PATH}
 | 
						${BC_CMD_SETUP_BUILD} --toolchain=deps/gbabuildcore/cmake/modules/GBA.cmake --target=gba --current_build=0 --build_type=debug --build_root=${BC_VAR_BUILD_PATH}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: loc
 | 
				
			||||||
 | 
					loc:
 | 
				
			||||||
 | 
						${BC_PY3} util/scripts/loc.py \
 | 
				
			||||||
 | 
							--search-dirs \
 | 
				
			||||||
 | 
								src \
 | 
				
			||||||
 | 
								deps/ox/src \
 | 
				
			||||||
 | 
								deps/buildcore \
 | 
				
			||||||
 | 
								deps/gbabuildcore \
 | 
				
			||||||
 | 
								deps/glutils \
 | 
				
			||||||
 | 
								deps/teagba \
 | 
				
			||||||
 | 
							--include-exts \
 | 
				
			||||||
 | 
								.cpp \
 | 
				
			||||||
 | 
								.hpp \
 | 
				
			||||||
 | 
								.py \
 | 
				
			||||||
 | 
								.s \
 | 
				
			||||||
 | 
								.cmake \
 | 
				
			||||||
 | 
							--exclude-paths \
 | 
				
			||||||
 | 
								deps/teagba/src/gba_crt0.s \
 | 
				
			||||||
 | 
								src/olympic/studio/applib/src/font.cpp \
 | 
				
			||||||
 | 
								src/olympic/studio/applib/src/font.hpp \
 | 
				
			||||||
 | 
								src/nostalgia/studio/icondata.cpp
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/buildcore/base.mk
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/buildcore/base.mk
									
									
									
									
										vendored
									
									
								
							@@ -93,7 +93,7 @@ purge:
 | 
				
			|||||||
	${BC_CMD_RM_RF} compile_commands.json
 | 
						${BC_CMD_RM_RF} compile_commands.json
 | 
				
			||||||
.PHONY: test
 | 
					.PHONY: test
 | 
				
			||||||
test: build
 | 
					test: build
 | 
				
			||||||
	${BC_CMD_ENVRUN} mypy ${BC_VAR_SCRIPTS}
 | 
						${BC_CMD_ENVRUN} ${BC_CMD_PY3} -m mypy ${BC_VAR_SCRIPTS}
 | 
				
			||||||
	${BC_CMD_CMAKE_BUILD} ${BC_VAR_BUILD_PATH} test
 | 
						${BC_CMD_CMAKE_BUILD} ${BC_VAR_BUILD_PATH} test
 | 
				
			||||||
.PHONY: test-verbose
 | 
					.PHONY: test-verbose
 | 
				
			||||||
test-verbose: build
 | 
					test-verbose: build
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								deps/buildcore/scripts/pybb.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								deps/buildcore/scripts/pybb.py
									
									
									
									
										vendored
									
									
								
							@@ -11,6 +11,7 @@
 | 
				
			|||||||
# "Python Busy Box" - adds cross-platform equivalents to Unix commands that
 | 
					# "Python Busy Box" - adds cross-platform equivalents to Unix commands that
 | 
				
			||||||
#                     don't translate well to that other operating system
 | 
					#                     don't translate well to that other operating system
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import multiprocessing
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import platform
 | 
					import platform
 | 
				
			||||||
import shutil
 | 
					import shutil
 | 
				
			||||||
@@ -57,7 +58,11 @@ def cmake_build(base_path: str, target: Optional[str]) -> int:
 | 
				
			|||||||
        path = os.path.join(base_path, d)
 | 
					        path = os.path.join(base_path, d)
 | 
				
			||||||
        if not os.path.isdir(path):
 | 
					        if not os.path.isdir(path):
 | 
				
			||||||
            continue
 | 
					            continue
 | 
				
			||||||
        args = ['cmake', '--build', path]
 | 
					        args = ['cmake', '--build', path, f'-j{multiprocessing.cpu_count()}']
 | 
				
			||||||
 | 
					        if path.endswith('release'):
 | 
				
			||||||
 | 
					            args.append('--config=release')
 | 
				
			||||||
 | 
					        elif path.endswith('debug'):
 | 
				
			||||||
 | 
					            args.append('--config=debug')
 | 
				
			||||||
        if target is not None:
 | 
					        if target is not None:
 | 
				
			||||||
            args.extend(['--target', target])
 | 
					            args.extend(['--target', target])
 | 
				
			||||||
        err = subprocess.run(args).returncode
 | 
					        err = subprocess.run(args).returncode
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/buildcore/scripts/util.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/buildcore/scripts/util.py
									
									
									
									
										vendored
									
									
								
							@@ -35,4 +35,6 @@ def get_arch() -> str:
 | 
				
			|||||||
    arch = platform.machine().lower()
 | 
					    arch = platform.machine().lower()
 | 
				
			||||||
    if arch == 'amd64':
 | 
					    if arch == 'amd64':
 | 
				
			||||||
        arch = 'x86_64'
 | 
					        arch = 'x86_64'
 | 
				
			||||||
 | 
					    elif arch == 'aarch64':
 | 
				
			||||||
 | 
					        arch = 'arm64'
 | 
				
			||||||
    return arch
 | 
					    return arch
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								deps/gbabuildcore/base.cmake
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								deps/gbabuildcore/base.cmake
									
									
									
									
										vendored
									
									
								
							@@ -1,8 +1,8 @@
 | 
				
			|||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/modules)
 | 
					list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/modules)
 | 
				
			||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib")
 | 
					set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib")
 | 
				
			||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc++")
 | 
					set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc++")
 | 
				
			||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-unwind-tables")
 | 
					#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-unwind-tables")
 | 
				
			||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
 | 
					#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
 | 
				
			||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
 | 
					set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
 | 
				
			||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing")
 | 
					set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing")
 | 
				
			||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb-interwork")
 | 
					set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb-interwork")
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								deps/glad/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								deps/glad/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +1,11 @@
 | 
				
			|||||||
add_library(glad OBJECT src/glad.c)
 | 
					add_library(glad src/glad.c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_include_directories(glad PUBLIC include)
 | 
					target_include_directories(glad PUBLIC include)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install(
 | 
				
			||||||
 | 
						TARGETS
 | 
				
			||||||
 | 
							glad
 | 
				
			||||||
 | 
						DESTINATION
 | 
				
			||||||
 | 
							LIBRARY DESTINATION lib
 | 
				
			||||||
 | 
							ARCHIVE DESTINATION lib
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										46
									
								
								deps/glutils/include/glutils/glutils.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								deps/glutils/include/glutils/glutils.hpp
									
									
									
									
										vendored
									
									
								
							@@ -89,7 +89,7 @@ struct GLObject: public Base {
 | 
				
			|||||||
		return id;
 | 
							return id;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constexpr operator const GLuint&() const noexcept {
 | 
						constexpr operator GLuint const&() const noexcept {
 | 
				
			||||||
		return id;
 | 
							return id;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -135,7 +135,7 @@ struct FrameBuffer {
 | 
				
			|||||||
		return fbo.id;
 | 
							return fbo.id;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constexpr operator const GLuint&() const noexcept {
 | 
						constexpr operator GLuint const&() const noexcept {
 | 
				
			||||||
		return fbo.id;
 | 
							return fbo.id;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -158,14 +158,14 @@ struct FrameBuffer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class FrameBufferBind {
 | 
					class FrameBufferBind {
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		static const FrameBuffer *s_activeFb;
 | 
							static FrameBuffer const *s_activeFb;
 | 
				
			||||||
		const FrameBuffer *m_restoreFb = nullptr;
 | 
							FrameBuffer const *m_restoreFb = nullptr;
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
		explicit FrameBufferBind(const FrameBuffer &fb) noexcept;
 | 
							explicit FrameBufferBind(FrameBuffer const &fb) noexcept;
 | 
				
			||||||
		~FrameBufferBind() noexcept;
 | 
							~FrameBufferBind() noexcept;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void bind(const FrameBuffer &fb) noexcept;
 | 
					void bind(FrameBuffer const &fb) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ShaderVarSet {
 | 
					struct ShaderVarSet {
 | 
				
			||||||
	GLsizei len{};
 | 
						GLsizei len{};
 | 
				
			||||||
@@ -176,7 +176,7 @@ struct ProgramSource {
 | 
				
			|||||||
	ox::Vector<glutils::ShaderVarSet> const shaderParams;
 | 
						ox::Vector<glutils::ShaderVarSet> const shaderParams;
 | 
				
			||||||
	GLsizei const rowLen = [this] {
 | 
						GLsizei const rowLen = [this] {
 | 
				
			||||||
		GLsizei len{};
 | 
							GLsizei len{};
 | 
				
			||||||
		for (auto const&v : shaderParams) {
 | 
							for (auto const &v : shaderParams) {
 | 
				
			||||||
			len += v.len;
 | 
								len += v.len;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return len;
 | 
							return len;
 | 
				
			||||||
@@ -187,23 +187,23 @@ struct ProgramSource {
 | 
				
			|||||||
	ox::String const geomShader{};
 | 
						ox::String const geomShader{};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ox::Result<GLProgram> buildShaderProgram(ProgramSource const&src) noexcept;
 | 
					ox::Result<GLProgram> buildShaderProgram(ProgramSource const &src) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ox::Result<GLProgram> buildShaderProgram(
 | 
					ox::Result<GLProgram> buildShaderProgram(
 | 
				
			||||||
		ox::CStringView const&vert,
 | 
							ox::CStringView const &vert,
 | 
				
			||||||
		ox::CStringView const&frag,
 | 
							ox::CStringView const &frag,
 | 
				
			||||||
		ox::CStringView const&geo = "") noexcept;
 | 
							ox::CStringView const &geo = "") noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setupShaderParams(
 | 
					void setupShaderParams(
 | 
				
			||||||
		GLProgram const&shader,
 | 
							GLProgram const &shader,
 | 
				
			||||||
		ox::Vector<ShaderVarSet> const&vars,
 | 
							ox::Vector<ShaderVarSet> const &vars,
 | 
				
			||||||
		GLsizei vertexRowLen) noexcept;
 | 
							GLsizei vertexRowLen) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setupShaderParams(GLProgram const&shader, ox::Vector<ShaderVarSet> const&vars) noexcept;
 | 
					void setupShaderParams(GLProgram const &shader, ox::Vector<ShaderVarSet> const &vars) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
glutils::GLVertexArray generateVertexArrayObject() noexcept;
 | 
					GLVertexArray generateVertexArrayObject() noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
glutils::GLBuffer generateBuffer() noexcept;
 | 
					GLBuffer generateBuffer() noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[nodiscard]]
 | 
					[[nodiscard]]
 | 
				
			||||||
FrameBuffer generateFrameBuffer(int width, int height) noexcept;
 | 
					FrameBuffer generateFrameBuffer(int width, int height) noexcept;
 | 
				
			||||||
@@ -215,20 +215,20 @@ void resizeFrameBuffer(FrameBuffer &fb, int width, int height) noexcept;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept;
 | 
					void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const&sz) noexcept;
 | 
					void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const &sz) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct BufferSet {
 | 
					struct BufferSet {
 | 
				
			||||||
	glutils::GLVertexArray vao;
 | 
						GLVertexArray vao;
 | 
				
			||||||
	glutils::GLBuffer vbo;
 | 
						GLBuffer vbo;
 | 
				
			||||||
	glutils::GLBuffer ebo;
 | 
						GLBuffer ebo;
 | 
				
			||||||
	glutils::GLTexture tex;
 | 
						GLTexture tex;
 | 
				
			||||||
	ox::Vector<float> vertices;
 | 
						ox::Vector<float> vertices;
 | 
				
			||||||
	ox::Vector<GLuint> elements;
 | 
						ox::Vector<GLuint> elements;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void sendVbo(BufferSet const&bs) noexcept;
 | 
					void sendVbo(BufferSet const &bs) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void sendEbo(BufferSet const&bs) noexcept;
 | 
					void sendEbo(BufferSet const &bs) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void clearScreen() noexcept;
 | 
					void clearScreen() noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										83
									
								
								deps/glutils/src/glutils.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										83
									
								
								deps/glutils/src/glutils.cpp
									
									
									
									
										vendored
									
									
								
							@@ -46,9 +46,9 @@ template struct GLObject<deleteVertexArray>;
 | 
				
			|||||||
template struct GLObject<deleteProgram>;
 | 
					template struct GLObject<deleteProgram>;
 | 
				
			||||||
template struct GLObject<deleteShader>;
 | 
					template struct GLObject<deleteShader>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const FrameBuffer *FrameBufferBind::s_activeFb = nullptr;
 | 
					FrameBuffer const *FrameBufferBind::s_activeFb = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FrameBufferBind::FrameBufferBind(const FrameBuffer &fb) noexcept: m_restoreFb(s_activeFb) {
 | 
					FrameBufferBind::FrameBufferBind(FrameBuffer const &fb) noexcept: m_restoreFb(s_activeFb) {
 | 
				
			||||||
	s_activeFb = &fb;
 | 
						s_activeFb = &fb;
 | 
				
			||||||
	glBindFramebuffer(GL_FRAMEBUFFER, fb);
 | 
						glBindFramebuffer(GL_FRAMEBUFFER, fb);
 | 
				
			||||||
	glViewport(0, 0, fb.width, fb.height);
 | 
						glViewport(0, 0, fb.width, fb.height);
 | 
				
			||||||
@@ -64,16 +64,16 @@ FrameBufferBind::~FrameBufferBind() noexcept {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void bind(const FrameBuffer &fb) noexcept {
 | 
					void bind(FrameBuffer const &fb) noexcept {
 | 
				
			||||||
	glBindFramebuffer(GL_FRAMEBUFFER, fb);
 | 
						glBindFramebuffer(GL_FRAMEBUFFER, fb);
 | 
				
			||||||
	glViewport(0, 0, fb.width, fb.height);
 | 
						glViewport(0, 0, fb.width, fb.height);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ox::Result<GLShader> buildShader(
 | 
					static ox::Result<GLShader> buildShader(
 | 
				
			||||||
		GLuint shaderType,
 | 
							GLuint const shaderType,
 | 
				
			||||||
		const GLchar *src,
 | 
							GLchar const *src,
 | 
				
			||||||
		ox::CRStringView shaderName) noexcept {
 | 
							ox::StringViewCR shaderName) noexcept {
 | 
				
			||||||
	GLShader shader(glCreateShader(shaderType));
 | 
						GLShader shader(glCreateShader(shaderType));
 | 
				
			||||||
	glShaderSource(shader, 1, &src, nullptr);
 | 
						glShaderSource(shader, 1, &src, nullptr);
 | 
				
			||||||
	glCompileShader(shader);
 | 
						glCompileShader(shader);
 | 
				
			||||||
@@ -83,13 +83,13 @@ static ox::Result<GLShader> buildShader(
 | 
				
			|||||||
		ox::Vector<char> errMsg(ox::units::KB);
 | 
							ox::Vector<char> errMsg(ox::units::KB);
 | 
				
			||||||
		glGetShaderInfoLog(shader, static_cast<GLsizei>(errMsg.size()), nullptr, errMsg.data());
 | 
							glGetShaderInfoLog(shader, static_cast<GLsizei>(errMsg.size()), nullptr, errMsg.data());
 | 
				
			||||||
		oxErrorf("shader compile error in {}: {}", shaderName, errMsg.data());
 | 
							oxErrorf("shader compile error in {}: {}", shaderName, errMsg.data());
 | 
				
			||||||
		return OxError(1, "shader compile error");
 | 
							return ox::Error(1, "shader compile error");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return shader;
 | 
						return shader;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ox::Result<GLProgram> buildShaderProgram(ProgramSource const&src) noexcept {
 | 
					ox::Result<GLProgram> buildShaderProgram(ProgramSource const &src) noexcept {
 | 
				
			||||||
	oxRequireM(program, buildShaderProgram(
 | 
						OX_REQUIRE_M(program, buildShaderProgram(
 | 
				
			||||||
			src.vertShader,
 | 
								src.vertShader,
 | 
				
			||||||
			src.fragShader,
 | 
								src.fragShader,
 | 
				
			||||||
			src.geomShader));
 | 
								src.geomShader));
 | 
				
			||||||
@@ -98,11 +98,11 @@ ox::Result<GLProgram> buildShaderProgram(ProgramSource const&src) noexcept {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setupShaderParams(
 | 
					void setupShaderParams(
 | 
				
			||||||
		GLProgram const&shader,
 | 
							GLProgram const &shader,
 | 
				
			||||||
		ox::Vector<ShaderVarSet> const&vars,
 | 
							ox::Vector<ShaderVarSet> const &vars,
 | 
				
			||||||
		GLsizei vertexRowLen) noexcept {
 | 
							GLsizei vertexRowLen) noexcept {
 | 
				
			||||||
	// setup vars
 | 
						// setup vars
 | 
				
			||||||
	for (size_t lenWritten = 0; auto const&v : vars) {
 | 
						for (size_t lenWritten = 0; auto const &v : vars) {
 | 
				
			||||||
		auto const attr = static_cast<GLuint>(glGetAttribLocation(shader, v.name.c_str()));
 | 
							auto const attr = static_cast<GLuint>(glGetAttribLocation(shader, v.name.c_str()));
 | 
				
			||||||
		glEnableVertexAttribArray(attr);
 | 
							glEnableVertexAttribArray(attr);
 | 
				
			||||||
		glVertexAttribPointer(
 | 
							glVertexAttribPointer(
 | 
				
			||||||
@@ -113,27 +113,27 @@ void setupShaderParams(
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setupShaderParams(GLProgram const&shader, ox::Vector<ShaderVarSet> const&vars) noexcept {
 | 
					void setupShaderParams(GLProgram const &shader, ox::Vector<ShaderVarSet> const &vars) noexcept {
 | 
				
			||||||
	// get row len
 | 
						// get row len
 | 
				
			||||||
	GLsizei vertexRowLen{};
 | 
						GLsizei vertexRowLen{};
 | 
				
			||||||
	for (auto const&v : vars) {
 | 
						for (auto const &v : vars) {
 | 
				
			||||||
		vertexRowLen += v.len;
 | 
							vertexRowLen += v.len;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	setupShaderParams(shader, vars, vertexRowLen);
 | 
						setupShaderParams(shader, vars, vertexRowLen);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ox::Result<GLProgram> buildShaderProgram(
 | 
					ox::Result<GLProgram> buildShaderProgram(
 | 
				
			||||||
		ox::CStringView const&vert,
 | 
							ox::CStringView const &vert,
 | 
				
			||||||
		ox::CStringView const&frag,
 | 
							ox::CStringView const &frag,
 | 
				
			||||||
		ox::CStringView const&geo) noexcept {
 | 
							ox::CStringView const &geo) noexcept {
 | 
				
			||||||
	GLProgram prgm(glCreateProgram());
 | 
						GLProgram prgm(glCreateProgram());
 | 
				
			||||||
	oxRequire(vs, buildShader(GL_VERTEX_SHADER, vert.c_str(), "vshad"));
 | 
						OX_REQUIRE(vs, buildShader(GL_VERTEX_SHADER, vert.c_str(), "vshad"));
 | 
				
			||||||
	glAttachShader(prgm, vs);
 | 
						glAttachShader(prgm, vs);
 | 
				
			||||||
	if (geo.c_str() && geo.bytes() != 0) {
 | 
						if (geo.c_str() && geo.bytes() != 0) {
 | 
				
			||||||
		oxRequire(gs, buildShader(GL_GEOMETRY_SHADER, geo.c_str(), "gshad"));
 | 
							OX_REQUIRE(gs, buildShader(GL_GEOMETRY_SHADER, geo.c_str(), "gshad"));
 | 
				
			||||||
		glAttachShader(prgm, gs);
 | 
							glAttachShader(prgm, gs);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxRequire(fs, buildShader(GL_FRAGMENT_SHADER, frag.c_str(), "fshad"));
 | 
						OX_REQUIRE(fs, buildShader(GL_FRAGMENT_SHADER, frag.c_str(), "fshad"));
 | 
				
			||||||
	glAttachShader(prgm, fs);
 | 
						glAttachShader(prgm, fs);
 | 
				
			||||||
	glLinkProgram(prgm);
 | 
						glLinkProgram(prgm);
 | 
				
			||||||
	return prgm;
 | 
						return prgm;
 | 
				
			||||||
@@ -162,16 +162,30 @@ FrameBuffer generateFrameBuffer(int width, int height) noexcept {
 | 
				
			|||||||
	// color texture
 | 
						// color texture
 | 
				
			||||||
	glGenTextures(1, &fb.color.id);
 | 
						glGenTextures(1, &fb.color.id);
 | 
				
			||||||
	glBindTexture(GL_TEXTURE_2D, fb.color);
 | 
						glBindTexture(GL_TEXTURE_2D, fb.color);
 | 
				
			||||||
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
 | 
						glTexImage2D(
 | 
				
			||||||
 | 
							GL_TEXTURE_2D,
 | 
				
			||||||
 | 
							0,
 | 
				
			||||||
 | 
							GL_RGB,
 | 
				
			||||||
 | 
							width,
 | 
				
			||||||
 | 
							height,
 | 
				
			||||||
 | 
							0,
 | 
				
			||||||
 | 
							GL_RGB,
 | 
				
			||||||
 | 
							GL_UNSIGNED_BYTE,
 | 
				
			||||||
 | 
							nullptr);
 | 
				
			||||||
	glGenerateMipmap(GL_TEXTURE_2D);
 | 
						glGenerateMipmap(GL_TEXTURE_2D);
 | 
				
			||||||
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 | 
						glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 | 
				
			||||||
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 | 
						glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 | 
				
			||||||
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb.color, 0);
 | 
						glFramebufferTexture2D(
 | 
				
			||||||
 | 
							GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb.color, 0);
 | 
				
			||||||
	// depth texture
 | 
						// depth texture
 | 
				
			||||||
	glGenRenderbuffers(1, &fb.depth.id);
 | 
						glGenRenderbuffers(1, &fb.depth.id);
 | 
				
			||||||
	glBindRenderbuffer(GL_RENDERBUFFER, fb.depth);
 | 
						glBindRenderbuffer(GL_RENDERBUFFER, fb.depth);
 | 
				
			||||||
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
 | 
						glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
 | 
				
			||||||
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb.depth);
 | 
						glFramebufferRenderbuffer(
 | 
				
			||||||
 | 
							GL_FRAMEBUFFER,
 | 
				
			||||||
 | 
							GL_DEPTH_STENCIL_ATTACHMENT,
 | 
				
			||||||
 | 
							GL_RENDERBUFFER,
 | 
				
			||||||
 | 
							fb.depth);
 | 
				
			||||||
	// verify FBO
 | 
						// verify FBO
 | 
				
			||||||
	oxAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Frame Buffer is incomplete");
 | 
						oxAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Frame Buffer is incomplete");
 | 
				
			||||||
	// restore primary FB
 | 
						// restore primary FB
 | 
				
			||||||
@@ -189,7 +203,16 @@ void resizeFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
 | 
				
			|||||||
	glBindFramebuffer(GL_FRAMEBUFFER, fb);
 | 
						glBindFramebuffer(GL_FRAMEBUFFER, fb);
 | 
				
			||||||
	// color texture
 | 
						// color texture
 | 
				
			||||||
	glBindTexture(GL_TEXTURE_2D, fb.color);
 | 
						glBindTexture(GL_TEXTURE_2D, fb.color);
 | 
				
			||||||
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
 | 
						glTexImage2D(
 | 
				
			||||||
 | 
							GL_TEXTURE_2D,
 | 
				
			||||||
 | 
							0,
 | 
				
			||||||
 | 
							GL_RGB,
 | 
				
			||||||
 | 
							width,
 | 
				
			||||||
 | 
							height,
 | 
				
			||||||
 | 
							0,
 | 
				
			||||||
 | 
							GL_RGB,
 | 
				
			||||||
 | 
							GL_UNSIGNED_BYTE,
 | 
				
			||||||
 | 
							nullptr);
 | 
				
			||||||
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 | 
						glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 | 
				
			||||||
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 | 
						glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 | 
				
			||||||
	// depth texture
 | 
						// depth texture
 | 
				
			||||||
@@ -201,7 +224,7 @@ void resizeFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
 | 
				
			|||||||
	glBindRenderbuffer(GL_RENDERBUFFER, 0);
 | 
						glBindRenderbuffer(GL_RENDERBUFFER, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
 | 
					void resizeInitFrameBuffer(FrameBuffer &fb, int const width, int const height) noexcept {
 | 
				
			||||||
	if (!fb) {
 | 
						if (!fb) {
 | 
				
			||||||
		fb = generateFrameBuffer(width, height);
 | 
							fb = generateFrameBuffer(width, height);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
@@ -209,18 +232,18 @@ void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
 | 
				
			|||||||
	resizeFrameBuffer(fb, width, height);
 | 
						resizeFrameBuffer(fb, width, height);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const&sz) noexcept {
 | 
					void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const &sz) noexcept {
 | 
				
			||||||
	resizeInitFrameBuffer(fb, sz.width, sz.height);
 | 
						resizeInitFrameBuffer(fb, sz.width, sz.height);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void sendVbo(BufferSet const&bs) noexcept {
 | 
					void sendVbo(BufferSet const &bs) noexcept {
 | 
				
			||||||
	const auto bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.vertices)::value_type) * bs.vertices.size());
 | 
						auto const bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.vertices)::value_type) * bs.vertices.size());
 | 
				
			||||||
	glBindBuffer(GL_ARRAY_BUFFER, bs.vbo);
 | 
						glBindBuffer(GL_ARRAY_BUFFER, bs.vbo);
 | 
				
			||||||
	glBufferData(GL_ARRAY_BUFFER, bufferSize, bs.vertices.data(), GL_DYNAMIC_DRAW);
 | 
						glBufferData(GL_ARRAY_BUFFER, bufferSize, bs.vertices.data(), GL_DYNAMIC_DRAW);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void sendEbo(BufferSet const&bs) noexcept {
 | 
					void sendEbo(BufferSet const &bs) noexcept {
 | 
				
			||||||
	const auto bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.elements)::value_type) * bs.elements.size());
 | 
						auto const bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.elements)::value_type) * bs.elements.size());
 | 
				
			||||||
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bs.ebo);
 | 
						glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bs.ebo);
 | 
				
			||||||
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferSize, bs.elements.data(), GL_STATIC_DRAW);
 | 
						glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferSize, bs.elements.data(), GL_STATIC_DRAW);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								deps/imgui/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								deps/imgui/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,7 @@ endif()
 | 
				
			|||||||
# DrinkingTea: end
 | 
					# DrinkingTea: end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_library(
 | 
					add_library(
 | 
				
			||||||
	imgui OBJECT
 | 
						imgui
 | 
				
			||||||
		imgui.cpp
 | 
							imgui.cpp
 | 
				
			||||||
		imgui_demo.cpp
 | 
							imgui_demo.cpp
 | 
				
			||||||
		imgui_draw.cpp
 | 
							imgui_draw.cpp
 | 
				
			||||||
@@ -20,3 +20,11 @@ target_include_directories(
 | 
				
			|||||||
	imgui SYSTEM PUBLIC
 | 
						imgui SYSTEM PUBLIC
 | 
				
			||||||
		.
 | 
							.
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install(
 | 
				
			||||||
 | 
						TARGETS
 | 
				
			||||||
 | 
							imgui
 | 
				
			||||||
 | 
						DESTINATION
 | 
				
			||||||
 | 
							LIBRARY DESTINATION lib
 | 
				
			||||||
 | 
							ARCHIVE DESTINATION lib
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								deps/nfde/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								deps/nfde/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							@@ -1,4 +1,4 @@
 | 
				
			|||||||
cmake_minimum_required(VERSION 3.5)
 | 
					cmake_minimum_required(VERSION 3.19)
 | 
				
			||||||
project(nativefiledialog-extended VERSION 1.1.1)
 | 
					project(nativefiledialog-extended VERSION 1.1.1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(nfd_ROOT_PROJECT OFF)
 | 
					set(nfd_ROOT_PROJECT OFF)
 | 
				
			||||||
@@ -10,7 +10,11 @@ if(NOT DEFINED BUILD_SHARED_LIBS)
 | 
				
			|||||||
	option(BUILD_SHARED_LIBS "Build a shared library instead of static" OFF)
 | 
						option(BUILD_SHARED_LIBS "Build a shared library instead of static" OFF)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
option(NFD_BUILD_TESTS "Build tests for nfd" ${nfd_ROOT_PROJECT})
 | 
					option(NFD_BUILD_TESTS "Build tests for nfd" ${nfd_ROOT_PROJECT})
 | 
				
			||||||
option(NFD_INSTALL "Generate install target for nfd" ${nfd_ROOT_PROJECT})
 | 
					# DrinkingTea: begin
 | 
				
			||||||
 | 
					if(NOT DEFINED NFD_INSTALL)
 | 
				
			||||||
 | 
						option(NFD_INSTALL "Generate install target for nfd" ${nfd_ROOT_PROJECT})
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					# DrinkingTea: end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(nfd_PLATFORM Undefined)
 | 
					set(nfd_PLATFORM Undefined)
 | 
				
			||||||
if(WIN32)
 | 
					if(WIN32)
 | 
				
			||||||
@@ -21,7 +25,9 @@ elseif(UNIX AND NOT APPLE)
 | 
				
			|||||||
  set(nfd_PLATFORM PLATFORM_UNIX)
 | 
					  set(nfd_PLATFORM PLATFORM_UNIX)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
message("nfd Platform: ${nfd_PLATFORM}")
 | 
					# DrinkingTea: begin
 | 
				
			||||||
 | 
					#message("nfd Platform: ${nfd_PLATFORM}")
 | 
				
			||||||
 | 
					# DrinkingTea: end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(nfd_COMPILER Undefined)
 | 
					set(nfd_COMPILER Undefined)
 | 
				
			||||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
 | 
					if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
 | 
				
			||||||
@@ -33,7 +39,9 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "C
 | 
				
			|||||||
  set(nfd_COMPILER COMPILER_GNU)
 | 
					  set(nfd_COMPILER COMPILER_GNU)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
message("nfd Compiler: ${nfd_COMPILER}")
 | 
					# DrinkingTea: begin
 | 
				
			||||||
 | 
					#message("nfd Compiler: ${nfd_COMPILER}")
 | 
				
			||||||
 | 
					# DrinkingTea: end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Use latest C++ by default (should be the best one), but let user override it
 | 
					# Use latest C++ by default (should be the best one), but let user override it
 | 
				
			||||||
if(NOT DEFINED CMAKE_CXX_STANDARD)
 | 
					if(NOT DEFINED CMAKE_CXX_STANDARD)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								deps/nfde/src/nfd_win.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								deps/nfde/src/nfd_win.cpp
									
									
									
									
										vendored
									
									
								
							@@ -201,7 +201,7 @@ nfdresult_t SetDefaultExtension(::IFileDialog* fileOpenDialog,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    if (*p_spec) {
 | 
					    if (*p_spec) {
 | 
				
			||||||
        // multiple file extensions for this type (need to allocate memory)
 | 
					        // multiple file extensions for this type (need to allocate memory)
 | 
				
			||||||
        size_t numChars = p_spec - filterList[0].spec;
 | 
					        size_t numChars = static_cast<size_t>(p_spec - filterList[0].spec);
 | 
				
			||||||
        // allocate one more char space for the '\0'
 | 
					        // allocate one more char space for the '\0'
 | 
				
			||||||
        nfdnchar_t* extnBuf = NFDi_Malloc<nfdnchar_t>(sizeof(nfdnchar_t) * (numChars + 1));
 | 
					        nfdnchar_t* extnBuf = NFDi_Malloc<nfdnchar_t>(sizeof(nfdnchar_t) * (numChars + 1));
 | 
				
			||||||
        if (!extnBuf) {
 | 
					        if (!extnBuf) {
 | 
				
			||||||
@@ -710,7 +710,7 @@ nfdresult_t CopyCharToWChar(const nfdu8char_t* inStr, nfdnchar_t*& outStr) {
 | 
				
			|||||||
    int charsNeeded = MultiByteToWideChar(CP_UTF8, 0, inStr, -1, nullptr, 0);
 | 
					    int charsNeeded = MultiByteToWideChar(CP_UTF8, 0, inStr, -1, nullptr, 0);
 | 
				
			||||||
    assert(charsNeeded);
 | 
					    assert(charsNeeded);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    nfdnchar_t* tmp_outStr = NFDi_Malloc<nfdnchar_t>(sizeof(nfdnchar_t) * charsNeeded);
 | 
					    nfdnchar_t* tmp_outStr = NFDi_Malloc<nfdnchar_t>(sizeof(nfdnchar_t) * static_cast<size_t>(charsNeeded));
 | 
				
			||||||
    if (!tmp_outStr) {
 | 
					    if (!tmp_outStr) {
 | 
				
			||||||
        return NFD_ERROR;
 | 
					        return NFD_ERROR;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -727,7 +727,7 @@ nfdresult_t CopyWCharToNFDChar(const nfdnchar_t* inStr, nfdu8char_t*& outStr) {
 | 
				
			|||||||
    int bytesNeeded = WideCharToMultiByte(CP_UTF8, 0, inStr, -1, nullptr, 0, nullptr, nullptr);
 | 
					    int bytesNeeded = WideCharToMultiByte(CP_UTF8, 0, inStr, -1, nullptr, 0, nullptr, nullptr);
 | 
				
			||||||
    assert(bytesNeeded);
 | 
					    assert(bytesNeeded);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    nfdu8char_t* tmp_outStr = NFDi_Malloc<nfdu8char_t>(sizeof(nfdu8char_t) * bytesNeeded);
 | 
					    nfdu8char_t* tmp_outStr = NFDi_Malloc<nfdu8char_t>(sizeof(nfdu8char_t) * static_cast<size_t>(bytesNeeded));
 | 
				
			||||||
    if (!tmp_outStr) {
 | 
					    if (!tmp_outStr) {
 | 
				
			||||||
        return NFD_ERROR;
 | 
					        return NFD_ERROR;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/.liccor.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/.liccor.yml
									
									
									
									
										vendored
									
									
								
							@@ -2,7 +2,7 @@
 | 
				
			|||||||
source:
 | 
					source:
 | 
				
			||||||
- src
 | 
					- src
 | 
				
			||||||
copyright_notice: |-
 | 
					copyright_notice: |-
 | 
				
			||||||
  Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					  Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  This Source Code Form is subject to the terms of the Mozilla Public
 | 
					  This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
  License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					  License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								deps/ox/deps/cityhash/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								deps/ox/deps/cityhash/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							@@ -9,9 +9,6 @@ set(CMAKE_CXX_EXTENSIONS OFF)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
 | 
					set(CMAKE_POSITION_INDEPENDENT_CODE ON)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(NOSTALGIA_BUILD_PLAYER OFF)
 | 
					 | 
				
			||||||
set(NOSTALGIA_BUILD_STUDIO_APP OFF)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
 | 
					set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
 | 
				
			||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
 | 
					set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
 | 
				
			||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
 | 
					set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
 | 
				
			||||||
@@ -28,3 +25,10 @@ endif()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
add_library(CityHash INTERFACE)
 | 
					add_library(CityHash INTERFACE)
 | 
				
			||||||
target_include_directories(CityHash INTERFACE include)
 | 
					target_include_directories(CityHash INTERFACE include)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install(
 | 
				
			||||||
 | 
					    DIRECTORY
 | 
				
			||||||
 | 
					        include/cityhash
 | 
				
			||||||
 | 
					    DESTINATION
 | 
				
			||||||
 | 
					        include
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -104,6 +104,11 @@ using size_t = decltype(alignof(int));
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __clang__
 | 
				
			||||||
 | 
					#pragma clang diagnostic push
 | 
				
			||||||
 | 
					#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace cityhash::detail {
 | 
					namespace cityhash::detail {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
@@ -671,4 +676,8 @@ constexpr uint128 CityHash128(const char *s, size_t len) noexcept {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __clang__
 | 
				
			||||||
 | 
					#pragma clang diagnostic pop
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif  // CITY_HASH_H_
 | 
					#endif  // CITY_HASH_H_
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/deps/jsoncpp/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/deps/jsoncpp/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							@@ -12,7 +12,7 @@
 | 
				
			|||||||
# CMake versions greater than the JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION policies will
 | 
					# CMake versions greater than the JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION policies will
 | 
				
			||||||
# continue to generate policy warnings "CMake Warning (dev)...Policy CMP0XXX is not set:"
 | 
					# continue to generate policy warnings "CMake Warning (dev)...Policy CMP0XXX is not set:"
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
set(JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION "3.8.0")
 | 
					set(JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION "3.13.2")
 | 
				
			||||||
set(JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION "3.13.2")
 | 
					set(JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION "3.13.2")
 | 
				
			||||||
cmake_minimum_required(VERSION ${JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION})
 | 
					cmake_minimum_required(VERSION ${JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION})
 | 
				
			||||||
if("${CMAKE_VERSION}" VERSION_LESS "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}")
 | 
					if("${CMAKE_VERSION}" VERSION_LESS "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}")
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										478
									
								
								deps/ox/ox-docs.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										478
									
								
								deps/ox/ox-docs.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,478 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					# Ox Docs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Project Structure
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All components have a platform indicator next to them:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (OB) - OS, Bare Metal
 | 
				
			||||||
 | 
					    (-B) - Bare Metal
 | 
				
			||||||
 | 
					    (O-) - OS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Ox - Library of things useful for portable bare metal and userland code. Not really that external...
 | 
				
			||||||
 | 
					    * clargs - Command Line Args processing (OB)
 | 
				
			||||||
 | 
					    * claw - Reads and writes Metal or Organic Claw with header to indicate which
 | 
				
			||||||
 | 
					    * event - Qt-like signal system (OB)
 | 
				
			||||||
 | 
					    * fs - file system (OB)
 | 
				
			||||||
 | 
					        * logconn - connects logging to Bullock (O-)
 | 
				
			||||||
 | 
					    * mc - Metal Claw serialization, builds on model (OB)
 | 
				
			||||||
 | 
					    * oc - Organic Claw serialization (wrapper around JsonCpp), builds on model (O-)
 | 
				
			||||||
 | 
					    * model - Data structure modelling (OB)
 | 
				
			||||||
 | 
					        * preloader - library for handling preloading of data (OB)
 | 
				
			||||||
 | 
					    * std - Standard-ish Library with a lot missing and some things added (OB)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Systems
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Error Handling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ox provides ```ox::Error``` to report errors.
 | 
				
			||||||
 | 
					```ox::Error``` is a struct that has overloaded operators to behave like an
 | 
				
			||||||
 | 
					integer error code, plus some extra fields to enhance debuggability.
 | 
				
			||||||
 | 
					If instantiated through the ```OxError(x)``` macro, it will also include the
 | 
				
			||||||
 | 
					file and line of the error.
 | 
				
			||||||
 | 
					The ```OxError(x)``` macro should only be used for the initial instantiation of
 | 
				
			||||||
 | 
					an ```ox::Error```.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In addition to ```ox::Error``` there is also the template ```ox::Result<T>```.
 | 
				
			||||||
 | 
					```ox::Result``` simply wraps the type T value in a struct that also includes
 | 
				
			||||||
 | 
					error information, which allows the returning of a value and an error without
 | 
				
			||||||
 | 
					resorting to output parameters.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If a function returns an ```ox::Error``` or ```ox::Result``` it should be
 | 
				
			||||||
 | 
					declared as ```noexcept``` and all exceptions should be translated to an
 | 
				
			||||||
 | 
					```ox::Error```.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ox::Result``` can be used as follows:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					ox::Result<int> foo(int i) noexcept {
 | 
				
			||||||
 | 
						if (i < 10) {
 | 
				
			||||||
 | 
							return i + 1; // implicitly calls ox::Result<T>::Result(T)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return OxError(1); // implicitly calls ox::Result<T>::Result(ox::Error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int caller1() {
 | 
				
			||||||
 | 
						auto v = foo(argc);
 | 
				
			||||||
 | 
						if (v.error) {
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						std::cout << v.value << '\n';
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int caller2() {
 | 
				
			||||||
 | 
						// it is also possible to capture the value and error in their own variables
 | 
				
			||||||
 | 
						auto [val, err] = foo(argc);
 | 
				
			||||||
 | 
						if (err) {
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						std::cout << val << '\n';
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Error caller3(int &i) {
 | 
				
			||||||
 | 
					    return foo(i).moveTo(i);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Error caller4(int &i) {
 | 
				
			||||||
 | 
					    return foo(i).copyTo(i);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int caller5(int i) {
 | 
				
			||||||
 | 
					    return foo(i).unwrap(); // unwrap will kill the program if there is an error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int caller6(int i) {
 | 
				
			||||||
 | 
					    return foo(i).unwrapThrow(); // unwrap will throw if there is an error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int caller7(int i) {
 | 
				
			||||||
 | 
					    return foo(i).or_value(0); // will return 0 if foo returned an error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<uint64_t> caller8(int i) {
 | 
				
			||||||
 | 
					    return foo(i).to<uint64_t>(); // will convert the result of foo to uint64_t
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Lastly, there are a few macros available to help in passing ```ox::Error```s
 | 
				
			||||||
 | 
					back up the call stack, ```OX_RETURN_ERROR```, ```OX_THROW_ERROR```, and
 | 
				
			||||||
 | 
					```OX_REQUIRE```.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```OX_RETURN_ERROR``` is by far the more helpful of the two.
 | 
				
			||||||
 | 
					```OX_RETURN_ERROR``` will return an ```ox::Error``` if it is not 0 and
 | 
				
			||||||
 | 
					```OX_THROW_ERROR``` will throw an ```ox::Error``` if it is not 0.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Since ```ox::Error``` is always nodiscard, you must do something with them.
 | 
				
			||||||
 | 
					In rare cases, you may not have anything you can do with them or you may know
 | 
				
			||||||
 | 
					the code will never fail in that particular instance.
 | 
				
			||||||
 | 
					This should be used sparingly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					void studioCode() {
 | 
				
			||||||
 | 
						auto [val, err] = foo(1);
 | 
				
			||||||
 | 
						OX_THROW_ERROR(err);
 | 
				
			||||||
 | 
						doStuff(val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Error engineCode() noexcept {
 | 
				
			||||||
 | 
						auto [val, err] = foo(1);
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(err);
 | 
				
			||||||
 | 
						doStuff(val);
 | 
				
			||||||
 | 
						return {};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void anyCode() {
 | 
				
			||||||
 | 
					    auto [val, err] = foo(1);
 | 
				
			||||||
 | 
					    std::ignore = err;
 | 
				
			||||||
 | 
					    doStuff(val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Both macros will also take the ```ox::Result``` directly:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					void studioCode() {
 | 
				
			||||||
 | 
						auto valerr = foo(1);
 | 
				
			||||||
 | 
						OX_THROW_ERROR(valerr);
 | 
				
			||||||
 | 
						doStuff(valerr.value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Error engineCode() noexcept {
 | 
				
			||||||
 | 
						auto valerr = foo(1);
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(valerr);
 | 
				
			||||||
 | 
						doStuff(valerr.value);
 | 
				
			||||||
 | 
						return {};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ox also has the ```OX_REQUIRE``` macro, which will initialize a value if there is no error, and return if there is.
 | 
				
			||||||
 | 
					It aims to somewhat emulate the ```?``` operator in Rust and Swift.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Rust ```?``` operator:
 | 
				
			||||||
 | 
					```rust
 | 
				
			||||||
 | 
					fn f() -> Result<i32, i32> {
 | 
				
			||||||
 | 
					  // do stuff
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn f2() -> Result<i32, i32> {
 | 
				
			||||||
 | 
					  let i = f()?;
 | 
				
			||||||
 | 
					  Ok(i + 4)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```OX_REQUIRE```:
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					ox::Result<int> f() noexcept {
 | 
				
			||||||
 | 
						// do stuff
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<int> f2() noexcept {
 | 
				
			||||||
 | 
						OX_REQUIRE(i, f()); // const auto [out, OX_CONCAT(oxRequire_err_, __LINE__)] = x; OX_RETURN_ERROR(OX_CONCAT(oxRequire_err_, __LINE__))
 | 
				
			||||||
 | 
						return i + 4;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					```OX_REQUIRE``` is not quite as versatile, but it should still cleanup a lot of otherwise less ideal code.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```OX_REQUIRE``` by default creates a const, but there is also an ```OX_REQUIRE_M``` (OX_REQUIRE Mutable)
 | 
				
			||||||
 | 
					variant for creating a non-const value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* ```OX_REQUIRE_M``` - OX_REQUIRE Mutable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Logging and Output
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ox provides for logging and debug prints via the ```oxTrace```, ```oxDebug```, and ```oxError``` macros.
 | 
				
			||||||
 | 
					Each of these also provides a format variation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ox also provide ```oxOut``` and ```oxErr``` for printing to stdout and stderr.
 | 
				
			||||||
 | 
					These are intended for permanent messages and always go to stdout and stderr.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tracing functions do not go to stdout unless the OXTRACE environment variable is set.
 | 
				
			||||||
 | 
					They also print with the channel that they are on, along with file and line.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Debug statements go to stdout and go to the logger on the "debug" channel.
 | 
				
			||||||
 | 
					Where trace statements are intended to be written with thoughtfulness,
 | 
				
			||||||
 | 
					debug statements are intended to be quick and temporary insertions.
 | 
				
			||||||
 | 
					Debug statements trigger compilation failures if OX_NODEBUG is enabled when CMake is run,
 | 
				
			||||||
 | 
					as it is on Jenkins builds, so ```oxDebug``` statements should never be checked in.
 | 
				
			||||||
 | 
					This makes ```oxDebug``` preferable to other forms of logging, as temporary prints should
 | 
				
			||||||
 | 
					never be checked in.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```oxError``` always prints.
 | 
				
			||||||
 | 
					It includes file and line, and is prefixed with a red "ERROR:".
 | 
				
			||||||
 | 
					It should generally be used conservatively.
 | 
				
			||||||
 | 
					It should be used only when there is an error that is not technically fatal, but
 | 
				
			||||||
 | 
					the user almost certainly wants to know about it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```oxTrace``` and ```oxTracef```:
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					void f(int x, int y) { // x = 9, y = 4
 | 
				
			||||||
 | 
						oxTrace("nostalgia.core.sdl.gfx") << "f:" << x << y; // Output: "f: 9 4"
 | 
				
			||||||
 | 
						oxTracef("nostalgia.core.sdl.gfx", "f: {}, {}", x, y); // Output: "f: 9, 4"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```oxDebug``` and ```oxDebugf```:
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					void f(int x, int y) { // x = 9, y = 4
 | 
				
			||||||
 | 
						oxDebug() << "f:" << x << y; // Output: "f: 9 4"
 | 
				
			||||||
 | 
						oxDebugf("f: {}, {}", x, y); // Output: "f: 9, 4"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```oxError``` and ```oxErrorf```:
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					void f(int x, int y) { // x = 9, y = 4
 | 
				
			||||||
 | 
						oxError() << "f:" << x << y; // Output: "ERROR: (<file>:<line>): f: 9 4"
 | 
				
			||||||
 | 
						oxErrorf("f: {}, {}", x, y); // Output: "ERROR: (<file>:<line>): f: 9, 4"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Model System
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ox has a model system that provides a sort of manual reflection mechanism.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Models require a model function for the type that you want to model.
 | 
				
			||||||
 | 
					It is also good to provide a type name and type version number, though that is not required.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The model function takes an instance of the type it is modelling and a template
 | 
				
			||||||
 | 
					parameter type.
 | 
				
			||||||
 | 
					The template parameter type must implement the API used in the models, but it
 | 
				
			||||||
 | 
					can do anything with the data provided to it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Here is an example from the Nostalgia/Core package:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					struct NostalgiaPalette {
 | 
				
			||||||
 | 
						static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.NostalgiaPalette";
 | 
				
			||||||
 | 
						static constexpr auto TypeVersion = 1;
 | 
				
			||||||
 | 
						ox::Vector<Color16> colors;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct NostalgiaGraphic {
 | 
				
			||||||
 | 
						static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.NostalgiaGraphic";
 | 
				
			||||||
 | 
						static constexpr auto TypeVersion = 1;
 | 
				
			||||||
 | 
						int8_t bpp = 0;
 | 
				
			||||||
 | 
						// rows and columns are really only used by TileSheetEditor
 | 
				
			||||||
 | 
						int rows = 1;
 | 
				
			||||||
 | 
						int columns = 1;
 | 
				
			||||||
 | 
						ox::FileAddress defaultPalette;
 | 
				
			||||||
 | 
						NostalgiaPalette pal;
 | 
				
			||||||
 | 
						ox::Vector<uint8_t> pixels;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T>
 | 
				
			||||||
 | 
					constexpr ox::Error model(T *h, ox::CommonPtrWith<NostalgiaPalette> auto *pal) noexcept {
 | 
				
			||||||
 | 
						h->template setTypeInfo<NostalgiaPalette>();
 | 
				
			||||||
 | 
						// it is also possible to provide the type name and type version as function arguments
 | 
				
			||||||
 | 
						//h->setTypeInfo("net.drinkingtea.nostalgia.core.NostalgiaPalette", 1);
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(h->field("colors", &pal->colors));
 | 
				
			||||||
 | 
						return {};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T>
 | 
				
			||||||
 | 
					constexpr ox::Error model(T *h, ox::CommonPtrWith<NostalgiaGraphic> auto *ng) noexcept {
 | 
				
			||||||
 | 
						h->template setTypeInfo<NostalgiaGraphic>();
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(h->field("bpp", &ng->bpp));
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(h->field("rows", &ng->rows));
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(h->field("columns", &ng->columns));
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(h->field("defaultPalette", &ng->defaultPalette));
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(h->field("pal", &ng->pal));
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(h->field("pixels", &ng->pixels));
 | 
				
			||||||
 | 
						return {};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The model system also provides for unions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ox/model/types.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class FileAddress {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						template<typename T>
 | 
				
			||||||
 | 
						friend constexpr Error model(T*, ox::CommonPtrWith<FileAddress> auto*) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							union Data {
 | 
				
			||||||
 | 
								static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress.Data";
 | 
				
			||||||
 | 
								char *path;
 | 
				
			||||||
 | 
								const char *constPath;
 | 
				
			||||||
 | 
								uint64_t inode;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected:
 | 
				
			||||||
 | 
							FileAddressType m_type = FileAddressType::None;
 | 
				
			||||||
 | 
							Data m_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T>
 | 
				
			||||||
 | 
					constexpr Error model(T *h, ox::CommonPtrWith<FileAddress::Data> auto *obj) noexcept {
 | 
				
			||||||
 | 
						h->template setTypeInfo<FileAddress::Data>();
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(h->fieldCString("path", &obj->path));
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(h->fieldCString("constPath", &obj->path));
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(h->field("inode", &obj->inode));
 | 
				
			||||||
 | 
						return {};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T>
 | 
				
			||||||
 | 
					constexpr Error model(T *io, ox::CommonPtrWith<FileAddress> auto *fa) noexcept {
 | 
				
			||||||
 | 
						io->template setTypeInfo<FileAddress>();
 | 
				
			||||||
 | 
						// cannot read from object in Reflect operation
 | 
				
			||||||
 | 
						if constexpr(ox_strcmp(T::opType(), OpType::Reflect) == 0) {
 | 
				
			||||||
 | 
							int8_t type = 0;
 | 
				
			||||||
 | 
							OX_RETURN_ERROR(io->field("type", &type));
 | 
				
			||||||
 | 
							OX_RETURN_ERROR(io->field("data", UnionView(&fa->m_data, 0)));
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							auto type = static_cast<int8_t>(fa->m_type);
 | 
				
			||||||
 | 
							OX_RETURN_ERROR(io->field("type", &type));
 | 
				
			||||||
 | 
							fa->m_type = static_cast<FileAddressType>(type);
 | 
				
			||||||
 | 
							OX_RETURN_ERROR(io->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return {};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There are also macros in ```<ox/model/def.hpp>``` for simplifying the declaration of models:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					OX_MODEL_BEGIN(NostalgiaGraphic)
 | 
				
			||||||
 | 
						OX_MODEL_FIELD(bpp)
 | 
				
			||||||
 | 
						OX_MODEL_FIELD(rows)
 | 
				
			||||||
 | 
						OX_MODEL_FIELD(columns)
 | 
				
			||||||
 | 
						OX_MODEL_FIELD(defaultPalette)
 | 
				
			||||||
 | 
						OX_MODEL_FIELD(pal)
 | 
				
			||||||
 | 
						OX_MODEL_FIELD(pixels)
 | 
				
			||||||
 | 
					oxModelEnd()
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Serialization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Using the model system, Ox provides for serialization.
 | 
				
			||||||
 | 
					Ox has MetalClaw and OrganicClaw as its serialization format options.
 | 
				
			||||||
 | 
					MetalClaw is a custom binary format designed for minimal size.
 | 
				
			||||||
 | 
					OrganicClaw is a wrapper around JsonCpp, chosen because it technically
 | 
				
			||||||
 | 
					implements a superset of JSON.
 | 
				
			||||||
 | 
					OrganicClaw requires support for 64 bit integers, whereas normal JSON
 | 
				
			||||||
 | 
					technically does not.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					These formats do not currently support floats.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There is also a wrapper format called Claw that provides a header at the
 | 
				
			||||||
 | 
					beginning of the file and can dynamically switch between the two depending on
 | 
				
			||||||
 | 
					what the header says is present.
 | 
				
			||||||
 | 
					The Claw header also includes information about the type and type version of
 | 
				
			||||||
 | 
					the data.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Claw header: ```M1;net.drinkingtea.nostalgia.core.NostalgiaPalette;1;```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					That reads:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Format is Metal Claw, version 1
 | 
				
			||||||
 | 
					* Type ID is net.drinkingtea.nostalgia.core.NostalgiaPalette
 | 
				
			||||||
 | 
					* Type version is 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Metal Claw Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##### Read
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					#include <ox/mc/read.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<NostalgiaPalette> loadPalette1(ox::BufferView const&buff) noexcept {
 | 
				
			||||||
 | 
						return ox::readMC<NostalgiaPalette>(buff);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept {
 | 
				
			||||||
 | 
						NostalgiaPalette pal;
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(ox::readMC(buff, pal));
 | 
				
			||||||
 | 
						return pal;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##### Write
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					#include <ox/mc/write.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<ox::Buffer> writeSpritePalette1(NostalgiaPalette const&pal) noexcept {
 | 
				
			||||||
 | 
						ox::Buffer buffer(ox::units::MB);
 | 
				
			||||||
 | 
						std::size_t sz = 0;
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(ox::writeMC(buffer.data(), buffer.size(), pal, &sz));
 | 
				
			||||||
 | 
						buffer.resize(sz);
 | 
				
			||||||
 | 
						return buffer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<ox::Buffer> writeSpritePalette2(NostalgiaPalette const&pal) noexcept {
 | 
				
			||||||
 | 
						return ox::writeMC(pal);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Organic Claw Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##### Read
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					#include <ox/oc/read.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<NostalgiaPalette> loadPalette1(ox::BufferView const&buff) noexcept {
 | 
				
			||||||
 | 
						return ox::readOC<NostalgiaPalette>(buff);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept {
 | 
				
			||||||
 | 
						NostalgiaPalette pal;
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(ox::readOC(buff, &pal));
 | 
				
			||||||
 | 
						return pal;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##### Write
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					#include <ox/oc/write.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<ox::Buffer> writeSpritePalette1(NostalgiaPalette const&pal) noexcept {
 | 
				
			||||||
 | 
						ox::Buffer buffer(ox::units::MB);
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(ox::writeOC(buffer.data(), buffer.size(), pal));
 | 
				
			||||||
 | 
						return buffer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<ox::Buffer> writeSpritePalette2(NostalgiaPalette const&pal) noexcept {
 | 
				
			||||||
 | 
						return ox::writeOC(pal);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Claw Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##### Read
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					#include <ox/claw/read.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<NostalgiaPalette> loadPalette1(ox::BufferView const&buff) noexcept {
 | 
				
			||||||
 | 
						return ox::readClaw<NostalgiaPalette>(buff);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept {
 | 
				
			||||||
 | 
						NostalgiaPalette pal;
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(ox::readClaw(buff, pal));
 | 
				
			||||||
 | 
						return pal;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##### Write
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```cpp
 | 
				
			||||||
 | 
					#include <ox/claw/write.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<ox::Buffer> writeSpritePalette(NostalgiaPalette const&pal) noexcept {
 | 
				
			||||||
 | 
						return ox::writeClaw(pal);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
							
								
								
									
										7
									
								
								deps/ox/src/ox/clargs/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								deps/ox/src/ox/clargs/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							@@ -1,4 +1,9 @@
 | 
				
			|||||||
cmake_minimum_required(VERSION 3.10)
 | 
					
 | 
				
			||||||
 | 
					if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
 | 
				
			||||||
 | 
						# enable warnings
 | 
				
			||||||
 | 
						set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-buffer-usage")
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_library(
 | 
					add_library(
 | 
				
			||||||
	OxClArgs
 | 
						OxClArgs
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										46
									
								
								deps/ox/src/ox/clargs/clargs.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								deps/ox/src/ox/clargs/clargs.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -11,23 +11,25 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace ox {
 | 
					namespace ox {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ClArgs::ClArgs(int argc, const char **args) noexcept {
 | 
					ClArgs::ClArgs(int argc, const char **args) noexcept: ClArgs({args, static_cast<size_t>(argc)}) {}
 | 
				
			||||||
	for (auto i = 0u; i < static_cast<unsigned>(argc); ++i) {
 | 
					
 | 
				
			||||||
		auto arg = String(args[i]);
 | 
					ClArgs::ClArgs(ox::SpanView<const char*> args) noexcept {
 | 
				
			||||||
 | 
						for (auto i = 0u; i < args.size(); ++i) {
 | 
				
			||||||
 | 
							auto arg = StringView{args[i]};
 | 
				
			||||||
		if (arg[0] == '-') {
 | 
							if (arg[0] == '-') {
 | 
				
			||||||
			while (arg[0] == '-' && arg.len()) {
 | 
								while (arg[0] == '-' && arg.size()) {
 | 
				
			||||||
				arg = arg.substr(1);
 | 
									arg = substr(arg, 1);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			m_bools[arg] = true;
 | 
								m_bools[arg] = true;
 | 
				
			||||||
			// parse additional arguments
 | 
								// parse additional arguments
 | 
				
			||||||
			if (i < static_cast<unsigned>(argc) && args[i + 1]) {
 | 
								if (i < args.size() && args[i + 1]) {
 | 
				
			||||||
				auto val = String(args[i + 1]);
 | 
									auto const val = StringView{args[i + 1]};
 | 
				
			||||||
				if (val.len() && val[i] != '-') {
 | 
									if (val.size() && val[0] != '-') {
 | 
				
			||||||
					if (val == "false") {
 | 
										if (val == "false") {
 | 
				
			||||||
						m_bools[arg] = false;
 | 
											m_bools[arg] = false;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					m_strings[arg] = val;
 | 
										m_strings[arg] = val;
 | 
				
			||||||
					if (auto r = ox::atoi(val.c_str()); r.error == 0) {
 | 
										if (auto r = ox::strToInt(val); r.error == 0) {
 | 
				
			||||||
						m_ints[arg] = r.value;
 | 
											m_ints[arg] = r.value;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					++i;
 | 
										++i;
 | 
				
			||||||
@@ -37,33 +39,33 @@ ClArgs::ClArgs(int argc, const char **args) noexcept {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool ClArgs::getBool(ox::CRStringView arg, bool defaultValue) const noexcept {
 | 
					bool ClArgs::getBool(ox::StringViewCR arg, bool defaultValue) const noexcept {
 | 
				
			||||||
	auto [value, err] = m_ints.at(arg);
 | 
						auto const [value, err] = m_bools.at(arg);
 | 
				
			||||||
	return !err ? *value : defaultValue;
 | 
						return !err ? *value : defaultValue;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
String ClArgs::getString(ox::CRStringView arg, ox::StringView defaultValue) const noexcept {
 | 
					String ClArgs::getString(ox::StringViewCR arg, ox::StringView defaultValue) const noexcept {
 | 
				
			||||||
	auto [value, err] = m_strings.at(arg);
 | 
						auto const [value, err] = m_strings.at(arg);
 | 
				
			||||||
	return !err ? ox::String(*value) : ox::String(defaultValue);
 | 
						return !err ? ox::String(*value) : ox::String(defaultValue);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ClArgs::getInt(ox::CRStringView arg, int defaultValue) const noexcept {
 | 
					int ClArgs::getInt(ox::StringViewCR arg, int defaultValue) const noexcept {
 | 
				
			||||||
	auto [value, err] = m_ints.at(arg);
 | 
						auto const [value, err] = m_ints.at(arg);
 | 
				
			||||||
	return !err ? *value : defaultValue;
 | 
						return !err ? *value : defaultValue;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<bool> ClArgs::getBool(ox::CRStringView arg) const noexcept {
 | 
					Result<bool> ClArgs::getBool(ox::StringViewCR arg) const noexcept {
 | 
				
			||||||
	oxRequire(out, m_bools.at(arg));
 | 
						OX_REQUIRE(out, m_bools.at(arg));
 | 
				
			||||||
	return *out;
 | 
						return *out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<String> ClArgs::getString(ox::CRStringView argName) const noexcept {
 | 
					Result<String> ClArgs::getString(ox::StringViewCR argName) const noexcept {
 | 
				
			||||||
	oxRequire(out, m_strings.at(argName));
 | 
						OX_REQUIRE(out, m_strings.at(argName));
 | 
				
			||||||
	return *out;
 | 
						return *out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<int> ClArgs::getInt(ox::CRStringView arg) const noexcept {
 | 
					Result<int> ClArgs::getInt(ox::StringViewCR arg) const noexcept {
 | 
				
			||||||
	oxRequire(out, m_ints.at(arg));
 | 
						OX_REQUIRE(out, m_ints.at(arg));
 | 
				
			||||||
	return *out;
 | 
						return *out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								deps/ox/src/ox/clargs/clargs.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								deps/ox/src/ox/clargs/clargs.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -9,6 +9,7 @@
 | 
				
			|||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <ox/std/hashmap.hpp>
 | 
					#include <ox/std/hashmap.hpp>
 | 
				
			||||||
 | 
					#include <ox/std/span.hpp>
 | 
				
			||||||
#include <ox/std/string.hpp>
 | 
					#include <ox/std/string.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ox {
 | 
					namespace ox {
 | 
				
			||||||
@@ -22,22 +23,24 @@ class ClArgs {
 | 
				
			|||||||
	public:
 | 
						public:
 | 
				
			||||||
		ClArgs(int argc, const char **args) noexcept;
 | 
							ClArgs(int argc, const char **args) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							ClArgs(ox::SpanView<const char*> args) noexcept;
 | 
				
			||||||
		bool getBool(ox::CRStringView arg, bool defaultValue) const noexcept;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		String getString(ox::CRStringView argName, ox::StringView defaultValue) const noexcept;
 | 
							bool getBool(ox::StringViewCR arg, bool defaultValue) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		int getInt(ox::CRStringView arg, int defaultValue) const noexcept;
 | 
							String getString(ox::StringViewCR argName, ox::StringView defaultValue) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		Result<bool> getBool(ox::CRStringView arg) const noexcept;
 | 
							int getInt(ox::StringViewCR arg, int defaultValue) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		Result<String> getString(ox::CRStringView argName) const noexcept;
 | 
							Result<bool> getBool(ox::StringViewCR arg) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<int> getInt(ox::CRStringView arg) const noexcept;
 | 
							[[nodiscard]]
 | 
				
			||||||
 | 
							Result<String> getString(ox::StringViewCR argName) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Result<int> getInt(ox::StringViewCR arg) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/claw/claw.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/claw/claw.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/claw/format.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/claw/format.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										34
									
								
								deps/ox/src/ox/claw/read.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								deps/ox/src/ox/claw/read.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -18,7 +18,7 @@ ox::Result<ox::StringView> readClawTypeId(ox::BufferView buff) noexcept {
 | 
				
			|||||||
	size_t outSz{};
 | 
						size_t outSz{};
 | 
				
			||||||
	const auto s1End = ox::strchr(buffRaw, ';', buffLen);
 | 
						const auto s1End = ox::strchr(buffRaw, ';', buffLen);
 | 
				
			||||||
	if (!s1End) {
 | 
						if (!s1End) {
 | 
				
			||||||
		return OxError(1, "Could not read Claw header");
 | 
							return ox::Error(1, "Could not read Claw header");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto const fmtSz = static_cast<std::size_t>(s1End - buffRaw) + 1;
 | 
						auto const fmtSz = static_cast<std::size_t>(s1End - buffRaw) + 1;
 | 
				
			||||||
	buffRaw += fmtSz;
 | 
						buffRaw += fmtSz;
 | 
				
			||||||
@@ -26,7 +26,7 @@ ox::Result<ox::StringView> readClawTypeId(ox::BufferView buff) noexcept {
 | 
				
			|||||||
	outSz += fmtSz;
 | 
						outSz += fmtSz;
 | 
				
			||||||
	auto const s2End = ox::strchr(buffRaw, ';', buffLen);
 | 
						auto const s2End = ox::strchr(buffRaw, ';', buffLen);
 | 
				
			||||||
	if (!s2End) {
 | 
						if (!s2End) {
 | 
				
			||||||
		return OxError(2, "Could not read Claw header");
 | 
							return ox::Error(2, "Could not read Claw header");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto const s2Size = static_cast<std::size_t>(s2End - buffRaw) + 1;
 | 
						auto const s2Size = static_cast<std::size_t>(s2End - buffRaw) + 1;
 | 
				
			||||||
	buffRaw += s2Size;
 | 
						buffRaw += s2Size;
 | 
				
			||||||
@@ -34,7 +34,7 @@ ox::Result<ox::StringView> readClawTypeId(ox::BufferView buff) noexcept {
 | 
				
			|||||||
	outSz += s2Size;
 | 
						outSz += s2Size;
 | 
				
			||||||
	auto const s3End = ox::strchr(buffRaw, ';', buffLen) + 1;
 | 
						auto const s3End = ox::strchr(buffRaw, ';', buffLen) + 1;
 | 
				
			||||||
	if (!s3End) {
 | 
						if (!s3End) {
 | 
				
			||||||
		return OxError(3, "Could not read Claw header");
 | 
							return ox::Error(3, "Could not read Claw header");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto const s3Size = static_cast<std::size_t>(s3End - buffRaw);
 | 
						auto const s3Size = static_cast<std::size_t>(s3End - buffRaw);
 | 
				
			||||||
	buffRaw += s3Size;
 | 
						buffRaw += s3Size;
 | 
				
			||||||
@@ -48,7 +48,7 @@ Result<ClawHeader> readClawHeader(ox::BufferView buff) noexcept {
 | 
				
			|||||||
	auto buffLen = buff.size();
 | 
						auto buffLen = buff.size();
 | 
				
			||||||
	const auto s1End = ox::strchr(buffRaw, ';', buffLen);
 | 
						const auto s1End = ox::strchr(buffRaw, ';', buffLen);
 | 
				
			||||||
	if (!s1End) {
 | 
						if (!s1End) {
 | 
				
			||||||
		return OxError(1, "Could not read Claw header");
 | 
							return ox::Error(1, "Could not read Claw header");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto const s1Size = static_cast<std::size_t>(s1End - buffRaw);
 | 
						auto const s1Size = static_cast<std::size_t>(s1End - buffRaw);
 | 
				
			||||||
	StringView const fmt(buffRaw, s1Size);
 | 
						StringView const fmt(buffRaw, s1Size);
 | 
				
			||||||
@@ -57,7 +57,7 @@ Result<ClawHeader> readClawHeader(ox::BufferView buff) noexcept {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	auto const s2End = ox::strchr(buffRaw, ';', buffLen);
 | 
						auto const s2End = ox::strchr(buffRaw, ';', buffLen);
 | 
				
			||||||
	if (!s2End) {
 | 
						if (!s2End) {
 | 
				
			||||||
		return OxError(2, "Could not read Claw header");
 | 
							return ox::Error(2, "Could not read Claw header");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto const s2Size = static_cast<std::size_t>(s2End - buffRaw);
 | 
						auto const s2Size = static_cast<std::size_t>(s2End - buffRaw);
 | 
				
			||||||
	StringView const typeName(buffRaw, s2Size);
 | 
						StringView const typeName(buffRaw, s2Size);
 | 
				
			||||||
@@ -66,7 +66,7 @@ Result<ClawHeader> readClawHeader(ox::BufferView buff) noexcept {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	auto const s3End = ox::strchr(buffRaw, ';', buffLen);
 | 
						auto const s3End = ox::strchr(buffRaw, ';', buffLen);
 | 
				
			||||||
	if (!s3End) {
 | 
						if (!s3End) {
 | 
				
			||||||
		return OxError(3, "Could not read Claw header");
 | 
							return ox::Error(3, "Could not read Claw header");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto const s3Size = static_cast<std::size_t>(s3End - buffRaw);
 | 
						auto const s3Size = static_cast<std::size_t>(s3End - buffRaw);
 | 
				
			||||||
	StringView const versionStr(buffRaw, s3Size);
 | 
						StringView const versionStr(buffRaw, s3Size);
 | 
				
			||||||
@@ -78,36 +78,36 @@ Result<ClawHeader> readClawHeader(ox::BufferView buff) noexcept {
 | 
				
			|||||||
	} else if (fmt == "O1") {
 | 
						} else if (fmt == "O1") {
 | 
				
			||||||
		hdr.fmt = ClawFormat::Organic;
 | 
							hdr.fmt = ClawFormat::Organic;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return OxError(4, "Claw format does not match any supported format/version combo");
 | 
							return ox::Error(4, "Claw format does not match any supported format/version combo");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	hdr.typeName = typeName;
 | 
						hdr.typeName = typeName;
 | 
				
			||||||
	std::ignore = ox::atoi(versionStr).copyTo(hdr.typeVersion);
 | 
						std::ignore = ox::strToInt(versionStr).copyTo(hdr.typeVersion);
 | 
				
			||||||
	hdr.data = buffRaw;
 | 
						hdr.data = buffRaw;
 | 
				
			||||||
	hdr.dataSize = buffLen;
 | 
						hdr.dataSize = buffLen;
 | 
				
			||||||
	return hdr;
 | 
						return hdr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<BufferView> stripClawHeader(ox::BufferView buff) noexcept {
 | 
					Result<BufferView> stripClawHeader(ox::BufferView buff) noexcept {
 | 
				
			||||||
	oxRequire(header, readClawHeader(buff));
 | 
						OX_REQUIRE(header, readClawHeader(buff));
 | 
				
			||||||
	return {{header.data, header.dataSize}};
 | 
						return {{header.data, header.dataSize}};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<ModelObject> readClaw(TypeStore &ts, BufferView buff) noexcept {
 | 
					Result<ModelObject> readClaw(TypeStore &ts, BufferView buff) noexcept {
 | 
				
			||||||
	oxRequire(header, readClawHeader(buff));
 | 
						OX_REQUIRE(header, readClawHeader(buff));
 | 
				
			||||||
	auto const [t, tdErr] = ts.getLoad(
 | 
						auto const [t, tdErr] = ts.getLoad(
 | 
				
			||||||
			header.typeName, header.typeVersion, header.typeParams);
 | 
								header.typeName, header.typeVersion, header.typeParams);
 | 
				
			||||||
	if (tdErr) {
 | 
						if (tdErr) {
 | 
				
			||||||
		return OxError(3, "Could not load type descriptor");
 | 
							return ox::Error(3, "Could not load type descriptor");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ModelObject obj;
 | 
						ModelObject obj;
 | 
				
			||||||
	oxReturnError(obj.setType(t));
 | 
						OX_RETURN_ERROR(obj.setType(t));
 | 
				
			||||||
	switch (header.fmt) {
 | 
						switch (header.fmt) {
 | 
				
			||||||
		case ClawFormat::Metal:
 | 
							case ClawFormat::Metal:
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			ox::BufferReader br({header.data, header.dataSize});
 | 
								ox::BufferReader br({header.data, header.dataSize});
 | 
				
			||||||
			MetalClawReader reader(br);
 | 
								MetalClawReader reader(br);
 | 
				
			||||||
			ModelHandlerInterface handler(&reader);
 | 
								ModelHandlerInterface handler(&reader);
 | 
				
			||||||
			oxReturnError(model(&handler, &obj));
 | 
								OX_RETURN_ERROR(model(&handler, &obj));
 | 
				
			||||||
			return obj;
 | 
								return obj;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		case ClawFormat::Organic:
 | 
							case ClawFormat::Organic:
 | 
				
			||||||
@@ -115,16 +115,16 @@ Result<ModelObject> readClaw(TypeStore &ts, BufferView buff) noexcept {
 | 
				
			|||||||
#ifdef OX_USE_STDLIB
 | 
					#ifdef OX_USE_STDLIB
 | 
				
			||||||
			OrganicClawReader reader({header.data, header.dataSize});
 | 
								OrganicClawReader reader({header.data, header.dataSize});
 | 
				
			||||||
			ModelHandlerInterface handler(&reader);
 | 
								ModelHandlerInterface handler(&reader);
 | 
				
			||||||
			oxReturnError(model(&handler, &obj));
 | 
								OX_RETURN_ERROR(model(&handler, &obj));
 | 
				
			||||||
			return obj;
 | 
								return obj;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		case ClawFormat::None:
 | 
							case ClawFormat::None:
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1);
 | 
						return ox::Error(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								deps/ox/src/ox/claw/read.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								deps/ox/src/ox/claw/read.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -40,12 +40,12 @@ Result<BufferView> stripClawHeader(ox::BufferView buff) noexcept;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
Error readClaw(ox::BufferView buff, T &val) {
 | 
					Error readClaw(ox::BufferView buff, T &val) {
 | 
				
			||||||
	oxRequire(header, readClawHeader(buff));
 | 
						OX_REQUIRE(header, readClawHeader(buff));
 | 
				
			||||||
	if (header.typeName != getModelTypeName<T>()) {
 | 
						if (header.typeName != getModelTypeName<T>()) {
 | 
				
			||||||
		return OxError(Error_ClawTypeMismatch, "Claw Read: Type mismatch");
 | 
							return ox::Error(Error_ClawTypeMismatch, "Claw Read: Type mismatch");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (header.typeVersion != getModelTypeVersion<T>()) {
 | 
						if (header.typeVersion != getModelTypeVersion<T>()) {
 | 
				
			||||||
		return OxError(Error_ClawTypeVersionMismatch, "Claw Read: Type Version mismatch");
 | 
							return ox::Error(Error_ClawTypeVersionMismatch, "Claw Read: Type Version mismatch");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	switch (header.fmt) {
 | 
						switch (header.fmt) {
 | 
				
			||||||
		case ClawFormat::Metal:
 | 
							case ClawFormat::Metal:
 | 
				
			||||||
@@ -65,15 +65,15 @@ Error readClaw(ox::BufferView buff, T &val) {
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		case ClawFormat::None:
 | 
							case ClawFormat::None:
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1);
 | 
						return ox::Error(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
Result<T> readClaw(ox::BufferView buff) {
 | 
					Result<T> readClaw(ox::BufferView buff) {
 | 
				
			||||||
	Result<T> val;
 | 
						Result<T> val;
 | 
				
			||||||
	oxReturnError(readClaw(buff, val.value));
 | 
						OX_RETURN_ERROR(readClaw(buff, val.value));
 | 
				
			||||||
	return val;
 | 
						return val;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/claw/readclaw.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/claw/readclaw.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										72
									
								
								deps/ox/src/ox/claw/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										72
									
								
								deps/ox/src/ox/claw/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -62,45 +62,45 @@ struct TestStruct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) {
 | 
					constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) {
 | 
				
			||||||
	oxReturnError(io->template setTypeInfo<TestUnion>());
 | 
						OX_RETURN_ERROR(io->template setTypeInfo<TestUnion>());
 | 
				
			||||||
	oxReturnError(io->field("Bool", &obj->Bool));
 | 
						OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
 | 
				
			||||||
	oxReturnError(io->field("Int", &obj->Int));
 | 
						OX_RETURN_ERROR(io->field("Int", &obj->Int));
 | 
				
			||||||
	oxReturnError(io->fieldCString("String", &obj->String));
 | 
						OX_RETURN_ERROR(io->fieldCString("String", &obj->String));
 | 
				
			||||||
	return OxError(0);
 | 
						return ox::Error(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStructNest> auto *obj) {
 | 
					constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStructNest> auto *obj) {
 | 
				
			||||||
	oxReturnError(io->template setTypeInfo<TestStructNest>());
 | 
						OX_RETURN_ERROR(io->template setTypeInfo<TestStructNest>());
 | 
				
			||||||
	oxReturnError(io->field("Bool", &obj->Bool));
 | 
						OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
 | 
				
			||||||
	oxReturnError(io->field("Int", &obj->Int));
 | 
						OX_RETURN_ERROR(io->field("Int", &obj->Int));
 | 
				
			||||||
	oxReturnError(io->field("String", &obj->String));
 | 
						OX_RETURN_ERROR(io->field("String", &obj->String));
 | 
				
			||||||
	return OxError(0);
 | 
						return ox::Error(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) {
 | 
					constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) {
 | 
				
			||||||
	oxReturnError(io->template setTypeInfo<TestStruct>());
 | 
						OX_RETURN_ERROR(io->template setTypeInfo<TestStruct>());
 | 
				
			||||||
	oxReturnError(io->field("Bool", &obj->Bool));
 | 
						OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
 | 
				
			||||||
	oxReturnError(io->field("Int", &obj->Int));
 | 
						OX_RETURN_ERROR(io->field("Int", &obj->Int));
 | 
				
			||||||
	oxReturnError(io->field("Int1", &obj->Int1));
 | 
						OX_RETURN_ERROR(io->field("Int1", &obj->Int1));
 | 
				
			||||||
	oxReturnError(io->field("Int2", &obj->Int2));
 | 
						OX_RETURN_ERROR(io->field("Int2", &obj->Int2));
 | 
				
			||||||
	oxReturnError(io->field("Int3", &obj->Int3));
 | 
						OX_RETURN_ERROR(io->field("Int3", &obj->Int3));
 | 
				
			||||||
	oxReturnError(io->field("Int4", &obj->Int4));
 | 
						OX_RETURN_ERROR(io->field("Int4", &obj->Int4));
 | 
				
			||||||
	oxReturnError(io->field("Int5", &obj->Int5));
 | 
						OX_RETURN_ERROR(io->field("Int5", &obj->Int5));
 | 
				
			||||||
	oxReturnError(io->field("Int6", &obj->Int6));
 | 
						OX_RETURN_ERROR(io->field("Int6", &obj->Int6));
 | 
				
			||||||
	oxReturnError(io->field("Int7", &obj->Int7));
 | 
						OX_RETURN_ERROR(io->field("Int7", &obj->Int7));
 | 
				
			||||||
	oxReturnError(io->field("Int8", &obj->Int8));
 | 
						OX_RETURN_ERROR(io->field("Int8", &obj->Int8));
 | 
				
			||||||
	int unionIdx = 0;
 | 
						int unionIdx = 0;
 | 
				
			||||||
	if constexpr(T::opType() != ox::OpType::Reflect) {
 | 
						if constexpr(T::opType() != ox::OpType::Reflect) {
 | 
				
			||||||
		unionIdx = obj->unionIdx;
 | 
							unionIdx = obj->unionIdx;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(io->field("Union", ox::UnionView{&obj->Union, unionIdx}));
 | 
						OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, unionIdx}));
 | 
				
			||||||
	oxReturnError(io->field("String", &obj->String));
 | 
						OX_RETURN_ERROR(io->field("String", &obj->String));
 | 
				
			||||||
	oxReturnError(io->field("List", obj->List, 4));
 | 
						OX_RETURN_ERROR(io->field("List", obj->List, 4));
 | 
				
			||||||
	oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
 | 
						OX_RETURN_ERROR(io->field("EmptyStruct", &obj->EmptyStruct));
 | 
				
			||||||
	oxReturnError(io->field("Struct", &obj->Struct));
 | 
						OX_RETURN_ERROR(io->field("Struct", &obj->Struct));
 | 
				
			||||||
	return OxError(0);
 | 
						return ox::Error(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
					static std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			||||||
@@ -109,24 +109,24 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
			"ClawHeaderReader",
 | 
								"ClawHeaderReader",
 | 
				
			||||||
			[] {
 | 
								[] {
 | 
				
			||||||
				constexpr auto hdr = ox::StringLiteral("O1;com.drinkingtea.ox.claw.test.Header;2;");
 | 
									constexpr auto hdr = ox::StringLiteral("O1;com.drinkingtea.ox.claw.test.Header;2;");
 | 
				
			||||||
				auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.len() + 1});
 | 
									auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.size() + 1});
 | 
				
			||||||
				oxAssert(err, "Error parsing header");
 | 
									oxAssert(err, "Error parsing header");
 | 
				
			||||||
				oxAssert(ch.fmt == ox::ClawFormat::Organic, "Format wrong");
 | 
									oxAssert(ch.fmt == ox::ClawFormat::Organic, "Format wrong");
 | 
				
			||||||
				oxAssert(ch.typeName == "com.drinkingtea.ox.claw.test.Header", "Type name wrong");
 | 
									oxAssert(ch.typeName == "com.drinkingtea.ox.claw.test.Header", "Type name wrong");
 | 
				
			||||||
				oxAssert(ch.typeVersion == 2, "Type version wrong");
 | 
									oxAssert(ch.typeVersion == 2, "Type version wrong");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ClawHeaderReader2",
 | 
								"ClawHeaderReader2",
 | 
				
			||||||
			[] {
 | 
								[] {
 | 
				
			||||||
				constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;");
 | 
									constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;");
 | 
				
			||||||
				auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.len() + 1});
 | 
									auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.size() + 1});
 | 
				
			||||||
				oxAssert(err, "Error parsing header");
 | 
									oxAssert(err, "Error parsing header");
 | 
				
			||||||
				oxAssert(ch.fmt == ox::ClawFormat::Metal, "Format wrong");
 | 
									oxAssert(ch.fmt == ox::ClawFormat::Metal, "Format wrong");
 | 
				
			||||||
				oxAssert(ch.typeName == "com.drinkingtea.ox.claw.test.Header2", "Type name wrong");
 | 
									oxAssert(ch.typeName == "com.drinkingtea.ox.claw.test.Header2", "Type name wrong");
 | 
				
			||||||
				oxAssert(ch.typeVersion == 3, "Type version wrong");
 | 
									oxAssert(ch.typeVersion == 3, "Type version wrong");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -134,7 +134,7 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
			[] {
 | 
								[] {
 | 
				
			||||||
				constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;awefawf");
 | 
									constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;awefawf");
 | 
				
			||||||
				constexpr auto expected = ox::StringLiteral("com.drinkingtea.ox.claw.test.Header2;3");
 | 
									constexpr auto expected = ox::StringLiteral("com.drinkingtea.ox.claw.test.Header2;3");
 | 
				
			||||||
				oxRequire(actual, ox::readClawTypeId({hdr.data(), hdr.len() + 1}));
 | 
									OX_REQUIRE(actual, ox::readClawTypeId({hdr.data(), hdr.size() + 1}));
 | 
				
			||||||
				oxExpect(actual, expected);
 | 
									oxExpect(actual, expected);
 | 
				
			||||||
				return ox::Error{};
 | 
									return ox::Error{};
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -145,8 +145,8 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				// This test doesn't confirm much, but it does show that the writer
 | 
									// This test doesn't confirm much, but it does show that the writer
 | 
				
			||||||
				// doesn't segfault
 | 
									// doesn't segfault
 | 
				
			||||||
				TestStruct ts;
 | 
									TestStruct ts;
 | 
				
			||||||
				oxReturnError(ox::writeClaw(ts, ox::ClawFormat::Metal));
 | 
									OX_RETURN_ERROR(ox::writeClaw(ts, ox::ClawFormat::Metal));
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -191,7 +191,7 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				oxAssert(testIn.Struct.String      == testOut.Struct.String, "Struct.String value mismatch");
 | 
									oxAssert(testIn.Struct.String      == testOut.Struct.String, "Struct.String value mismatch");
 | 
				
			||||||
				oxAssert(testIn.Struct.Bool        == testOut.Struct.Bool, "Struct.Bool value mismatch");
 | 
									oxAssert(testIn.Struct.Bool        == testOut.Struct.Bool, "Struct.Bool value mismatch");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/claw/write.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/claw/write.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								deps/ox/src/ox/claw/write.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								deps/ox/src/ox/claw/write.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -39,7 +39,7 @@ struct TypeInfoCatcher {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constexpr Error field(...) noexcept {
 | 
						constexpr Error field(...) noexcept {
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static constexpr auto opType() {
 | 
						static constexpr auto opType() {
 | 
				
			||||||
@@ -76,21 +76,21 @@ template<typename T>
 | 
				
			|||||||
ox::Error writeClawHeader(Writer_c auto &writer, const T *t, ClawFormat fmt) noexcept {
 | 
					ox::Error writeClawHeader(Writer_c auto &writer, const T *t, ClawFormat fmt) noexcept {
 | 
				
			||||||
	switch (fmt) {
 | 
						switch (fmt) {
 | 
				
			||||||
		case ClawFormat::Metal:
 | 
							case ClawFormat::Metal:
 | 
				
			||||||
			oxReturnError(write(writer, "M2;"));
 | 
								OX_RETURN_ERROR(write(writer, "M2;"));
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case ClawFormat::Organic:
 | 
							case ClawFormat::Organic:
 | 
				
			||||||
			oxReturnError(write(writer, "O1;"));
 | 
								OX_RETURN_ERROR(write(writer, "O1;"));
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(write(writer, detail::getTypeName(t)));
 | 
						OX_RETURN_ERROR(write(writer, detail::getTypeName(t)));
 | 
				
			||||||
	oxReturnError(writer.put(';'));
 | 
						OX_RETURN_ERROR(writer.put(';'));
 | 
				
			||||||
	const auto tn = detail::getTypeVersion(t);
 | 
						const auto tn = detail::getTypeVersion(t);
 | 
				
			||||||
	if (tn > -1) {
 | 
						if (tn > -1) {
 | 
				
			||||||
		oxReturnError(ox::writeItoa(tn, writer));
 | 
							OX_RETURN_ERROR(ox::writeItoa(tn, writer));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(writer.put(';'));
 | 
						OX_RETURN_ERROR(writer.put(';'));
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -102,19 +102,19 @@ Result<Buffer> writeClaw(
 | 
				
			|||||||
		std::size_t buffReserveSz = 2 * units::KB) noexcept {
 | 
							std::size_t buffReserveSz = 2 * units::KB) noexcept {
 | 
				
			||||||
	Buffer out(buffReserveSz);
 | 
						Buffer out(buffReserveSz);
 | 
				
			||||||
	BufferWriter bw(&out, 0);
 | 
						BufferWriter bw(&out, 0);
 | 
				
			||||||
	oxReturnError(detail::writeClawHeader(bw, &t, fmt));
 | 
						OX_RETURN_ERROR(detail::writeClawHeader(bw, &t, fmt));
 | 
				
			||||||
#ifdef OX_USE_STDLIB
 | 
					#ifdef OX_USE_STDLIB
 | 
				
			||||||
	if (fmt == ClawFormat::Metal) {
 | 
						if (fmt == ClawFormat::Metal) {
 | 
				
			||||||
		oxReturnError(writeMC(bw, t));
 | 
							OX_RETURN_ERROR(writeMC(bw, t));
 | 
				
			||||||
	} else if (fmt == ClawFormat::Organic) {
 | 
						} else if (fmt == ClawFormat::Organic) {
 | 
				
			||||||
		oxRequire(data, writeOC(t));
 | 
							OX_REQUIRE(data, writeOC(t));
 | 
				
			||||||
		oxReturnError(bw.write(data.data(), data.size()));
 | 
							OX_RETURN_ERROR(bw.write(data.data(), data.size()));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	if (fmt != ClawFormat::Metal) {
 | 
						if (fmt != ClawFormat::Metal) {
 | 
				
			||||||
		return OxError(1, "OC is not supported in this build");
 | 
							return ox::Error(1, "OC is not supported in this build");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(writeMC(bw, t));
 | 
						OX_RETURN_ERROR(writeMC(bw, t));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	out.resize(bw.tellp());
 | 
						out.resize(bw.tellp());
 | 
				
			||||||
	return out;
 | 
						return out;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/event/event.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/event/event.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/event/signal.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/event/signal.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										34
									
								
								deps/ox/src/ox/event/signal.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								deps/ox/src/ox/event/signal.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -57,7 +57,7 @@ class Signal {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			void call(Args... args) final {
 | 
								void call(Args... args) final {
 | 
				
			||||||
				if constexpr(detail::isError<decltype(f(args...))>::value) {
 | 
									if constexpr(detail::isError<decltype(f(args...))>::value) {
 | 
				
			||||||
					oxThrowError(f(args...));
 | 
										OX_THROW_ERROR(f(args...));
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					f(args...);
 | 
										f(args...);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -76,7 +76,7 @@ class Signal {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			void call(Args... args) final {
 | 
								void call(Args... args) final {
 | 
				
			||||||
				if constexpr(detail::isError<decltype((m_receiver->*(m_methodPtr))(args...))>::value) {
 | 
									if constexpr(detail::isError<decltype((m_receiver->*(m_methodPtr))(args...))>::value) {
 | 
				
			||||||
					oxThrowError((m_receiver->*(m_methodPtr))(args...));
 | 
										OX_THROW_ERROR((m_receiver->*(m_methodPtr))(args...));
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					f(args...);
 | 
										f(args...);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -107,7 +107,7 @@ class Signal {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			void call(Args... args) final {
 | 
								void call(Args... args) final {
 | 
				
			||||||
				if constexpr(detail::isError<decltype((m_receiver->*(m_methodPtr))(args...))>::value) {
 | 
									if constexpr(detail::isError<decltype((m_receiver->*(m_methodPtr))(args...))>::value) {
 | 
				
			||||||
					oxThrowError((m_receiver->*(m_methodPtr))(args...));
 | 
										OX_THROW_ERROR((m_receiver->*(m_methodPtr))(args...));
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					(m_receiver->*(m_methodPtr))(args...);
 | 
										(m_receiver->*(m_methodPtr))(args...);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -143,6 +143,11 @@ class Signal {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		Error disconnectObject(const void *receiver) const noexcept;
 | 
							Error disconnectObject(const void *receiver) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[[nodiscard]]
 | 
				
			||||||
 | 
							size_t connectionCnt() const noexcept {
 | 
				
			||||||
 | 
								return m_slots.size();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void emit(Args... args) const;
 | 
							void emit(Args... args) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error emitCheckError(Args... args) const noexcept;
 | 
							Error emitCheckError(Args... args) const noexcept;
 | 
				
			||||||
@@ -193,11 +198,11 @@ Error Signal<Args...>::disconnectObject(const void *receiver) const noexcept {
 | 
				
			|||||||
	for (auto i = 0u; i < m_slots.size(); ++i) {
 | 
						for (auto i = 0u; i < m_slots.size(); ++i) {
 | 
				
			||||||
		const auto &slot = m_slots[i];
 | 
							const auto &slot = m_slots[i];
 | 
				
			||||||
		if (slot->receiver() == receiver) {
 | 
							if (slot->receiver() == receiver) {
 | 
				
			||||||
			oxReturnError(m_slots.erase(i));
 | 
								OX_RETURN_ERROR(m_slots.erase(i));
 | 
				
			||||||
			--i;
 | 
								--i;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1, "Signal::disconnectObject: Receiver was not found among this Signal's slots");
 | 
						return ox::Error(1, "Signal::disconnectObject: Receiver was not found among this Signal's slots");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class... Args>
 | 
					template<class... Args>
 | 
				
			||||||
@@ -213,9 +218,9 @@ Error Signal<Args...>::emitCheckError(Args... args) const noexcept {
 | 
				
			|||||||
		for (auto &f : m_slots) {
 | 
							for (auto &f : m_slots) {
 | 
				
			||||||
			f->call(args...);
 | 
								f->call(args...);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	} catch (const ox::Exception &ex) {
 | 
						} catch (const ox::Exception &ex) {
 | 
				
			||||||
		return ox::Error(ex.file, ex.line, ex.errCode, ex.msg);
 | 
							return ox::Error(ex.errCode, ex.msg, ex.src);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -319,6 +324,11 @@ class Signal<Error(Args...)> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		Error disconnectObject(const void *receiver) const noexcept;
 | 
							Error disconnectObject(const void *receiver) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[[nodiscard]]
 | 
				
			||||||
 | 
							size_t connectionCnt() const noexcept {
 | 
				
			||||||
 | 
								return m_slots.size();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void emit(Args... args) const noexcept;
 | 
							void emit(Args... args) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error emitCheckError(Args... args) const noexcept;
 | 
							Error emitCheckError(Args... args) const noexcept;
 | 
				
			||||||
@@ -381,11 +391,11 @@ Error Signal<Error(Args...)>::disconnectObject(const void *receiver) const noexc
 | 
				
			|||||||
	for (auto i = 0u; i < m_slots.size(); ++i) {
 | 
						for (auto i = 0u; i < m_slots.size(); ++i) {
 | 
				
			||||||
		const auto &slot = m_slots[i];
 | 
							const auto &slot = m_slots[i];
 | 
				
			||||||
		if (slot->receiver() == receiver) {
 | 
							if (slot->receiver() == receiver) {
 | 
				
			||||||
			oxReturnError(m_slots.erase(i));
 | 
								OX_RETURN_ERROR(m_slots.erase(i));
 | 
				
			||||||
			--i;
 | 
								--i;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1, "Signal::disconnectObject: Receiver was not found among this Signal's slots");
 | 
						return ox::Error(1, "Signal::disconnectObject: Receiver was not found among this Signal's slots");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class... Args>
 | 
					template<class... Args>
 | 
				
			||||||
@@ -398,9 +408,9 @@ void Signal<Error(Args...)>::emit(Args... args) const noexcept {
 | 
				
			|||||||
template<class... Args>
 | 
					template<class... Args>
 | 
				
			||||||
Error Signal<Error(Args...)>::emitCheckError(Args... args) const noexcept {
 | 
					Error Signal<Error(Args...)>::emitCheckError(Args... args) const noexcept {
 | 
				
			||||||
	for (auto &f : m_slots) {
 | 
						for (auto &f : m_slots) {
 | 
				
			||||||
		oxReturnError(f->call(ox::forward<Args>(args)...));
 | 
							OX_RETURN_ERROR(f->call(ox::forward<Args>(args)...));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								deps/ox/src/ox/event/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								deps/ox/src/ox/event/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -17,7 +17,7 @@ struct TestStruct: public ox::SignalHandler {
 | 
				
			|||||||
	int value = 0;
 | 
						int value = 0;
 | 
				
			||||||
	ox::Error method(int i) noexcept {
 | 
						ox::Error method(int i) noexcept {
 | 
				
			||||||
		value = i;
 | 
							value = i;
 | 
				
			||||||
		return OxError(0);
 | 
							return ox::Error(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,13 +27,13 @@ std::map<ox::StringView, std::function<ox::Error()>> tests = {
 | 
				
			|||||||
		[] {
 | 
							[] {
 | 
				
			||||||
			ox::Signal<ox::Error(int)> signal;
 | 
								ox::Signal<ox::Error(int)> signal;
 | 
				
			||||||
			signal.connect([](int i) -> ox::Error {
 | 
								signal.connect([](int i) -> ox::Error {
 | 
				
			||||||
				return OxError(i != 5);
 | 
									return ox::Error(i != 5);
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
			TestStruct ts;
 | 
								TestStruct ts;
 | 
				
			||||||
			signal.connect(&ts, &TestStruct::method);
 | 
								signal.connect(&ts, &TestStruct::method);
 | 
				
			||||||
			oxReturnError(signal.emitCheckError(5));
 | 
								OX_RETURN_ERROR(signal.emitCheckError(5));
 | 
				
			||||||
			oxReturnError(OxError(ts.value != 5));
 | 
								OX_RETURN_ERROR(ox::Error(ts.value != 5));
 | 
				
			||||||
			return OxError(0);
 | 
								return ox::Error(0);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								deps/ox/src/ox/fs/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								deps/ox/src/ox/fs/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,7 @@
 | 
				
			|||||||
 | 
					if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
 | 
				
			||||||
 | 
						# enable warnings
 | 
				
			||||||
 | 
						set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-buffer-usage")
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_library(
 | 
					add_library(
 | 
				
			||||||
	OxFS
 | 
						OxFS
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										112
									
								
								deps/ox/src/ox/fs/filestore/filestoretemplate.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										112
									
								
								deps/ox/src/ox/fs/filestore/filestoretemplate.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -10,6 +10,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <ox/fs/ptrarith/nodebuffer.hpp>
 | 
					#include <ox/fs/ptrarith/nodebuffer.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ox {
 | 
					namespace ox {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using InodeId_t = uint64_t;
 | 
					using InodeId_t = uint64_t;
 | 
				
			||||||
@@ -205,12 +207,12 @@ Error FileStoreTemplate<size_t>::format(void *buffer, std::size_t bufferSize) {
 | 
				
			|||||||
	auto fsData = nb->malloc(sizeof(FileStoreData)).value;
 | 
						auto fsData = nb->malloc(sizeof(FileStoreData)).value;
 | 
				
			||||||
	if (!fsData.valid()) {
 | 
						if (!fsData.valid()) {
 | 
				
			||||||
		oxTrace("ox.fs.FileStoreTemplate.format.fail", "Could not read data section of FileStoreData");
 | 
							oxTrace("ox.fs.FileStoreTemplate.format.fail", "Could not read data section of FileStoreData");
 | 
				
			||||||
		return OxError(1, "Could not read data section of FileStoreData");
 | 
							return ox::Error(1, "Could not read data section of FileStoreData");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto data = nb->template dataOf<FileStoreData>(fsData);
 | 
						auto data = nb->template dataOf<FileStoreData>(fsData);
 | 
				
			||||||
	if (!data.valid()) {
 | 
						if (!data.valid()) {
 | 
				
			||||||
		oxTrace("ox.fs.FileStoreTemplate.format.fail", "Could not read data section of FileStoreData");
 | 
							oxTrace("ox.fs.FileStoreTemplate.format.fail", "Could not read data section of FileStoreData");
 | 
				
			||||||
		return OxError(1, "Could not read data section of FileStoreData");
 | 
							return ox::Error(1, "Could not read data section of FileStoreData");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	new (data) FileStoreData;
 | 
						new (data) FileStoreData;
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
@@ -221,24 +223,24 @@ Error FileStoreTemplate<size_t>::setSize(std::size_t size) {
 | 
				
			|||||||
	if (m_buffSize >= size) {
 | 
						if (m_buffSize >= size) {
 | 
				
			||||||
		return m_buffer->setSize(static_cast<size_t>(size));
 | 
							return m_buffer->setSize(static_cast<size_t>(size));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1);
 | 
						return ox::Error(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t>
 | 
					template<typename size_t>
 | 
				
			||||||
Error FileStoreTemplate<size_t>::incLinks(uint64_t id) {
 | 
					Error FileStoreTemplate<size_t>::incLinks(uint64_t id) {
 | 
				
			||||||
	oxRequireM(item, find(static_cast<size_t>(id)).validate());
 | 
						OX_REQUIRE_M(item, find(static_cast<size_t>(id)).validate());
 | 
				
			||||||
	++item->links;
 | 
						++item->links;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t>
 | 
					template<typename size_t>
 | 
				
			||||||
Error FileStoreTemplate<size_t>::decLinks(uint64_t id) {
 | 
					Error FileStoreTemplate<size_t>::decLinks(uint64_t id) {
 | 
				
			||||||
	oxRequireM(item, find(static_cast<size_t>(id)).validate());
 | 
						OX_REQUIRE_M(item, find(static_cast<size_t>(id)).validate());
 | 
				
			||||||
	--item->links;
 | 
						--item->links;
 | 
				
			||||||
	if (item->links == 0) {
 | 
						if (item->links == 0) {
 | 
				
			||||||
		oxReturnError(remove(item));
 | 
							OX_RETURN_ERROR(remove(item));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t>
 | 
					template<typename size_t>
 | 
				
			||||||
@@ -247,7 +249,7 @@ Error FileStoreTemplate<size_t>::write(uint64_t id64, const void *data, FsSize_t
 | 
				
			|||||||
	oxTracef("ox.fs.FileStoreTemplate.write", "Attempting to write to inode {}", id);
 | 
						oxTracef("ox.fs.FileStoreTemplate.write", "Attempting to write to inode {}", id);
 | 
				
			||||||
	auto existing = find(id);
 | 
						auto existing = find(id);
 | 
				
			||||||
	if (!canWrite(existing, dataSize)) {
 | 
						if (!canWrite(existing, dataSize)) {
 | 
				
			||||||
		oxReturnError(compact());
 | 
							OX_RETURN_ERROR(compact());
 | 
				
			||||||
		existing = find(id);
 | 
							existing = find(id);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -267,7 +269,7 @@ Error FileStoreTemplate<size_t>::write(uint64_t id64, const void *data, FsSize_t
 | 
				
			|||||||
		// if first malloc failed, compact and try again
 | 
							// if first malloc failed, compact and try again
 | 
				
			||||||
		if (!dest.valid()) {
 | 
							if (!dest.valid()) {
 | 
				
			||||||
			oxTrace("ox.fs.FileStoreTemplate.write", "Allocation failed, compacting");
 | 
								oxTrace("ox.fs.FileStoreTemplate.write", "Allocation failed, compacting");
 | 
				
			||||||
			oxReturnError(compact());
 | 
								OX_RETURN_ERROR(compact());
 | 
				
			||||||
			dest = m_buffer->malloc(dataSize).value;
 | 
								dest = m_buffer->malloc(dataSize).value;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (dest.valid()) {
 | 
							if (dest.valid()) {
 | 
				
			||||||
@@ -296,16 +298,16 @@ Error FileStoreTemplate<size_t>::write(uint64_t id64, const void *data, FsSize_t
 | 
				
			|||||||
						        dest->id.get(), dest.offset(), destData.size());
 | 
											        dest->id.get(), dest.offset(), destData.size());
 | 
				
			||||||
						fsData->rootNode = dest.offset();
 | 
											fsData->rootNode = dest.offset();
 | 
				
			||||||
						oxTracef("ox.fs.FileStoreTemplate.write", "Root inode: {}", dest->id.get());
 | 
											oxTracef("ox.fs.FileStoreTemplate.write", "Root inode: {}", dest->id.get());
 | 
				
			||||||
						return OxError(0);
 | 
											return {};
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					oxTrace("ox.fs.FileStoreTemplate.write.fail", "Could not place item due to absence of FileStore header.");
 | 
										oxTrace("ox.fs.FileStoreTemplate.write.fail", "Could not place item due to absence of FileStore header.");
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		oxReturnError(m_buffer->free(dest));
 | 
							OX_RETURN_ERROR(m_buffer->free(dest));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1);
 | 
						return ox::Error(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t>
 | 
					template<typename size_t>
 | 
				
			||||||
@@ -320,7 +322,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, void *out, FsSize_t outSize,
 | 
				
			|||||||
	// error check
 | 
						// error check
 | 
				
			||||||
	if (!src.valid()) {
 | 
						if (!src.valid()) {
 | 
				
			||||||
		oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not find requested item: {}", id);
 | 
							oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not find requested item: {}", id);
 | 
				
			||||||
		return OxError(1, "Could not find requested item");
 | 
							return ox::Error(1, "Could not find requested item");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto srcData = m_buffer->template dataOf<uint8_t>(src);
 | 
						auto srcData = m_buffer->template dataOf<uint8_t>(src);
 | 
				
			||||||
@@ -333,7 +335,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, void *out, FsSize_t outSize,
 | 
				
			|||||||
		oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not read data section of item: {}", id);
 | 
							oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not read data section of item: {}", id);
 | 
				
			||||||
		oxTracef("ox.fs.FileStoreTemplate.read.fail",
 | 
							oxTracef("ox.fs.FileStoreTemplate.read.fail",
 | 
				
			||||||
		         "Item data section size: {}, Expected size: {}", srcData.size(), outSize);
 | 
							         "Item data section size: {}, Expected size: {}", srcData.size(), outSize);
 | 
				
			||||||
		return OxError(1, "Invalid inode");
 | 
							return ox::Error(1, "Invalid inode");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ox::memcpy(out, srcData, srcData.size());
 | 
						ox::memcpy(out, srcData, srcData.size());
 | 
				
			||||||
@@ -351,7 +353,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, FsSize_t readStart, FsSize_t
 | 
				
			|||||||
	// error check
 | 
						// error check
 | 
				
			||||||
	if (!src.valid()) {
 | 
						if (!src.valid()) {
 | 
				
			||||||
		oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not find requested item: {}", id);
 | 
							oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not find requested item: {}", id);
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto srcData = m_buffer->template dataOf<uint8_t>(src);
 | 
						auto srcData = m_buffer->template dataOf<uint8_t>(src);
 | 
				
			||||||
@@ -364,7 +366,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, FsSize_t readStart, FsSize_t
 | 
				
			|||||||
		oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not read data section of item: {}", id);
 | 
							oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not read data section of item: {}", id);
 | 
				
			||||||
		oxTracef("ox.fs.FileStoreTemplate.read.fail",
 | 
							oxTracef("ox.fs.FileStoreTemplate.read.fail",
 | 
				
			||||||
		         "Item data section size: {}, Expected size: {}", srcData.size(), readSize);
 | 
							         "Item data section size: {}, Expected size: {}", srcData.size(), readSize);
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ox::memcpy(out, srcData.get() + readStart, readSize);
 | 
						ox::memcpy(out, srcData.get() + readStart, readSize);
 | 
				
			||||||
@@ -384,7 +386,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, FsSize_t readStart,
 | 
				
			|||||||
	// error check
 | 
						// error check
 | 
				
			||||||
	if (!src.valid()) {
 | 
						if (!src.valid()) {
 | 
				
			||||||
		oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not find requested item: {}", id);
 | 
							oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not find requested item: {}", id);
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto srcData = m_buffer->template dataOf<uint8_t>(src);
 | 
						auto srcData = m_buffer->template dataOf<uint8_t>(src);
 | 
				
			||||||
@@ -397,7 +399,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, FsSize_t readStart,
 | 
				
			|||||||
		oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not read data section of item: {}", id);
 | 
							oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not read data section of item: {}", id);
 | 
				
			||||||
		oxTracef("ox.fs.FileStoreTemplate.read.fail",
 | 
							oxTracef("ox.fs.FileStoreTemplate.read.fail",
 | 
				
			||||||
		         "Item data section size: {}, Expected size: {}", srcData.size(), readSize);
 | 
							         "Item data section size: {}, Expected size: {}", srcData.size(), readSize);
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ox::memcpy(out, srcData.get() + readStart, readSize);
 | 
						ox::memcpy(out, srcData.get() + readStart, readSize);
 | 
				
			||||||
@@ -420,30 +422,30 @@ ptrarith::Ptr<uint8_t, std::size_t> FileStoreTemplate<size_t>::read(uint64_t id)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename size_t>
 | 
					template<typename size_t>
 | 
				
			||||||
Error FileStoreTemplate<size_t>::resize() {
 | 
					Error FileStoreTemplate<size_t>::resize() {
 | 
				
			||||||
	oxReturnError(compact());
 | 
						OX_RETURN_ERROR(compact());
 | 
				
			||||||
	const auto newSize = static_cast<std::size_t>(size() - available());
 | 
						const auto newSize = static_cast<std::size_t>(size() - available());
 | 
				
			||||||
	oxTracef("ox.fs.FileStoreTemplate.resize", "resize to: {}", newSize);
 | 
						oxTracef("ox.fs.FileStoreTemplate.resize", "resize to: {}", newSize);
 | 
				
			||||||
	oxReturnError(m_buffer->setSize(newSize));
 | 
						OX_RETURN_ERROR(m_buffer->setSize(newSize));
 | 
				
			||||||
	oxTracef("ox.fs.FileStoreTemplate.resize", "resized to: {}", m_buffer->size());
 | 
						oxTracef("ox.fs.FileStoreTemplate.resize", "resized to: {}", m_buffer->size());
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t>
 | 
					template<typename size_t>
 | 
				
			||||||
Error FileStoreTemplate<size_t>::resize(std::size_t size, void *newBuff) {
 | 
					Error FileStoreTemplate<size_t>::resize(std::size_t size, void *newBuff) {
 | 
				
			||||||
	if (m_buffer->size() > size) {
 | 
						if (m_buffer->size() > size) {
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error{1, "new buffer is too small for existing data"};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	m_buffSize = static_cast<size_t>(size);
 | 
						m_buffSize = static_cast<size_t>(size);
 | 
				
			||||||
	if (newBuff) {
 | 
						if (newBuff) {
 | 
				
			||||||
		m_buffer = reinterpret_cast<Buffer*>(newBuff);
 | 
							m_buffer = static_cast<Buffer*>(newBuff);
 | 
				
			||||||
		oxReturnError(m_buffer->setSize(static_cast<size_t>(size)));
 | 
							OX_RETURN_ERROR(m_buffer->setSize(static_cast<size_t>(size)));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t>
 | 
					template<typename size_t>
 | 
				
			||||||
Result<StatInfo> FileStoreTemplate<size_t>::stat(uint64_t id) const {
 | 
					Result<StatInfo> FileStoreTemplate<size_t>::stat(uint64_t id) const {
 | 
				
			||||||
	oxRequire(inode, find(static_cast<size_t>(id)).validate());
 | 
						OX_REQUIRE(inode, find(static_cast<size_t>(id)).validate());
 | 
				
			||||||
	return StatInfo {
 | 
						return StatInfo {
 | 
				
			||||||
		id,
 | 
							id,
 | 
				
			||||||
		inode->links,
 | 
							inode->links,
 | 
				
			||||||
@@ -475,16 +477,16 @@ char *FileStoreTemplate<size_t>::buff() {
 | 
				
			|||||||
template<typename size_t>
 | 
					template<typename size_t>
 | 
				
			||||||
Error FileStoreTemplate<size_t>::walk(Error(*cb)(uint8_t, uint64_t, uint64_t)) {
 | 
					Error FileStoreTemplate<size_t>::walk(Error(*cb)(uint8_t, uint64_t, uint64_t)) {
 | 
				
			||||||
	for (auto i = m_buffer->iterator(); i.valid(); i.next()) {
 | 
						for (auto i = m_buffer->iterator(); i.valid(); i.next()) {
 | 
				
			||||||
		oxReturnError(cb(i->fileType, i.ptr().offset(), i.ptr().end()));
 | 
							OX_RETURN_ERROR(cb(i->fileType, i.ptr().offset(), i.ptr().end()));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t>
 | 
					template<typename size_t>
 | 
				
			||||||
Result<typename FileStoreTemplate<size_t>::InodeId_t> FileStoreTemplate<size_t>::generateInodeId() {
 | 
					Result<typename FileStoreTemplate<size_t>::InodeId_t> FileStoreTemplate<size_t>::generateInodeId() {
 | 
				
			||||||
	auto fsData = fileStoreData();
 | 
						auto fsData = fileStoreData();
 | 
				
			||||||
	if (!fsData) {
 | 
						if (!fsData) {
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for (auto i = 0; i < 100; i++) {
 | 
						for (auto i = 0; i < 100; i++) {
 | 
				
			||||||
		auto inode = static_cast<typename FileStoreTemplate<size_t>::InodeId_t>(fsData->random.gen() % MaxValue<InodeId_t>);
 | 
							auto inode = static_cast<typename FileStoreTemplate<size_t>::InodeId_t>(fsData->random.gen() % MaxValue<InodeId_t>);
 | 
				
			||||||
@@ -492,7 +494,7 @@ Result<typename FileStoreTemplate<size_t>::InodeId_t> FileStoreTemplate<size_t>:
 | 
				
			|||||||
			return inode;
 | 
								return inode;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(2);
 | 
						return ox::Error(2);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t>
 | 
					template<typename size_t>
 | 
				
			||||||
@@ -501,10 +503,10 @@ Error FileStoreTemplate<size_t>::compact() {
 | 
				
			|||||||
	return m_buffer->compact([this, &isFirstItem](uint64_t oldAddr, ItemPtr item) -> Error {
 | 
						return m_buffer->compact([this, &isFirstItem](uint64_t oldAddr, ItemPtr item) -> Error {
 | 
				
			||||||
		if (isFirstItem) {
 | 
							if (isFirstItem) {
 | 
				
			||||||
			isFirstItem = false;
 | 
								isFirstItem = false;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (!item.valid()) {
 | 
							if (!item.valid()) {
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		oxTracef("ox.fs.FileStoreTemplate.compact.moveItem", "Moving Item: {} from {} to {}", item->id.get(), oldAddr, item.offset());
 | 
							oxTracef("ox.fs.FileStoreTemplate.compact.moveItem", "Moving Item: {} from {} to {}", item->id.get(), oldAddr, item.offset());
 | 
				
			||||||
		// update rootInode if this is it
 | 
							// update rootInode if this is it
 | 
				
			||||||
@@ -522,7 +524,7 @@ Error FileStoreTemplate<size_t>::compact() {
 | 
				
			|||||||
				parent->right = item;
 | 
									parent->right = item;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -542,15 +544,15 @@ template<typename size_t>
 | 
				
			|||||||
Error FileStoreTemplate<size_t>::placeItem(ItemPtr item) {
 | 
					Error FileStoreTemplate<size_t>::placeItem(ItemPtr item) {
 | 
				
			||||||
	auto fsData = fileStoreData();
 | 
						auto fsData = fileStoreData();
 | 
				
			||||||
	if (!fsData) {
 | 
						if (!fsData) {
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxRequireM(root, m_buffer->ptr(fsData->rootNode).validate());
 | 
						OX_REQUIRE_M(root, m_buffer->ptr(fsData->rootNode).validate());
 | 
				
			||||||
	if (root->id == item->id) {
 | 
						if (root->id == item->id) {
 | 
				
			||||||
		fsData->rootNode = item;
 | 
							fsData->rootNode = item;
 | 
				
			||||||
		item->left = root->left;
 | 
							item->left = root->left;
 | 
				
			||||||
		item->right = root->right;
 | 
							item->right = root->right;
 | 
				
			||||||
		oxTracef("ox.fs.FileStoreTemplate.placeItem", "Overwrote Root Item: {}", item->id.get());
 | 
							oxTracef("ox.fs.FileStoreTemplate.placeItem", "Overwrote Root Item: {}", item->id.get());
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return placeItem(root, item);
 | 
							return placeItem(root, item);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -560,7 +562,7 @@ template<typename size_t>
 | 
				
			|||||||
Error FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item, int depth) {
 | 
					Error FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item, int depth) {
 | 
				
			||||||
	if (depth > 5000) {
 | 
						if (depth > 5000) {
 | 
				
			||||||
		oxTrace("ox.fs.FileStoreTemplate.placeItem.fail", "Excessive recursion depth, stopping before stack overflow.");
 | 
							oxTrace("ox.fs.FileStoreTemplate.placeItem.fail", "Excessive recursion depth, stopping before stack overflow.");
 | 
				
			||||||
		return OxError(2);
 | 
							return ox::Error(2);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (item->id > root->id) {
 | 
						if (item->id > root->id) {
 | 
				
			||||||
		auto right = m_buffer->ptr(root->right);
 | 
							auto right = m_buffer->ptr(root->right);
 | 
				
			||||||
@@ -571,7 +573,7 @@ Error FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item, int depth
 | 
				
			|||||||
				item->right = right->right;
 | 
									item->right = right->right;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			oxTracef("ox.fs.FileStoreTemplate.placeItem", "Placed Item: {}", item->id.get());
 | 
								oxTracef("ox.fs.FileStoreTemplate.placeItem", "Placed Item: {}", item->id.get());
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			return placeItem(right, item, depth + 1);
 | 
								return placeItem(right, item, depth + 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -584,13 +586,13 @@ Error FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item, int depth
 | 
				
			|||||||
				item->right = left->right;
 | 
									item->right = left->right;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			oxTracef("ox.fs.FileStoreTemplate.placeItem", "Placed Item: {}", item->id.get());
 | 
								oxTracef("ox.fs.FileStoreTemplate.placeItem", "Placed Item: {}", item->id.get());
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			return placeItem(left, item, depth + 1);
 | 
								return placeItem(left, item, depth + 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		oxTrace("ox.fs.FileStoreTemplate.placeItem.fail", "Cannot insert an item on itself.");
 | 
							oxTrace("ox.fs.FileStoreTemplate.placeItem.fail", "Cannot insert an item on itself.");
 | 
				
			||||||
		return OxError(1, "Cannot insert an item on itself.");
 | 
							return ox::Error(1, "Cannot insert an item on itself.");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -598,9 +600,9 @@ template<typename size_t>
 | 
				
			|||||||
Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr item) {
 | 
					Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr item) {
 | 
				
			||||||
	auto fsData = fileStoreData();
 | 
						auto fsData = fileStoreData();
 | 
				
			||||||
	if (!fsData) {
 | 
						if (!fsData) {
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxRequireM(root, m_buffer->ptr(fsData->rootNode).validate());
 | 
						OX_REQUIRE_M(root, m_buffer->ptr(fsData->rootNode).validate());
 | 
				
			||||||
	if (root->id == item->id) {
 | 
						if (root->id == item->id) {
 | 
				
			||||||
		item->left = root->left;
 | 
							item->left = root->left;
 | 
				
			||||||
		item->right = root->right;
 | 
							item->right = root->right;
 | 
				
			||||||
@@ -622,7 +624,7 @@ Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr item) {
 | 
				
			|||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			fsData->rootNode = 0;
 | 
								fsData->rootNode = 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return unplaceItem(root, item);
 | 
							return unplaceItem(root, item);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -632,7 +634,7 @@ template<typename size_t>
 | 
				
			|||||||
Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr root, ItemPtr item, int depth) {
 | 
					Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr root, ItemPtr item, int depth) {
 | 
				
			||||||
	if (depth >= 5000) {
 | 
						if (depth >= 5000) {
 | 
				
			||||||
		oxTrace("ox.fs.FileStoreTemplate.unplaceItem.fail", "Excessive recursion depth, stopping before stack overflow.");
 | 
							oxTrace("ox.fs.FileStoreTemplate.unplaceItem.fail", "Excessive recursion depth, stopping before stack overflow.");
 | 
				
			||||||
		return OxError(1, "Excessive recursion depth, stopping before stack overflow.");
 | 
							return ox::Error(1, "Excessive recursion depth, stopping before stack overflow.");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (item->id > root->id) {
 | 
						if (item->id > root->id) {
 | 
				
			||||||
		auto right = m_buffer->ptr(root->right);
 | 
							auto right = m_buffer->ptr(root->right);
 | 
				
			||||||
@@ -651,25 +653,25 @@ Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr root, ItemPtr item, int dep
 | 
				
			|||||||
			return unplaceItem(left, item, depth + 1);
 | 
								return unplaceItem(left, item, depth + 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (item->right) {
 | 
						if (item->right) {
 | 
				
			||||||
		oxReturnError(placeItem(m_buffer->ptr(item->right)));
 | 
							OX_RETURN_ERROR(placeItem(m_buffer->ptr(item->right)));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (item->left) {
 | 
						if (item->left) {
 | 
				
			||||||
		oxReturnError(placeItem(m_buffer->ptr(item->left)));
 | 
							OX_RETURN_ERROR(placeItem(m_buffer->ptr(item->left)));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t>
 | 
					template<typename size_t>
 | 
				
			||||||
Error FileStoreTemplate<size_t>::remove(ItemPtr item) {
 | 
					Error FileStoreTemplate<size_t>::remove(ItemPtr item) {
 | 
				
			||||||
	if (item.valid()) {
 | 
						if (item.valid()) {
 | 
				
			||||||
		oxReturnError(unplaceItem(item));
 | 
							OX_RETURN_ERROR(unplaceItem(item));
 | 
				
			||||||
		oxReturnError(m_buffer->free(item));
 | 
							OX_RETURN_ERROR(m_buffer->free(item));
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1);
 | 
						return ox::Error(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t>
 | 
					template<typename size_t>
 | 
				
			||||||
@@ -771,3 +773,5 @@ using FileStore16 = FileStoreTemplate<uint16_t>;
 | 
				
			|||||||
using FileStore32 = FileStoreTemplate<uint32_t>;
 | 
					using FileStore32 = FileStoreTemplate<uint32_t>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_CLANG_NOWARN_END
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/fs/filesystem/directory.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/fs/filesystem/directory.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										68
									
								
								deps/ox/src/ox/fs/filesystem/directory.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										68
									
								
								deps/ox/src/ox/fs/filesystem/directory.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -15,6 +15,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "types.hpp"
 | 
					#include "types.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ox {
 | 
					namespace ox {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename InodeId_t>
 | 
					template<typename InodeId_t>
 | 
				
			||||||
@@ -43,17 +45,17 @@ struct OX_PACKED DirectoryEntry {
 | 
				
			|||||||
	public:
 | 
						public:
 | 
				
			||||||
		constexpr DirectoryEntry() noexcept = default;
 | 
							constexpr DirectoryEntry() noexcept = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error init(InodeId_t inode, ox::CRStringView name, size_t bufferSize) noexcept {
 | 
							Error init(InodeId_t inode, ox::StringViewCR name, size_t bufferSize) noexcept {
 | 
				
			||||||
			oxTracef("ox.fs.DirectoryEntry.init", "inode: {}, name: {}, bufferSize: {}", inode, name, bufferSize);
 | 
								oxTracef("ox.fs.DirectoryEntry.init", "inode: {}, name: {}, bufferSize: {}", inode, name, bufferSize);
 | 
				
			||||||
			m_bufferSize = static_cast<InodeId_t>(bufferSize);
 | 
								m_bufferSize = static_cast<InodeId_t>(bufferSize);
 | 
				
			||||||
			auto d = data();
 | 
								auto d = data();
 | 
				
			||||||
			if (d.valid()) {
 | 
								if (d.valid()) {
 | 
				
			||||||
				d->inode = inode;
 | 
									d->inode = inode;
 | 
				
			||||||
				auto const maxStrSz = bufferSize - 1 - sizeof(*this);
 | 
									auto const maxStrSz = bufferSize - 1 - sizeof(*this);
 | 
				
			||||||
				ox::strncpy(d->name, name.data(), ox::min(maxStrSz, name.len()));
 | 
									ox::strncpy(d->name, name.data(), ox::min(maxStrSz, name.size()));
 | 
				
			||||||
				return {};
 | 
									return {};
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ptrarith::Ptr<DirectoryEntryData, InodeId_t> data() noexcept {
 | 
							ptrarith::Ptr<DirectoryEntryData, InodeId_t> data() noexcept {
 | 
				
			||||||
@@ -139,11 +141,11 @@ template<typename FileStore, typename InodeId_t>
 | 
				
			|||||||
Error Directory<FileStore, InodeId_t>::init() noexcept {
 | 
					Error Directory<FileStore, InodeId_t>::init() noexcept {
 | 
				
			||||||
	constexpr auto Size = sizeof(Buffer);
 | 
						constexpr auto Size = sizeof(Buffer);
 | 
				
			||||||
	oxTracef("ox.fs.Directory.init", "Initializing Directory with Inode ID: {}", m_inodeId);
 | 
						oxTracef("ox.fs.Directory.init", "Initializing Directory with Inode ID: {}", m_inodeId);
 | 
				
			||||||
	oxReturnError(m_fs.write(m_inodeId, nullptr, Size, static_cast<uint8_t>(FileType::Directory)));
 | 
						OX_RETURN_ERROR(m_fs.write(m_inodeId, nullptr, Size, static_cast<uint8_t>(FileType::Directory)));
 | 
				
			||||||
	auto buff = m_fs.read(m_inodeId).template to<Buffer>();
 | 
						auto buff = m_fs.read(m_inodeId).template to<Buffer>();
 | 
				
			||||||
	if (!buff.valid()) {
 | 
						if (!buff.valid()) {
 | 
				
			||||||
		m_size = 0;
 | 
							m_size = 0;
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	new (buff) Buffer(Size);
 | 
						new (buff) Buffer(Size);
 | 
				
			||||||
	m_size = Size;
 | 
						m_size = Size;
 | 
				
			||||||
@@ -156,21 +158,21 @@ Error Directory<FileStore, InodeId_t>::mkdir(PathIterator path, bool parents) {
 | 
				
			|||||||
		oxTrace("ox.fs.Directory.mkdir", path.fullPath());
 | 
							oxTrace("ox.fs.Directory.mkdir", path.fullPath());
 | 
				
			||||||
		// determine if already exists
 | 
							// determine if already exists
 | 
				
			||||||
		ox::StringView name;
 | 
							ox::StringView name;
 | 
				
			||||||
		oxReturnError(path.get(name));
 | 
							OX_RETURN_ERROR(path.get(name));
 | 
				
			||||||
		auto childInode = find(PathIterator(name));
 | 
							auto childInode = find(PathIterator(name));
 | 
				
			||||||
		if (!childInode.ok()) {
 | 
							if (!childInode.ok()) {
 | 
				
			||||||
			// if this is not the last item in the path and parents is disabled,
 | 
								// if this is not the last item in the path and parents is disabled,
 | 
				
			||||||
			// return an error
 | 
								// return an error
 | 
				
			||||||
			if (!parents && path.hasNext()) {
 | 
								if (!parents && path.hasNext()) {
 | 
				
			||||||
				return OxError(1);
 | 
									return ox::Error(1);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			childInode = m_fs.generateInodeId();
 | 
								childInode = m_fs.generateInodeId();
 | 
				
			||||||
			oxTracef("ox.fs.Directory.mkdir", "Generated Inode ID: {}", childInode.value);
 | 
								oxTracef("ox.fs.Directory.mkdir", "Generated Inode ID: {}", childInode.value);
 | 
				
			||||||
			oxLogError(childInode.error);
 | 
								oxLogError(childInode.error);
 | 
				
			||||||
			oxReturnError(childInode.error);
 | 
								OX_RETURN_ERROR(childInode.error);
 | 
				
			||||||
			// initialize the directory
 | 
								// initialize the directory
 | 
				
			||||||
			Directory<FileStore, InodeId_t> child(m_fs, childInode.value);
 | 
								Directory<FileStore, InodeId_t> child(m_fs, childInode.value);
 | 
				
			||||||
			oxReturnError(child.init());
 | 
								OX_RETURN_ERROR(child.init());
 | 
				
			||||||
			auto err = write(PathIterator(name), childInode.value);
 | 
								auto err = write(PathIterator(name), childInode.value);
 | 
				
			||||||
			if (err) {
 | 
								if (err) {
 | 
				
			||||||
				oxLogError(err);
 | 
									oxLogError(err);
 | 
				
			||||||
@@ -181,7 +183,7 @@ Error Directory<FileStore, InodeId_t>::mkdir(PathIterator path, bool parents) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		Directory<FileStore, InodeId_t> child(m_fs, childInode.value);
 | 
							Directory<FileStore, InodeId_t> child(m_fs, childInode.value);
 | 
				
			||||||
		if (path.hasNext()) {
 | 
							if (path.hasNext()) {
 | 
				
			||||||
			oxReturnError(child.mkdir(path.next(), parents));
 | 
								OX_RETURN_ERROR(child.mkdir(path.next(), parents));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
@@ -194,45 +196,45 @@ Error Directory<FileStore, InodeId_t>::write(PathIterator path, uint64_t inode64
 | 
				
			|||||||
	if (path.next().hasNext()) { // not yet at target directory, recurse to next one
 | 
						if (path.next().hasNext()) { // not yet at target directory, recurse to next one
 | 
				
			||||||
		oxTracef("ox.fs.Directory.write", "Attempting to write to next sub-Directory: {} of {}",
 | 
							oxTracef("ox.fs.Directory.write", "Attempting to write to next sub-Directory: {} of {}",
 | 
				
			||||||
		         name, path.fullPath());
 | 
							         name, path.fullPath());
 | 
				
			||||||
		oxReturnError(path.get(name));
 | 
							OX_RETURN_ERROR(path.get(name));
 | 
				
			||||||
		oxRequire(nextChild, findEntry(name));
 | 
							OX_REQUIRE(nextChild, findEntry(name));
 | 
				
			||||||
		oxTracef("ox.fs.Directory.write", "{}: {}", name, nextChild);
 | 
							oxTracef("ox.fs.Directory.write", "{}: {}", name, nextChild);
 | 
				
			||||||
		if (nextChild) {
 | 
							if (nextChild) {
 | 
				
			||||||
			return Directory(m_fs, nextChild).write(path.next(), inode);
 | 
								return Directory(m_fs, nextChild).write(path.next(), inode);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			oxTracef("ox.fs.Directory.write", "{} not found and not allowed to create it.", name);
 | 
								oxTracef("ox.fs.Directory.write", "{} not found and not allowed to create it.", name);
 | 
				
			||||||
			return OxError(1, "File not found and not allowed to create it.");
 | 
								return ox::Error(1, "File not found and not allowed to create it.");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		oxTrace("ox.fs.Directory.write", path.fullPath());
 | 
							oxTrace("ox.fs.Directory.write", path.fullPath());
 | 
				
			||||||
		oxReturnError(path.next(name));
 | 
							OX_RETURN_ERROR(path.next(name));
 | 
				
			||||||
		// insert the new entry on this directory
 | 
							// insert the new entry on this directory
 | 
				
			||||||
		// get the name
 | 
							// get the name
 | 
				
			||||||
		// find existing version of directory
 | 
							// find existing version of directory
 | 
				
			||||||
		oxTracef("ox.fs.Directory.write", "Searching for directory inode {}", m_inodeId);
 | 
							oxTracef("ox.fs.Directory.write", "Searching for directory inode {}", m_inodeId);
 | 
				
			||||||
		oxRequire(oldStat, m_fs.stat(m_inodeId));
 | 
							OX_REQUIRE(oldStat, m_fs.stat(m_inodeId));
 | 
				
			||||||
		oxTracef("ox.fs.Directory.write", "Found existing directory of size {}", oldStat.size);
 | 
							oxTracef("ox.fs.Directory.write", "Found existing directory of size {}", oldStat.size);
 | 
				
			||||||
		auto old = m_fs.read(m_inodeId).template to<Buffer>();
 | 
							auto old = m_fs.read(m_inodeId).template to<Buffer>();
 | 
				
			||||||
		if (!old.valid()) {
 | 
							if (!old.valid()) {
 | 
				
			||||||
			oxTrace("ox.fs.Directory.write.fail", "Could not read existing version of Directory");
 | 
								oxTrace("ox.fs.Directory.write.fail", "Could not read existing version of Directory");
 | 
				
			||||||
			return OxError(1, "Could not read existing version of Directory");
 | 
								return ox::Error(1, "Could not read existing version of Directory");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		const auto pathSize = name.len() + 1;
 | 
							const auto pathSize = name.size() + 1;
 | 
				
			||||||
		const auto entryDataSize = DirectoryEntry<InodeId_t>::DirectoryEntryData::spaceNeeded(pathSize);
 | 
							const auto entryDataSize = DirectoryEntry<InodeId_t>::DirectoryEntryData::spaceNeeded(pathSize);
 | 
				
			||||||
		const auto newSize = oldStat.size + Buffer::spaceNeeded(entryDataSize);
 | 
							const auto newSize = oldStat.size + Buffer::spaceNeeded(entryDataSize);
 | 
				
			||||||
		auto cpy = ox_malloca(newSize, Buffer, *old, oldStat.size);
 | 
							auto cpy = ox_malloca(newSize, Buffer, *old, oldStat.size);
 | 
				
			||||||
		if (cpy == nullptr) {
 | 
							if (cpy == nullptr) {
 | 
				
			||||||
			oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for copy of Directory");
 | 
								oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for copy of Directory");
 | 
				
			||||||
			return OxError(1, "Could not allocate memory for copy of Directory");
 | 
								return ox::Error(1, "Could not allocate memory for copy of Directory");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		oxReturnError(cpy->setSize(newSize));
 | 
							OX_RETURN_ERROR(cpy->setSize(newSize));
 | 
				
			||||||
		auto val = cpy->malloc(entryDataSize).value;
 | 
							auto val = cpy->malloc(entryDataSize).value;
 | 
				
			||||||
		if (!val.valid()) {
 | 
							if (!val.valid()) {
 | 
				
			||||||
			oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for new directory entry");
 | 
								oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for new directory entry");
 | 
				
			||||||
			return OxError(1, "Could not allocate memory for new directory entry");
 | 
								return ox::Error(1, "Could not allocate memory for new directory entry");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		oxTracef("ox.fs.Directory.write", "Attempting to write Directory entry: {}", name);
 | 
							oxTracef("ox.fs.Directory.write", "Attempting to write Directory entry: {}", name);
 | 
				
			||||||
		oxReturnError(val->init(inode, name, val.size()));
 | 
							OX_RETURN_ERROR(val->init(inode, name, val.size()));
 | 
				
			||||||
		return m_fs.write(m_inodeId, cpy.get(), cpy->size(), static_cast<uint8_t>(FileType::Directory));
 | 
							return m_fs.write(m_inodeId, cpy.get(), cpy->size(), static_cast<uint8_t>(FileType::Directory));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -240,7 +242,7 @@ Error Directory<FileStore, InodeId_t>::write(PathIterator path, uint64_t inode64
 | 
				
			|||||||
template<typename FileStore, typename InodeId_t>
 | 
					template<typename FileStore, typename InodeId_t>
 | 
				
			||||||
Error Directory<FileStore, InodeId_t>::remove(PathIterator path) noexcept {
 | 
					Error Directory<FileStore, InodeId_t>::remove(PathIterator path) noexcept {
 | 
				
			||||||
	ox::StringView name;
 | 
						ox::StringView name;
 | 
				
			||||||
	oxReturnError(path.get(name));
 | 
						OX_RETURN_ERROR(path.get(name));
 | 
				
			||||||
	oxTrace("ox.fs.Directory.remove", name);
 | 
						oxTrace("ox.fs.Directory.remove", name);
 | 
				
			||||||
	auto buff = m_fs.read(m_inodeId).template to<Buffer>();
 | 
						auto buff = m_fs.read(m_inodeId).template to<Buffer>();
 | 
				
			||||||
	if (buff.valid()) {
 | 
						if (buff.valid()) {
 | 
				
			||||||
@@ -249,7 +251,7 @@ Error Directory<FileStore, InodeId_t>::remove(PathIterator path) noexcept {
 | 
				
			|||||||
			auto data = i->data();
 | 
								auto data = i->data();
 | 
				
			||||||
			if (data.valid()) {
 | 
								if (data.valid()) {
 | 
				
			||||||
				if (name == data->name) {
 | 
									if (name == data->name) {
 | 
				
			||||||
					oxReturnError(buff->free(i));
 | 
										OX_RETURN_ERROR(buff->free(i));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				oxTrace("ox.fs.Directory.remove", "INVALID DIRECTORY ENTRY");
 | 
									oxTrace("ox.fs.Directory.remove", "INVALID DIRECTORY ENTRY");
 | 
				
			||||||
@@ -257,7 +259,7 @@ Error Directory<FileStore, InodeId_t>::remove(PathIterator path) noexcept {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		oxTrace("ox.fs.Directory.remove.fail", "Could not find directory buffer");
 | 
							oxTrace("ox.fs.Directory.remove.fail", "Could not find directory buffer");
 | 
				
			||||||
		return OxError(1, "Could not find directory buffer");
 | 
							return ox::Error(1, "Could not find directory buffer");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -269,13 +271,13 @@ Error Directory<FileStore, InodeId_t>::ls(F cb) noexcept {
 | 
				
			|||||||
	auto buff = m_fs.read(m_inodeId).template to<Buffer>();
 | 
						auto buff = m_fs.read(m_inodeId).template to<Buffer>();
 | 
				
			||||||
	if (!buff.valid()) {
 | 
						if (!buff.valid()) {
 | 
				
			||||||
		oxTrace("ox.fs.Directory.ls.fail", "Could not directory buffer");
 | 
							oxTrace("ox.fs.Directory.ls.fail", "Could not directory buffer");
 | 
				
			||||||
		return OxError(1, "Could not directory buffer");
 | 
							return ox::Error(1, "Could not directory buffer");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxTrace("ox.fs.Directory.ls", "Found directory buffer.");
 | 
						oxTrace("ox.fs.Directory.ls", "Found directory buffer.");
 | 
				
			||||||
	for (auto i = buff->iterator(); i.valid(); i.next()) {
 | 
						for (auto i = buff->iterator(); i.valid(); i.next()) {
 | 
				
			||||||
		auto data = i->data();
 | 
							auto data = i->data();
 | 
				
			||||||
		if (data.valid()) {
 | 
							if (data.valid()) {
 | 
				
			||||||
			oxReturnError(cb(data->name, data->inode));
 | 
								OX_RETURN_ERROR(cb(data->name, data->inode));
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			oxTrace("ox.fs.Directory.ls", "INVALID DIRECTORY ENTRY");
 | 
								oxTrace("ox.fs.Directory.ls", "INVALID DIRECTORY ENTRY");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -284,12 +286,12 @@ Error Directory<FileStore, InodeId_t>::ls(F cb) noexcept {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename InodeId_t>
 | 
					template<typename FileStore, typename InodeId_t>
 | 
				
			||||||
Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::findEntry(CRStringView name) const noexcept {
 | 
					Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::findEntry(StringViewCR name) const noexcept {
 | 
				
			||||||
	oxTrace("ox.fs.Directory.findEntry", name);
 | 
						oxTrace("ox.fs.Directory.findEntry", name);
 | 
				
			||||||
	auto buff = m_fs.read(m_inodeId).template to<Buffer>();
 | 
						auto buff = m_fs.read(m_inodeId).template to<Buffer>();
 | 
				
			||||||
	if (!buff.valid()) {
 | 
						if (!buff.valid()) {
 | 
				
			||||||
		oxTrace("ox.fs.Directory.findEntry.fail", "Could not findEntry directory buffer");
 | 
							oxTrace("ox.fs.Directory.findEntry.fail", "Could not findEntry directory buffer");
 | 
				
			||||||
		return OxError(2, "Could not findEntry directory buffer");
 | 
							return ox::Error(2, "Could not findEntry directory buffer");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxTracef("ox.fs.Directory.findEntry", "Found directory buffer, size: {}", buff.size());
 | 
						oxTracef("ox.fs.Directory.findEntry", "Found directory buffer, size: {}", buff.size());
 | 
				
			||||||
	for (auto i = buff->iterator(); i.valid(); i.next()) {
 | 
						for (auto i = buff->iterator(); i.valid(); i.next()) {
 | 
				
			||||||
@@ -305,15 +307,15 @@ Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::findEntry
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxTrace("ox.fs.Directory.findEntry.fail", "Entry not present");
 | 
						oxTrace("ox.fs.Directory.findEntry.fail", "Entry not present");
 | 
				
			||||||
	return OxError(1, "Entry not present");
 | 
						return ox::Error(1, "Entry not present");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename InodeId_t>
 | 
					template<typename FileStore, typename InodeId_t>
 | 
				
			||||||
Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::find(PathIterator path) const noexcept {
 | 
					Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::find(PathIterator path) const noexcept {
 | 
				
			||||||
	// determine if already exists
 | 
						// determine if already exists
 | 
				
			||||||
	ox::StringView name;
 | 
						ox::StringView name;
 | 
				
			||||||
	oxReturnError(path.get(name));
 | 
						OX_RETURN_ERROR(path.get(name));
 | 
				
			||||||
	oxRequire(v, findEntry(name));
 | 
						OX_REQUIRE(v, findEntry(name));
 | 
				
			||||||
	// recurse if not at end of path
 | 
						// recurse if not at end of path
 | 
				
			||||||
	if (auto p = path.next(); p.valid()) {
 | 
						if (auto p = path.next(); p.valid()) {
 | 
				
			||||||
		Directory dir(m_fs, v);
 | 
							Directory dir(m_fs, v);
 | 
				
			||||||
@@ -333,3 +335,5 @@ using Directory16 = Directory<FileStore16, uint16_t>;
 | 
				
			|||||||
using Directory32 = Directory<FileStore32, uint32_t>;
 | 
					using Directory32 = Directory<FileStore32, uint32_t>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_CLANG_NOWARN_END
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								deps/ox/src/ox/fs/filesystem/filelocation.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								deps/ox/src/ox/fs/filesystem/filelocation.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -28,11 +28,13 @@ FileAddress::FileAddress(uint64_t inode) noexcept {
 | 
				
			|||||||
	m_type = FileAddressType::Inode;
 | 
						m_type = FileAddressType::Inode;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FileAddress::FileAddress(ox::CRStringView path) noexcept {
 | 
					FileAddress::FileAddress(ox::StringViewCR path) noexcept {
 | 
				
			||||||
	auto pathSize = path.bytes();
 | 
						auto pathSize = path.bytes();
 | 
				
			||||||
	m_data.path = new char[pathSize + 1];
 | 
						m_data.path = new char[pathSize + 1];
 | 
				
			||||||
 | 
						OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
	memcpy(m_data.path, path.data(), pathSize);
 | 
						memcpy(m_data.path, path.data(), pathSize);
 | 
				
			||||||
	m_data.path[pathSize] = 0;
 | 
						m_data.path[pathSize] = 0;
 | 
				
			||||||
 | 
						OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
	m_type = FileAddressType::Path;
 | 
						m_type = FileAddressType::Path;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -46,9 +48,11 @@ FileAddress &FileAddress::operator=(const FileAddress &other) noexcept {
 | 
				
			|||||||
		case FileAddressType::Path:
 | 
							case FileAddressType::Path:
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (other.m_data.path) {
 | 
								if (other.m_data.path) {
 | 
				
			||||||
 | 
									OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
				auto strSize = ox::strlen(other.m_data.path) + 1;
 | 
									auto strSize = ox::strlen(other.m_data.path) + 1;
 | 
				
			||||||
				m_data.path = new char[strSize];
 | 
									m_data.path = new char[strSize];
 | 
				
			||||||
				ox::memcpy(m_data.path, other.m_data.path, strSize);
 | 
									ox::memcpy(m_data.path, other.m_data.path, strSize);
 | 
				
			||||||
 | 
									OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				m_data.constPath = "";
 | 
									m_data.constPath = "";
 | 
				
			||||||
				m_type = FileAddressType::ConstPath;
 | 
									m_type = FileAddressType::ConstPath;
 | 
				
			||||||
@@ -114,7 +118,7 @@ bool FileAddress::operator==(FileAddress const&other) const noexcept {
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool FileAddress::operator==(CRStringView path) const noexcept {
 | 
					bool FileAddress::operator==(StringViewCR path) const noexcept {
 | 
				
			||||||
	auto [p, err] = getPath();
 | 
						auto [p, err] = getPath();
 | 
				
			||||||
	if (err) {
 | 
						if (err) {
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										39
									
								
								deps/ox/src/ox/fs/filesystem/filelocation.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								deps/ox/src/ox/fs/filesystem/filelocation.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -13,6 +13,8 @@
 | 
				
			|||||||
#include <ox/model/typenamecatcher.hpp>
 | 
					#include <ox/model/typenamecatcher.hpp>
 | 
				
			||||||
#include <ox/model/types.hpp>
 | 
					#include <ox/model/types.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ox {
 | 
					namespace ox {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum class FileAddressType: int8_t {
 | 
					enum class FileAddressType: int8_t {
 | 
				
			||||||
@@ -22,9 +24,6 @@ enum class FileAddressType: int8_t {
 | 
				
			|||||||
	Inode,
 | 
						Inode,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					 | 
				
			||||||
constexpr Error model(T *h, CommonPtrWith<class FileAddress> auto *fa) noexcept;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class FileAddress {
 | 
					class FileAddress {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<typename T>
 | 
						template<typename T>
 | 
				
			||||||
@@ -57,7 +56,7 @@ class FileAddress {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		FileAddress(uint64_t inode) noexcept;
 | 
							FileAddress(uint64_t inode) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		explicit FileAddress(CRStringView path) noexcept;
 | 
							explicit FileAddress(StringViewCR path) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		constexpr FileAddress(ox::StringLiteral path) noexcept;
 | 
							constexpr FileAddress(ox::StringLiteral path) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -69,7 +68,7 @@ class FileAddress {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		bool operator==(const FileAddress &other) const noexcept;
 | 
							bool operator==(const FileAddress &other) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool operator==(CRStringView path) const noexcept;
 | 
							bool operator==(StringViewCR path) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		constexpr FileAddressType type() const noexcept {
 | 
							constexpr FileAddressType type() const noexcept {
 | 
				
			||||||
@@ -87,7 +86,7 @@ class FileAddress {
 | 
				
			|||||||
				case FileAddressType::Inode:
 | 
									case FileAddressType::Inode:
 | 
				
			||||||
					return m_data.inode;
 | 
										return m_data.inode;
 | 
				
			||||||
				default:
 | 
									default:
 | 
				
			||||||
					return OxError(1);
 | 
										return ox::Error(1);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -98,7 +97,7 @@ class FileAddress {
 | 
				
			|||||||
				case FileAddressType::ConstPath:
 | 
									case FileAddressType::ConstPath:
 | 
				
			||||||
					return ox::CStringView(m_data.constPath);
 | 
										return ox::CStringView(m_data.constPath);
 | 
				
			||||||
				default:
 | 
									default:
 | 
				
			||||||
					return OxError(1);
 | 
										return ox::Error(1);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -152,31 +151,33 @@ constexpr const char *getModelTypeName<FileAddress>() noexcept {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr Error model(T *h, CommonPtrWith<FileAddress::Data> auto *obj) noexcept {
 | 
					constexpr Error model(T *h, CommonPtrWith<FileAddress::Data> auto *obj) noexcept {
 | 
				
			||||||
	oxReturnError(h->template setTypeInfo<FileAddress::Data>());
 | 
						OX_RETURN_ERROR(h->template setTypeInfo<FileAddress::Data>());
 | 
				
			||||||
	oxReturnError(h->fieldCString("path", &obj->path));
 | 
						OX_RETURN_ERROR(h->fieldCString("path", &obj->path));
 | 
				
			||||||
	oxReturnError(h->fieldCString("constPath", &obj->path));
 | 
						OX_RETURN_ERROR(h->fieldCString("constPath", &obj->path));
 | 
				
			||||||
	oxReturnError(h->field("inode", &obj->inode));
 | 
						OX_RETURN_ERROR(h->field("inode", &obj->inode));
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr Error model(T *h, CommonPtrWith<FileAddress> auto *fa) noexcept {
 | 
					constexpr Error model(T *h, CommonPtrWith<FileAddress> auto *fa) noexcept {
 | 
				
			||||||
	oxReturnError(h->template setTypeInfo<FileAddress>());
 | 
						OX_RETURN_ERROR(h->template setTypeInfo<FileAddress>());
 | 
				
			||||||
	if constexpr(T::opType() == OpType::Reflect) {
 | 
						if constexpr(T::opType() == OpType::Reflect) {
 | 
				
			||||||
		int8_t type = -1;
 | 
							int8_t type = -1;
 | 
				
			||||||
		oxReturnError(h->field("type", &type));
 | 
							OX_RETURN_ERROR(h->field("type", &type));
 | 
				
			||||||
		oxReturnError(h->field("data", UnionView(&fa->m_data, type)));
 | 
							OX_RETURN_ERROR(h->field("data", UnionView(&fa->m_data, type)));
 | 
				
			||||||
	} else if constexpr(T::opType() == OpType::Read) {
 | 
						} else if constexpr(T::opType() == OpType::Read) {
 | 
				
			||||||
		auto type = static_cast<int8_t>(fa->m_type);
 | 
							auto type = static_cast<int8_t>(fa->m_type);
 | 
				
			||||||
		oxReturnError(h->field("type", &type));
 | 
							OX_RETURN_ERROR(h->field("type", &type));
 | 
				
			||||||
		fa->m_type = static_cast<FileAddressType>(type);
 | 
							fa->m_type = static_cast<FileAddressType>(type);
 | 
				
			||||||
		oxReturnError(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
 | 
							OX_RETURN_ERROR(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
 | 
				
			||||||
	} else if constexpr(T::opType() == OpType::Write) {
 | 
						} else if constexpr(T::opType() == OpType::Write) {
 | 
				
			||||||
		auto const type = static_cast<int8_t>(fa->m_type);
 | 
							auto const type = static_cast<int8_t>(fa->m_type);
 | 
				
			||||||
		oxReturnError(h->field("type", &type));
 | 
							OX_RETURN_ERROR(h->field("type", &type));
 | 
				
			||||||
		oxReturnError(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
 | 
							OX_RETURN_ERROR(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_CLANG_NOWARN_END
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										75
									
								
								deps/ox/src/ox/fs/filesystem/filesystem.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										75
									
								
								deps/ox/src/ox/fs/filesystem/filesystem.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -21,7 +21,7 @@ Result<const char*> MemFS::directAccess(const FileAddress &addr) const noexcept
 | 
				
			|||||||
		case FileAddressType::Path:
 | 
							case FileAddressType::Path:
 | 
				
			||||||
			return directAccess(StringView(addr.getPath().value));
 | 
								return directAccess(StringView(addr.getPath().value));
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -33,46 +33,73 @@ Error FileSystem::read(const FileAddress &addr, void *buffer, std::size_t size)
 | 
				
			|||||||
		case FileAddressType::Path:
 | 
							case FileAddressType::Path:
 | 
				
			||||||
			return readFilePath(StringView(addr.getPath().value), buffer, size);
 | 
								return readFilePath(StringView(addr.getPath().value), buffer, size);
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Result<Buffer> FileSystem::read(FileAddress const &addr, size_t const size) noexcept {
 | 
				
			||||||
 | 
						Result<Buffer> out;
 | 
				
			||||||
 | 
						out.value.resize(size);
 | 
				
			||||||
 | 
						switch (addr.type()) {
 | 
				
			||||||
 | 
							case FileAddressType::Inode:
 | 
				
			||||||
 | 
								OX_RETURN_ERROR(readFileInode(addr.getInode().value, out.value.data(), size));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case FileAddressType::ConstPath:
 | 
				
			||||||
 | 
							case FileAddressType::Path:
 | 
				
			||||||
 | 
								OX_RETURN_ERROR(readFilePath(StringView{addr.getPath().value}, out.value.data(), size));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return ox::Error{1};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Result<Buffer> FileSystem::read(StringViewCR path, size_t const size) noexcept {
 | 
				
			||||||
 | 
						Result<Buffer> out;
 | 
				
			||||||
 | 
						out.value.resize(size);
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(readFilePath(path, out.value.data(), size));
 | 
				
			||||||
 | 
						return out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<Buffer> FileSystem::read(const FileAddress &addr) noexcept {
 | 
					Result<Buffer> FileSystem::read(const FileAddress &addr) noexcept {
 | 
				
			||||||
	oxRequire(s, stat(addr));
 | 
						OX_REQUIRE(s, stat(addr));
 | 
				
			||||||
	Buffer buff(static_cast<std::size_t>(s.size));
 | 
						Buffer buff(static_cast<std::size_t>(s.size));
 | 
				
			||||||
	oxReturnError(read(addr, buff.data(), buff.size()));
 | 
						OX_RETURN_ERROR(read(addr, buff.data(), buff.size()));
 | 
				
			||||||
	return buff;
 | 
						return buff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<Buffer> FileSystem::read(CRStringView path) noexcept {
 | 
					Result<Buffer> FileSystem::read(StringViewCR path) noexcept {
 | 
				
			||||||
	oxRequire(s, statPath(path));
 | 
						OX_REQUIRE(s, statPath(path));
 | 
				
			||||||
	Buffer buff(static_cast<std::size_t>(s.size));
 | 
						Buffer buff(static_cast<std::size_t>(s.size));
 | 
				
			||||||
	oxReturnError(readFilePath(path, buff.data(), buff.size()));
 | 
						OX_RETURN_ERROR(readFilePath(path, buff.data(), buff.size()));
 | 
				
			||||||
	return buff;
 | 
						return buff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error FileSystem::read(const FileAddress &addr, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept {
 | 
					Error FileSystem::read(
 | 
				
			||||||
 | 
							FileAddress const &addr,
 | 
				
			||||||
 | 
							std::size_t const readStart,
 | 
				
			||||||
 | 
							std::size_t const readSize,
 | 
				
			||||||
 | 
							void *buffer,
 | 
				
			||||||
 | 
							std::size_t *size) noexcept {
 | 
				
			||||||
	switch (addr.type()) {
 | 
						switch (addr.type()) {
 | 
				
			||||||
		case FileAddressType::Inode:
 | 
							case FileAddressType::Inode:
 | 
				
			||||||
			return read(addr.getInode().value, readStart, readSize, buffer, size);
 | 
								return readFileInodeRange(addr.getInode().value, readStart, readSize, buffer, size);
 | 
				
			||||||
		case FileAddressType::ConstPath:
 | 
							case FileAddressType::ConstPath:
 | 
				
			||||||
		case FileAddressType::Path:
 | 
							case FileAddressType::Path:
 | 
				
			||||||
			return OxError(2, "Unsupported for path lookups");
 | 
								return readFilePathRange(addr.getPath().value, readStart, readSize, buffer, size);
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error FileSystem::remove(const FileAddress &addr, bool recursive) noexcept {
 | 
					Result<size_t> FileSystem::read(
 | 
				
			||||||
	switch (addr.type()) {
 | 
							StringViewCR path,
 | 
				
			||||||
		case FileAddressType::Inode:
 | 
							std::size_t const readStart,
 | 
				
			||||||
			return remove(addr.getInode().value, recursive);
 | 
							std::size_t const readSize,
 | 
				
			||||||
		case FileAddressType::ConstPath:
 | 
							Span<char> buff) noexcept {
 | 
				
			||||||
		case FileAddressType::Path:
 | 
						size_t szOut{buff.size()};
 | 
				
			||||||
			return remove(StringView(addr.getPath().value), recursive);
 | 
						OX_RETURN_ERROR(readFilePathRange(path, readStart, readSize, buff.data(), &szOut));
 | 
				
			||||||
		default:
 | 
						return szOut;
 | 
				
			||||||
			return OxError(1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error FileSystem::write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType) noexcept {
 | 
					Error FileSystem::write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType) noexcept {
 | 
				
			||||||
@@ -83,7 +110,7 @@ Error FileSystem::write(const FileAddress &addr, const void *buffer, uint64_t si
 | 
				
			|||||||
		case FileAddressType::Path:
 | 
							case FileAddressType::Path:
 | 
				
			||||||
			return writeFilePath(StringView(addr.getPath().value), buffer, size, fileType);
 | 
								return writeFilePath(StringView(addr.getPath().value), buffer, size, fileType);
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -95,7 +122,7 @@ Result<FileStat> FileSystem::stat(const FileAddress &addr) const noexcept {
 | 
				
			|||||||
		case FileAddressType::Path:
 | 
							case FileAddressType::Path:
 | 
				
			||||||
			return statPath(StringView(addr.getPath().value));
 | 
								return statPath(StringView(addr.getPath().value));
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										249
									
								
								deps/ox/src/ox/fs/filesystem/filesystem.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										249
									
								
								deps/ox/src/ox/fs/filesystem/filesystem.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -20,7 +20,7 @@
 | 
				
			|||||||
namespace ox {
 | 
					namespace ox {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace detail {
 | 
					namespace detail {
 | 
				
			||||||
static inline void fsBuffFree(char *buff) noexcept {
 | 
					inline void fsBuffFree(char *buff) noexcept {
 | 
				
			||||||
	safeDelete(buff);
 | 
						safeDelete(buff);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -30,44 +30,64 @@ class FileSystem {
 | 
				
			|||||||
	public:
 | 
						public:
 | 
				
			||||||
		virtual ~FileSystem() noexcept = default;
 | 
							virtual ~FileSystem() noexcept = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual Error mkdir(CRStringView path, bool recursive) noexcept = 0;
 | 
							virtual Error mkdir(StringViewCR path, bool recursive) noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/**
 | 
							/**
 | 
				
			||||||
		 * Moves an entry from one directory to another.
 | 
							 * Moves an entry from one directory to another.
 | 
				
			||||||
		 * @param src the path to the file
 | 
							 * @param src the path to the file
 | 
				
			||||||
		 * @param dest the path of the destination directory
 | 
							 * @param dest the path of the destination directory
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		virtual Error move(CRStringView src, CRStringView dest) noexcept = 0;
 | 
							virtual Error move(StringViewCR src, StringViewCR dest) noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error read(const FileAddress &addr, void *buffer, std::size_t size) noexcept;
 | 
							Error read(const FileAddress &addr, void *buffer, std::size_t size) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Result<Buffer> read(FileAddress const &addr, size_t size) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Result<Buffer> read(StringViewCR path, size_t size) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<Buffer> read(const FileAddress &addr) noexcept;
 | 
							Result<Buffer> read(const FileAddress &addr) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<Buffer> read(CRStringView path) noexcept;
 | 
							Result<Buffer> read(StringViewCR path) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline Error read(CRStringView path, void *buffer, std::size_t buffSize) noexcept {
 | 
							Error read(StringViewCR path, void *buffer, std::size_t buffSize) noexcept {
 | 
				
			||||||
			return readFilePath(path, buffer, buffSize);
 | 
								return readFilePath(path, buffer, buffSize);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline Error read(uint64_t inode, void *buffer, std::size_t buffSize) noexcept {
 | 
							Error read(uint64_t inode, void *buffer, std::size_t buffSize) noexcept {
 | 
				
			||||||
			return readFileInode(inode, buffer, buffSize);
 | 
								return readFileInode(inode, buffer, buffSize);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error read(const FileAddress &addr, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept;
 | 
							Error read(
 | 
				
			||||||
 | 
								FileAddress const &addr,
 | 
				
			||||||
 | 
								size_t readStart,
 | 
				
			||||||
 | 
								size_t readSize,
 | 
				
			||||||
 | 
								void *buffer,
 | 
				
			||||||
 | 
								size_t *size) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual Result<Vector<String>> ls(CRStringView dir) const noexcept = 0;
 | 
							/**
 | 
				
			||||||
 | 
							 *
 | 
				
			||||||
 | 
							 * @param path
 | 
				
			||||||
 | 
							 * @param readStart
 | 
				
			||||||
 | 
							 * @param readSize
 | 
				
			||||||
 | 
							 * @param buff
 | 
				
			||||||
 | 
							 * @return error or number of bytes read
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							Result<size_t> read(
 | 
				
			||||||
 | 
								StringViewCR path, size_t readStart, size_t readSize, ox::Span<char> buff) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual Error remove(CRStringView path, bool recursive) noexcept = 0;
 | 
							virtual Result<Vector<String>> ls(StringViewCR dir) const noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error remove(const FileAddress &addr, bool recursive = false) noexcept;
 | 
							Error remove(StringViewCR path, bool recursive = false) noexcept {
 | 
				
			||||||
 | 
								return removePath(path, recursive);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual Error resize(uint64_t size, void *buffer) noexcept = 0;
 | 
							virtual Error resize(uint64_t size, void *buffer) noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error write(CRStringView path, const void *buffer, uint64_t size) noexcept {
 | 
							Error write(StringViewCR path, const void *buffer, uint64_t size) noexcept {
 | 
				
			||||||
			return writeFilePath(path, buffer, size, FileType::NormalFile);
 | 
								return writeFilePath(path, buffer, size, FileType::NormalFile);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error write(CRStringView path, ox::Span<char> const&buff) noexcept {
 | 
							Error write(StringViewCR path, ox::SpanView<char> const&buff) noexcept {
 | 
				
			||||||
			return write(path, buff.data(), buff.size(), FileType::NormalFile);
 | 
								return write(path, buff.data(), buff.size(), FileType::NormalFile);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -75,42 +95,42 @@ class FileSystem {
 | 
				
			|||||||
			return write(inode, buffer, size, FileType::NormalFile);
 | 
								return write(inode, buffer, size, FileType::NormalFile);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error write(uint64_t inode, ox::Span<char> const&buff) noexcept {
 | 
							Error write(uint64_t inode, ox::SpanView<char> const&buff) noexcept {
 | 
				
			||||||
			return write(inode, buff.data(), buff.size(), FileType::NormalFile);
 | 
								return write(inode, buff.data(), buff.size(), FileType::NormalFile);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType = FileType::NormalFile) noexcept;
 | 
							Error write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType = FileType::NormalFile) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline Error write(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept {
 | 
							Error write(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept {
 | 
				
			||||||
			return writeFilePath(path, buffer, size, fileType);
 | 
								return writeFilePath(path, buffer, size, fileType);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline Error write(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept {
 | 
							Error write(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept {
 | 
				
			||||||
			return writeFileInode(inode, buffer, size, fileType);
 | 
								return writeFileInode(inode, buffer, size, fileType);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline Result<FileStat> stat(uint64_t inode) const noexcept {
 | 
							Result<FileStat> stat(uint64_t inode) const noexcept {
 | 
				
			||||||
			return statInode(inode);
 | 
								return statInode(inode);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline Result<FileStat> stat(CRStringView path) const noexcept {
 | 
							Result<FileStat> stat(StringViewCR path) const noexcept {
 | 
				
			||||||
			return statPath(path);
 | 
								return statPath(path);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<FileStat> stat(const FileAddress &addr) const noexcept;
 | 
							Result<FileStat> stat(const FileAddress &addr) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		inline bool exists(uint64_t inode) const noexcept {
 | 
							bool exists(uint64_t inode) const noexcept {
 | 
				
			||||||
			return statInode(inode).ok();
 | 
								return statInode(inode).ok();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		inline bool exists(ox::StringView path) const noexcept {
 | 
							bool exists(ox::StringView path) const noexcept {
 | 
				
			||||||
			return statPath(path).ok();
 | 
								return statPath(path).ok();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		inline bool exists(FileAddress const&addr) const noexcept {
 | 
							bool exists(FileAddress const&addr) const noexcept {
 | 
				
			||||||
			return stat(addr).ok();
 | 
								return stat(addr).ok();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -134,15 +154,20 @@ class FileSystem {
 | 
				
			|||||||
	protected:
 | 
						protected:
 | 
				
			||||||
		virtual Result<FileStat> statInode(uint64_t inode) const noexcept = 0;
 | 
							virtual Result<FileStat> statInode(uint64_t inode) const noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual Result<FileStat> statPath(CRStringView path) const noexcept = 0;
 | 
							virtual Result<FileStat> statPath(StringViewCR path) const noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual Error readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept = 0;
 | 
							virtual Error readFilePath(StringViewCR path, void *buffer, std::size_t buffSize) noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept = 0;
 | 
							virtual Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept = 0;
 | 
							virtual Error readFilePathRange(
 | 
				
			||||||
 | 
								StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual Error writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept = 0;
 | 
							virtual Error readFileInodeRange(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							virtual Error removePath(StringViewCR path, bool recursive) noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							virtual Error writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept = 0;
 | 
							virtual Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -152,16 +177,16 @@ class MemFS: public FileSystem {
 | 
				
			|||||||
	public:
 | 
						public:
 | 
				
			||||||
		Result<const char*> directAccess(const FileAddress &addr) const noexcept;
 | 
							Result<const char*> directAccess(const FileAddress &addr) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline Result<const char*> directAccess(CRStringView path) const noexcept {
 | 
							Result<const char*> directAccess(StringViewCR path) const noexcept {
 | 
				
			||||||
			return directAccessPath(path);
 | 
								return directAccessPath(path);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline Result<const char*> directAccess(uint64_t inode) const noexcept {
 | 
							Result<const char*> directAccess(uint64_t inode) const noexcept {
 | 
				
			||||||
			return directAccessInode(inode);
 | 
								return directAccessInode(inode);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected:
 | 
						protected:
 | 
				
			||||||
		virtual Result<const char*> directAccessPath(CRStringView path) const noexcept = 0;
 | 
							virtual Result<const char*> directAccessPath(StringViewCR path) const noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual Result<const char*> directAccessInode(uint64_t inode) const noexcept = 0;
 | 
							virtual Result<const char*> directAccessInode(uint64_t inode) const noexcept = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -197,26 +222,29 @@ class FileSystemTemplate: public MemFS {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		static Error format(void *buff, uint64_t buffSize) noexcept;
 | 
							static Error format(void *buff, uint64_t buffSize) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error mkdir(CRStringView path, bool recursive) noexcept override;
 | 
							Error mkdir(StringViewCR path, bool recursive) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error move(CRStringView src, CRStringView dest) noexcept override;
 | 
							Error move(StringViewCR src, StringViewCR dest) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept override;
 | 
							Error readFilePath(StringViewCR path, void *buffer, std::size_t buffSize) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<const char*> directAccessPath(CRStringView) const noexcept override;
 | 
							Result<const char*> directAccessPath(StringViewCR) const noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept override;
 | 
							Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override;
 | 
							Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Error readFilePathRange(
 | 
				
			||||||
 | 
								StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Error removePath(StringViewCR path, bool recursive) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<const char*> directAccessInode(uint64_t) const noexcept override;
 | 
							Result<const char*> directAccessInode(uint64_t) const noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<Vector<String>> ls(CRStringView dir) const noexcept override;
 | 
							Result<Vector<String>> ls(StringViewCR dir) const noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename F>
 | 
							template<typename F>
 | 
				
			||||||
		Error ls(CRStringView path, F cb) const;
 | 
							Error ls(StringViewCR path, F cb) const;
 | 
				
			||||||
 | 
					 | 
				
			||||||
		Error remove(CRStringView path, bool recursive) noexcept override;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/**
 | 
							/**
 | 
				
			||||||
		 * Resizes FileSystem to minimum possible size.
 | 
							 * Resizes FileSystem to minimum possible size.
 | 
				
			||||||
@@ -225,13 +253,13 @@ class FileSystemTemplate: public MemFS {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		Error resize(uint64_t size, void *buffer) noexcept override;
 | 
							Error resize(uint64_t size, void *buffer) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept override;
 | 
							Error writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept override;
 | 
							Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<FileStat> statInode(uint64_t inode) const noexcept override;
 | 
							Result<FileStat> statInode(uint64_t inode) const noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<FileStat> statPath(CRStringView path) const noexcept override;
 | 
							Result<FileStat> statPath(StringViewCR path) const noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		uint64_t spaceNeeded(uint64_t size) const noexcept override;
 | 
							uint64_t spaceNeeded(uint64_t size) const noexcept override;
 | 
				
			||||||
@@ -253,7 +281,7 @@ class FileSystemTemplate: public MemFS {
 | 
				
			|||||||
		/**
 | 
							/**
 | 
				
			||||||
		 * Finds the inode ID at the given path.
 | 
							 * Finds the inode ID at the given path.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		Result<uint64_t> find(CRStringView path) const noexcept;
 | 
							Result<uint64_t> find(StringViewCR path) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<Directory> rootDir() const noexcept;
 | 
							Result<Directory> rootDir() const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -284,69 +312,69 @@ FileSystemTemplate<FileStore, Directory>::~FileSystemTemplate() noexcept {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Error FileSystemTemplate<FileStore, Directory>::format(void *buff, uint64_t buffSize) noexcept {
 | 
					Error FileSystemTemplate<FileStore, Directory>::format(void *buff, uint64_t buffSize) noexcept {
 | 
				
			||||||
	oxReturnError(FileStore::format(buff, static_cast<size_t>(buffSize)));
 | 
						OX_RETURN_ERROR(FileStore::format(buff, static_cast<size_t>(buffSize)));
 | 
				
			||||||
	FileStore fs(buff, static_cast<size_t>(buffSize));
 | 
						FileStore fs(buff, static_cast<size_t>(buffSize));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constexpr auto rootDirInode = MaxValue<typename FileStore::InodeId_t> / 2;
 | 
						constexpr auto rootDirInode = MaxValue<typename FileStore::InodeId_t> / 2;
 | 
				
			||||||
	Directory rootDir(fs, rootDirInode);
 | 
						Directory rootDir(fs, rootDirInode);
 | 
				
			||||||
	oxReturnError(rootDir.init());
 | 
						OX_RETURN_ERROR(rootDir.init());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FileSystemData fd;
 | 
						FileSystemData fd;
 | 
				
			||||||
	fd.rootDirInode = rootDirInode;
 | 
						fd.rootDirInode = rootDirInode;
 | 
				
			||||||
	oxTracef("ox.fs.FileSystemTemplate.format", "rootDirInode: {}", fd.rootDirInode.get());
 | 
						oxTracef("ox.fs.FileSystemTemplate.format", "rootDirInode: {}", fd.rootDirInode.get());
 | 
				
			||||||
	oxReturnError(fs.write(InodeFsData, &fd, sizeof(fd)));
 | 
						OX_RETURN_ERROR(fs.write(InodeFsData, &fd, sizeof(fd)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!fs.read(fd.rootDirInode).valid()) {
 | 
						if (!fs.read(fd.rootDirInode).valid()) {
 | 
				
			||||||
		oxTrace("ox.fs.FileSystemTemplate.format.error", "FileSystemTemplate::format did not correctly create root directory");
 | 
							oxTrace("ox.fs.FileSystemTemplate.format.error", "FileSystemTemplate::format did not correctly create root directory");
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Error FileSystemTemplate<FileStore, Directory>::mkdir(CRStringView path, bool recursive) noexcept {
 | 
					Error FileSystemTemplate<FileStore, Directory>::mkdir(StringViewCR path, bool recursive) noexcept {
 | 
				
			||||||
	oxTracef("ox.fs.FileSystemTemplate.mkdir", "path: {}, recursive: {}", path, recursive);
 | 
						oxTracef("ox.fs.FileSystemTemplate.mkdir", "path: {}, recursive: {}", path, recursive);
 | 
				
			||||||
	oxRequireM(rootDir, this->rootDir());
 | 
						OX_REQUIRE_M(rootDir, this->rootDir());
 | 
				
			||||||
	return rootDir.mkdir(path, recursive);
 | 
						return rootDir.mkdir(path, recursive);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Error FileSystemTemplate<FileStore, Directory>::move(CRStringView src, CRStringView dest) noexcept {
 | 
					Error FileSystemTemplate<FileStore, Directory>::move(StringViewCR src, StringViewCR dest) noexcept {
 | 
				
			||||||
	oxRequire(fd, fileSystemData());
 | 
						OX_REQUIRE(fd, fileSystemData());
 | 
				
			||||||
	Directory rootDir(m_fs, fd.rootDirInode);
 | 
						Directory rootDir(m_fs, fd.rootDirInode);
 | 
				
			||||||
	oxRequireM(inode, rootDir.find(src));
 | 
						OX_REQUIRE_M(inode, rootDir.find(src));
 | 
				
			||||||
	oxReturnError(rootDir.write(dest, inode));
 | 
						OX_RETURN_ERROR(rootDir.write(dest, inode));
 | 
				
			||||||
	oxReturnError(rootDir.remove(src));
 | 
						OX_RETURN_ERROR(rootDir.remove(src));
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Error FileSystemTemplate<FileStore, Directory>::readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept {
 | 
					Error FileSystemTemplate<FileStore, Directory>::readFilePath(StringViewCR path, void *buffer, std::size_t buffSize) noexcept {
 | 
				
			||||||
	oxTrace("ox.fs.FileSystemTemplate.readFilePath", path);
 | 
						oxTrace("ox.fs.FileSystemTemplate.readFilePath", path);
 | 
				
			||||||
	oxRequire(fd, fileSystemData());
 | 
						OX_REQUIRE(fd, fileSystemData());
 | 
				
			||||||
	Directory rootDir(m_fs, fd.rootDirInode);
 | 
						Directory rootDir(m_fs, fd.rootDirInode);
 | 
				
			||||||
	oxRequire(s, stat(path));
 | 
						OX_REQUIRE(s, stat(path));
 | 
				
			||||||
	if (s.size > buffSize) {
 | 
						if (s.size > buffSize) {
 | 
				
			||||||
		return OxError(1, "Buffer to small to load file");
 | 
							return ox::Error(1, "Buffer to small to load file");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return readFileInodeRange(s.inode, 0, static_cast<size_t>(s.size), buffer, &buffSize);
 | 
						return readFileInodeRange(s.inode, 0, static_cast<size_t>(s.size), buffer, &buffSize);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessPath(CRStringView path) const noexcept {
 | 
					Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessPath(StringViewCR path) const noexcept {
 | 
				
			||||||
	oxRequire(fd, fileSystemData());
 | 
						OX_REQUIRE(fd, fileSystemData());
 | 
				
			||||||
	Directory rootDir(m_fs, fd.rootDirInode);
 | 
						Directory rootDir(m_fs, fd.rootDirInode);
 | 
				
			||||||
	oxRequire(inode, rootDir.find(path));
 | 
						OX_REQUIRE(inode, rootDir.find(path));
 | 
				
			||||||
	return directAccessInode(inode);
 | 
						return directAccessInode(inode);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Error FileSystemTemplate<FileStore, Directory>::readFileInode(uint64_t inode, void *buffer, std::size_t buffSize) noexcept {
 | 
					Error FileSystemTemplate<FileStore, Directory>::readFileInode(uint64_t inode, void *buffer, std::size_t buffSize) noexcept {
 | 
				
			||||||
	oxTracef("ox.fs.FileSystemTemplate.readFileInode", "{}", inode);
 | 
						oxTracef("ox.fs.FileSystemTemplate.readFileInode", "{}", inode);
 | 
				
			||||||
	oxRequire(s, stat(inode));
 | 
						OX_REQUIRE(s, stat(inode));
 | 
				
			||||||
	if (s.size > buffSize) {
 | 
						if (s.size > buffSize) {
 | 
				
			||||||
		return OxError(1, "Buffer to small to load file");
 | 
							return ox::Error(1, "Buffer to small to load file");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return readFileInodeRange(inode, 0, static_cast<size_t>(s.size), buffer, &buffSize);
 | 
						return readFileInodeRange(inode, 0, static_cast<size_t>(s.size), buffer, &buffSize);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -357,39 +385,18 @@ Error FileSystemTemplate<FileStore, Directory>::readFileInodeRange(uint64_t inod
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessInode(uint64_t inode) const noexcept {
 | 
					Error FileSystemTemplate<FileStore, Directory>::readFilePathRange(
 | 
				
			||||||
	auto data = m_fs.read(inode);
 | 
						StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept {
 | 
				
			||||||
	if (!data.valid()) {
 | 
						OX_REQUIRE(s, stat(path));
 | 
				
			||||||
		return OxError(1, "Data not valid");
 | 
						return readFileInodeRange(s.inode, readStart, readSize, buffer, buffSize);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return reinterpret_cast<char*>(data.get());
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Result<Vector<String>> FileSystemTemplate<FileStore, Directory>::ls(CRStringView path) const noexcept {
 | 
					Error FileSystemTemplate<FileStore, Directory>::removePath(StringViewCR path, bool recursive) noexcept {
 | 
				
			||||||
	Vector<String> out;
 | 
						OX_REQUIRE(fd, fileSystemData());
 | 
				
			||||||
	oxReturnError(ls(path, [&out](CRStringView name, typename FileStore::InodeId_t) {
 | 
					 | 
				
			||||||
		out.emplace_back(name);
 | 
					 | 
				
			||||||
		return OxError(0);
 | 
					 | 
				
			||||||
	}));
 | 
					 | 
				
			||||||
	return out;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					 | 
				
			||||||
template<typename F>
 | 
					 | 
				
			||||||
Error FileSystemTemplate<FileStore, Directory>::ls(CRStringView path, F cb) const {
 | 
					 | 
				
			||||||
	oxTracef("ox.fs.FileSystemTemplate.ls", "path: {}", path);
 | 
					 | 
				
			||||||
	oxRequire(s, stat(path));
 | 
					 | 
				
			||||||
	Directory dir(m_fs, s.inode);
 | 
					 | 
				
			||||||
	return dir.ls(cb);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					 | 
				
			||||||
Error FileSystemTemplate<FileStore, Directory>::remove(CRStringView path, bool recursive) noexcept {
 | 
					 | 
				
			||||||
	oxRequire(fd, fileSystemData());
 | 
					 | 
				
			||||||
	Directory rootDir(m_fs, fd.rootDirInode);
 | 
						Directory rootDir(m_fs, fd.rootDirInode);
 | 
				
			||||||
	oxRequire(inode, rootDir.find(path));
 | 
						OX_REQUIRE(inode, rootDir.find(path));
 | 
				
			||||||
	oxRequire(st, statInode(inode));
 | 
						OX_REQUIRE(st, statInode(inode));
 | 
				
			||||||
	if (st.fileType == FileType::NormalFile || recursive) {
 | 
						if (st.fileType == FileType::NormalFile || recursive) {
 | 
				
			||||||
		if (auto err = rootDir.remove(path)) {
 | 
							if (auto err = rootDir.remove(path)) {
 | 
				
			||||||
			// removal failed, try putting the index back
 | 
								// removal failed, try putting the index back
 | 
				
			||||||
@@ -398,9 +405,37 @@ Error FileSystemTemplate<FileStore, Directory>::remove(CRStringView path, bool r
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		oxTrace("FileSystemTemplate.remove.fail", "Tried to remove directory without recursive setting.");
 | 
							oxTrace("FileSystemTemplate.remove.fail", "Tried to remove directory without recursive setting.");
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
 | 
					Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessInode(uint64_t inode) const noexcept {
 | 
				
			||||||
 | 
						auto data = m_fs.read(inode);
 | 
				
			||||||
 | 
						if (!data.valid()) {
 | 
				
			||||||
 | 
							return ox::Error(1, "Data not valid");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return reinterpret_cast<char*>(data.get());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
 | 
					Result<Vector<String>> FileSystemTemplate<FileStore, Directory>::ls(StringViewCR path) const noexcept {
 | 
				
			||||||
 | 
						Vector<String> out;
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(ls(path, [&out](StringViewCR name, typename FileStore::InodeId_t) {
 | 
				
			||||||
 | 
							out.emplace_back(name);
 | 
				
			||||||
 | 
							return ox::Error{};
 | 
				
			||||||
 | 
						}));
 | 
				
			||||||
 | 
						return out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
 | 
					template<typename F>
 | 
				
			||||||
 | 
					Error FileSystemTemplate<FileStore, Directory>::ls(StringViewCR path, F cb) const {
 | 
				
			||||||
 | 
						oxTracef("ox.fs.FileSystemTemplate.ls", "path: {}", path);
 | 
				
			||||||
 | 
						OX_REQUIRE(s, stat(path));
 | 
				
			||||||
 | 
						Directory dir(m_fs, s.inode);
 | 
				
			||||||
 | 
						return dir.ls(cb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
@@ -410,36 +445,36 @@ Error FileSystemTemplate<FileStore, Directory>::resize() noexcept {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Error FileSystemTemplate<FileStore, Directory>::resize(uint64_t size, void *buffer) noexcept {
 | 
					Error FileSystemTemplate<FileStore, Directory>::resize(uint64_t size, void *buffer) noexcept {
 | 
				
			||||||
	oxReturnError(m_fs.resize(static_cast<size_t>(size), buffer));
 | 
						OX_RETURN_ERROR(m_fs.resize(static_cast<size_t>(size), buffer));
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Error FileSystemTemplate<FileStore, Directory>::writeFilePath(
 | 
					Error FileSystemTemplate<FileStore, Directory>::writeFilePath(
 | 
				
			||||||
		CRStringView path,
 | 
							StringViewCR path,
 | 
				
			||||||
		const void *buffer,
 | 
							const void *buffer,
 | 
				
			||||||
		uint64_t size,
 | 
							uint64_t size,
 | 
				
			||||||
		FileType fileType) noexcept {
 | 
							FileType fileType) noexcept {
 | 
				
			||||||
	oxTrace("ox.fs.FileSystemTemplate.writeFilePath", path);
 | 
						oxTrace("ox.fs.FileSystemTemplate.writeFilePath", path);
 | 
				
			||||||
	auto [inode, err] = find(path);
 | 
						auto [inode, err] = find(path);
 | 
				
			||||||
	if (err) {
 | 
						if (err) {
 | 
				
			||||||
		oxReturnError(m_fs.generateInodeId().moveTo(inode));
 | 
							OX_RETURN_ERROR(m_fs.generateInodeId().moveTo(inode));
 | 
				
			||||||
		oxRequireM(rootDir, this->rootDir());
 | 
							OX_REQUIRE_M(rootDir, this->rootDir());
 | 
				
			||||||
		oxReturnError(rootDir.write(path, inode));
 | 
							OX_RETURN_ERROR(rootDir.write(path, inode));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(writeFileInode(inode, buffer, size, fileType));
 | 
						OX_RETURN_ERROR(writeFileInode(inode, buffer, size, fileType));
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Error FileSystemTemplate<FileStore, Directory>::writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept {
 | 
					Error FileSystemTemplate<FileStore, Directory>::writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept {
 | 
				
			||||||
	oxTrace("ox.fs.FileSystemTemplate.writeFileInode", ox::itoa(inode));
 | 
						oxTrace("ox.fs.FileSystemTemplate.writeFileInode", ox::intToStr(inode));
 | 
				
			||||||
	return m_fs.write(inode, buffer, static_cast<size_t>(size), static_cast<uint8_t>(fileType));
 | 
						return m_fs.write(inode, buffer, static_cast<size_t>(size), static_cast<uint8_t>(fileType));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Result<FileStat> FileSystemTemplate<FileStore, Directory>::statInode(uint64_t inode) const noexcept {
 | 
					Result<FileStat> FileSystemTemplate<FileStore, Directory>::statInode(uint64_t inode) const noexcept {
 | 
				
			||||||
	oxRequire(s, m_fs.stat(inode));
 | 
						OX_REQUIRE(s, m_fs.stat(inode));
 | 
				
			||||||
	FileStat out;
 | 
						FileStat out;
 | 
				
			||||||
	out.inode = s.inode;
 | 
						out.inode = s.inode;
 | 
				
			||||||
	out.links = s.links;
 | 
						out.links = s.links;
 | 
				
			||||||
@@ -449,8 +484,8 @@ Result<FileStat> FileSystemTemplate<FileStore, Directory>::statInode(uint64_t in
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Result<FileStat> FileSystemTemplate<FileStore, Directory>::statPath(CRStringView path) const noexcept {
 | 
					Result<FileStat> FileSystemTemplate<FileStore, Directory>::statPath(StringViewCR path) const noexcept {
 | 
				
			||||||
	oxRequire(inode, find(path));
 | 
						OX_REQUIRE(inode, find(path));
 | 
				
			||||||
	return stat(inode);
 | 
						return stat(inode);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -487,25 +522,25 @@ bool FileSystemTemplate<FileStore, Directory>::valid() const noexcept {
 | 
				
			|||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Result<typename FileSystemTemplate<FileStore, Directory>::FileSystemData> FileSystemTemplate<FileStore, Directory>::fileSystemData() const noexcept {
 | 
					Result<typename FileSystemTemplate<FileStore, Directory>::FileSystemData> FileSystemTemplate<FileStore, Directory>::fileSystemData() const noexcept {
 | 
				
			||||||
	FileSystemData fd;
 | 
						FileSystemData fd;
 | 
				
			||||||
	oxReturnError(m_fs.read(InodeFsData, &fd, sizeof(fd)));
 | 
						OX_RETURN_ERROR(m_fs.read(InodeFsData, &fd, sizeof(fd)));
 | 
				
			||||||
	return fd;
 | 
						return fd;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Result<uint64_t> FileSystemTemplate<FileStore, Directory>::find(CRStringView path) const noexcept {
 | 
					Result<uint64_t> FileSystemTemplate<FileStore, Directory>::find(StringViewCR path) const noexcept {
 | 
				
			||||||
	oxRequire(fd, fileSystemData());
 | 
						OX_REQUIRE(fd, fileSystemData());
 | 
				
			||||||
	// return root as a special case
 | 
						// return root as a special case
 | 
				
			||||||
	if (path == "/") {
 | 
						if (path == "/") {
 | 
				
			||||||
		return static_cast<uint64_t>(fd.rootDirInode);
 | 
							return static_cast<uint64_t>(fd.rootDirInode);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	Directory rootDir(m_fs, fd.rootDirInode);
 | 
						Directory rootDir(m_fs, fd.rootDirInode);
 | 
				
			||||||
	oxRequire(out, rootDir.find(path));
 | 
						OX_REQUIRE(out, rootDir.find(path));
 | 
				
			||||||
	return static_cast<uint64_t>(out);
 | 
						return static_cast<uint64_t>(out);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename FileStore, typename Directory>
 | 
					template<typename FileStore, typename Directory>
 | 
				
			||||||
Result<Directory> FileSystemTemplate<FileStore, Directory>::rootDir() const noexcept {
 | 
					Result<Directory> FileSystemTemplate<FileStore, Directory>::rootDir() const noexcept {
 | 
				
			||||||
	oxRequire(fd, fileSystemData());
 | 
						OX_REQUIRE(fd, fileSystemData());
 | 
				
			||||||
	return Directory(m_fs, fd.rootDirInode);
 | 
						return Directory(m_fs, fd.rootDirInode);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										96
									
								
								deps/ox/src/ox/fs/filesystem/passthroughfs.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										96
									
								
								deps/ox/src/ox/fs/filesystem/passthroughfs.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -17,7 +17,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace ox {
 | 
					namespace ox {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PassThroughFS::PassThroughFS(CRStringView dirPath) {
 | 
					PassThroughFS::PassThroughFS(StringViewCR dirPath) {
 | 
				
			||||||
	m_path = std::string_view(dirPath.data(), dirPath.bytes());
 | 
						m_path = std::string_view(dirPath.data(), dirPath.bytes());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,7 +27,7 @@ String PassThroughFS::basePath() const noexcept {
 | 
				
			|||||||
	return ox::String(m_path.string().c_str());
 | 
						return ox::String(m_path.string().c_str());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error PassThroughFS::mkdir(CRStringView path, bool recursive) noexcept {
 | 
					Error PassThroughFS::mkdir(StringViewCR path, bool recursive) noexcept {
 | 
				
			||||||
	bool success = false;
 | 
						bool success = false;
 | 
				
			||||||
	const auto p = m_path / stripSlash(path);
 | 
						const auto p = m_path / stripSlash(path);
 | 
				
			||||||
	const auto u8p = p.u8string();
 | 
						const auto u8p = p.u8string();
 | 
				
			||||||
@@ -39,7 +39,7 @@ Error PassThroughFS::mkdir(CRStringView path, bool recursive) noexcept {
 | 
				
			|||||||
			success = true;
 | 
								success = true;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			success = std::filesystem::create_directories(p, ec);
 | 
								success = std::filesystem::create_directories(p, ec);
 | 
				
			||||||
			oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed"));
 | 
								OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed"));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		std::error_code ec;
 | 
							std::error_code ec;
 | 
				
			||||||
@@ -48,26 +48,26 @@ Error PassThroughFS::mkdir(CRStringView path, bool recursive) noexcept {
 | 
				
			|||||||
			success = true;
 | 
								success = true;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			success = std::filesystem::create_directory(p, ec);
 | 
								success = std::filesystem::create_directory(p, ec);
 | 
				
			||||||
			oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed"));
 | 
								OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed"));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(success ? 0 : 1);
 | 
						return ox::Error(success ? 0 : 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error PassThroughFS::move(CRStringView src, CRStringView dest) noexcept {
 | 
					Error PassThroughFS::move(StringViewCR src, StringViewCR dest) noexcept {
 | 
				
			||||||
	std::error_code ec;
 | 
						std::error_code ec;
 | 
				
			||||||
	std::filesystem::rename(m_path / stripSlash(src), m_path / stripSlash(dest), ec);
 | 
						std::filesystem::rename(m_path / stripSlash(src), m_path / stripSlash(dest), ec);
 | 
				
			||||||
	if (ec.value()) {
 | 
						if (ec.value()) {
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<Vector<String>> PassThroughFS::ls(CRStringView dir) const noexcept {
 | 
					Result<Vector<String>> PassThroughFS::ls(StringViewCR dir) const noexcept {
 | 
				
			||||||
	Vector<String> out;
 | 
						Vector<String> out;
 | 
				
			||||||
	std::error_code ec;
 | 
						std::error_code ec;
 | 
				
			||||||
	const auto di = std::filesystem::directory_iterator(m_path / stripSlash(dir), ec);
 | 
						const auto di = std::filesystem::directory_iterator(m_path / stripSlash(dir), ec);
 | 
				
			||||||
	oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: ls failed"));
 | 
						OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: ls failed"));
 | 
				
			||||||
	for (const auto &p : di) {
 | 
						for (const auto &p : di) {
 | 
				
			||||||
		const auto u8p = p.path().filename().u8string();
 | 
							const auto u8p = p.path().filename().u8string();
 | 
				
			||||||
		out.emplace_back(reinterpret_cast<const char*>(u8p.c_str()));
 | 
							out.emplace_back(reinterpret_cast<const char*>(u8p.c_str()));
 | 
				
			||||||
@@ -75,25 +75,17 @@ Result<Vector<String>> PassThroughFS::ls(CRStringView dir) const noexcept {
 | 
				
			|||||||
	return out;
 | 
						return out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error PassThroughFS::remove(CRStringView path, bool recursive) noexcept {
 | 
					 | 
				
			||||||
	if (recursive) {
 | 
					 | 
				
			||||||
		return OxError(std::filesystem::remove_all(m_path / stripSlash(path)) != 0);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		return OxError(std::filesystem::remove(m_path / stripSlash(path)) != 0);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Error PassThroughFS::resize(uint64_t, void*) noexcept {
 | 
					Error PassThroughFS::resize(uint64_t, void*) noexcept {
 | 
				
			||||||
	// unsupported
 | 
						// unsupported
 | 
				
			||||||
	return OxError(1, "resize is not supported by PassThroughFS");
 | 
						return ox::Error(1, "resize is not supported by PassThroughFS");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<FileStat> PassThroughFS::statInode(uint64_t) const noexcept {
 | 
					Result<FileStat> PassThroughFS::statInode(uint64_t) const noexcept {
 | 
				
			||||||
	// unsupported
 | 
						// unsupported
 | 
				
			||||||
	return OxError(1, "statInode(uint64_t) is not supported by PassThroughFS");
 | 
						return ox::Error(1, "statInode(uint64_t) is not supported by PassThroughFS");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<FileStat> PassThroughFS::statPath(CRStringView path) const noexcept {
 | 
					Result<FileStat> PassThroughFS::statPath(StringViewCR path) const noexcept {
 | 
				
			||||||
	std::error_code ec;
 | 
						std::error_code ec;
 | 
				
			||||||
	const auto p = m_path / stripSlash(path);
 | 
						const auto p = m_path / stripSlash(path);
 | 
				
			||||||
	const FileType type = std::filesystem::is_directory(p, ec) ?
 | 
						const FileType type = std::filesystem::is_directory(p, ec) ?
 | 
				
			||||||
@@ -101,7 +93,9 @@ Result<FileStat> PassThroughFS::statPath(CRStringView path) const noexcept {
 | 
				
			|||||||
	oxTracef("ox.fs.PassThroughFS.statInode", "{} {}", ec.message(), path);
 | 
						oxTracef("ox.fs.PassThroughFS.statInode", "{} {}", ec.message(), path);
 | 
				
			||||||
	const uint64_t size = type == FileType::Directory ? 0 : std::filesystem::file_size(p, ec);
 | 
						const uint64_t size = type == FileType::Directory ? 0 : std::filesystem::file_size(p, ec);
 | 
				
			||||||
	oxTracef("ox.fs.PassThroughFS.statInode.size", "{} {}", path, size);
 | 
						oxTracef("ox.fs.PassThroughFS.statInode.size", "{} {}", path, size);
 | 
				
			||||||
	oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: stat failed"));
 | 
						if (auto err = ec.value()) {
 | 
				
			||||||
 | 
							return ox::Error{static_cast<ox::ErrorCode>(err), "PassThroughFS: stat failed"};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return FileStat{0, 0, size, type};
 | 
						return FileStat{0, 0, size, type};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -112,14 +106,14 @@ uint64_t PassThroughFS::spaceNeeded(uint64_t size) const noexcept {
 | 
				
			|||||||
Result<uint64_t> PassThroughFS::available() const noexcept {
 | 
					Result<uint64_t> PassThroughFS::available() const noexcept {
 | 
				
			||||||
	std::error_code ec;
 | 
						std::error_code ec;
 | 
				
			||||||
	const auto s = std::filesystem::space(m_path, ec);
 | 
						const auto s = std::filesystem::space(m_path, ec);
 | 
				
			||||||
	oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: could not get FS size"));
 | 
						OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: could not get FS size"));
 | 
				
			||||||
	return s.available;
 | 
						return s.available;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<uint64_t> PassThroughFS::size() const noexcept {
 | 
					Result<uint64_t> PassThroughFS::size() const noexcept {
 | 
				
			||||||
	std::error_code ec;
 | 
						std::error_code ec;
 | 
				
			||||||
	const auto s = std::filesystem::space(m_path, ec);
 | 
						const auto s = std::filesystem::space(m_path, ec);
 | 
				
			||||||
	oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: could not get FS size"));
 | 
						OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: could not get FS size"));
 | 
				
			||||||
	return s.capacity;
 | 
						return s.capacity;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -128,7 +122,7 @@ char *PassThroughFS::buff() noexcept {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error PassThroughFS::walk(Error(*)(uint8_t, uint64_t, uint64_t)) noexcept {
 | 
					Error PassThroughFS::walk(Error(*)(uint8_t, uint64_t, uint64_t)) noexcept {
 | 
				
			||||||
	return OxError(1, "walk(Error(*)(uint8_t, uint64_t, uint64_t)) is not supported by PassThroughFS");
 | 
						return ox::Error(1, "walk(Error(*)(uint8_t, uint64_t, uint64_t)) is not supported by PassThroughFS");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool PassThroughFS::valid() const noexcept {
 | 
					bool PassThroughFS::valid() const noexcept {
 | 
				
			||||||
@@ -140,53 +134,79 @@ bool PassThroughFS::valid() const noexcept {
 | 
				
			|||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error PassThroughFS::readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept {
 | 
					Error PassThroughFS::readFilePath(StringViewCR path, void *buffer, std::size_t buffSize) noexcept {
 | 
				
			||||||
	try {
 | 
						try {
 | 
				
			||||||
		std::ifstream file((m_path / stripSlash(path)), std::ios::binary | std::ios::ate);
 | 
							std::ifstream file((m_path / stripSlash(path)), std::ios::binary | std::ios::ate);
 | 
				
			||||||
		const std::size_t size = static_cast<std::size_t>(file.tellg());
 | 
							const std::size_t size = static_cast<std::size_t>(file.tellg());
 | 
				
			||||||
		file.seekg(0, std::ios::beg);
 | 
							file.seekg(0, std::ios::beg);
 | 
				
			||||||
		if (size > buffSize) {
 | 
							if (size > buffSize) {
 | 
				
			||||||
			oxTracef("ox.fs.PassThroughFS.read.error", "Read failed: Buffer too small: {}", path);
 | 
								oxTracef("ox.fs.PassThroughFS.read.error", "Read failed: Buffer too small: {}", path);
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		file.read(static_cast<char*>(buffer), static_cast<std::streamsize>(buffSize));
 | 
							file.read(static_cast<char*>(buffer), static_cast<std::streamsize>(buffSize));
 | 
				
			||||||
	} catch (const std::fstream::failure &f) {
 | 
						} catch (const std::fstream::failure &f) {
 | 
				
			||||||
		oxTracef("ox.fs.PassThroughFS.read.error", "Read of {} failed: {}", path, f.what());
 | 
							oxTracef("ox.fs.PassThroughFS.read.error", "Read of {} failed: {}", path, f.what());
 | 
				
			||||||
		return OxError(2);
 | 
							return ox::Error(2);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error PassThroughFS::readFileInode(uint64_t, void*, std::size_t) noexcept {
 | 
					Error PassThroughFS::readFileInode(uint64_t, void*, std::size_t) noexcept {
 | 
				
			||||||
	// unsupported
 | 
						// unsupported
 | 
				
			||||||
	return OxError(1, "readFileInode(uint64_t, void*, std::size_t) is not supported by PassThroughFS");
 | 
						return ox::Error(1, "readFileInode(uint64_t, void*, std::size_t) is not supported by PassThroughFS");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Error PassThroughFS::readFilePathRange(
 | 
				
			||||||
 | 
						StringViewCR path, size_t const readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept {
 | 
				
			||||||
 | 
						try {
 | 
				
			||||||
 | 
							std::ifstream file(m_path / stripSlash(path), std::ios::binary | std::ios::ate);
 | 
				
			||||||
 | 
							auto const size = static_cast<size_t>(file.tellg());
 | 
				
			||||||
 | 
							readSize = ox::min(readSize, size);
 | 
				
			||||||
 | 
							file.seekg(static_cast<off_t>(readStart), std::ios::beg);
 | 
				
			||||||
 | 
							if (readSize > *buffSize) {
 | 
				
			||||||
 | 
								oxTracef("ox.fs.PassThroughFS.read.error", "Read failed: Buffer too small: {}", path);
 | 
				
			||||||
 | 
								return ox::Error{1};
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							file.read(static_cast<char*>(buffer), static_cast<std::streamsize>(readSize));
 | 
				
			||||||
 | 
							return {};
 | 
				
			||||||
 | 
						} catch (std::fstream::failure const &f) {
 | 
				
			||||||
 | 
							oxTracef("ox.fs.PassThroughFS.read.error", "Read of {} failed: {}", path, f.what());
 | 
				
			||||||
 | 
							return ox::Error{2};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error PassThroughFS::readFileInodeRange(uint64_t, std::size_t, std::size_t, void*, std::size_t*) noexcept {
 | 
					Error PassThroughFS::readFileInodeRange(uint64_t, std::size_t, std::size_t, void*, std::size_t*) noexcept {
 | 
				
			||||||
	// unsupported
 | 
						// unsupported
 | 
				
			||||||
	return OxError(1, "read(uint64_t, std::size_t, std::size_t, void*, std::size_t*) is not supported by PassThroughFS");
 | 
						return ox::Error(1, "read(uint64_t, std::size_t, std::size_t, void*, std::size_t*) is not supported by PassThroughFS");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error PassThroughFS::writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType) noexcept {
 | 
					Error PassThroughFS::removePath(StringViewCR path, bool const recursive) noexcept {
 | 
				
			||||||
 | 
						if (recursive) {
 | 
				
			||||||
 | 
							return ox::Error{std::filesystem::remove_all(m_path / stripSlash(path)) == 0};
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return ox::Error{!std::filesystem::remove(m_path / stripSlash(path))};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Error PassThroughFS::writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType) noexcept {
 | 
				
			||||||
	const auto p = (m_path / stripSlash(path));
 | 
						const auto p = (m_path / stripSlash(path));
 | 
				
			||||||
	try {
 | 
						try {
 | 
				
			||||||
		std::ofstream f(p, std::ios::binary);
 | 
							std::ofstream f(p, std::ios::binary);
 | 
				
			||||||
		f.write(static_cast<const char*>(buffer), static_cast<std::streamsize>(size));
 | 
							f.write(static_cast<const char*>(buffer), static_cast<std::streamsize>(size));
 | 
				
			||||||
	} catch (const std::fstream::failure &f) {
 | 
						} catch (const std::fstream::failure &f) {
 | 
				
			||||||
		oxTracef("ox.fs.PassThroughFS.read.error", "Write of {} failed: {}", path, f.what());
 | 
							oxTracef("ox.fs.PassThroughFS.read.error", "Write of {} failed: {}", path, f.what());
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error PassThroughFS::writeFileInode(uint64_t, const void*, uint64_t, FileType) noexcept {
 | 
					Error PassThroughFS::writeFileInode(uint64_t, const void*, uint64_t, FileType) noexcept {
 | 
				
			||||||
	// unsupported
 | 
						// unsupported
 | 
				
			||||||
	return OxError(1, "writeFileInode(uint64_t, void*, uint64_t, uint8_t) is not supported by PassThroughFS");
 | 
						return ox::Error(1, "writeFileInode(uint64_t, void*, uint64_t, uint8_t) is not supported by PassThroughFS");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::string_view PassThroughFS::stripSlash(StringView path) noexcept {
 | 
					std::string_view PassThroughFS::stripSlash(StringView path) noexcept {
 | 
				
			||||||
	const auto pathLen = ox::strlen(path);
 | 
						for (auto i = 0u; i < path.size() && path[0] == '/'; i++) {
 | 
				
			||||||
	for (auto i = 0u; i < pathLen && path[0] == '/'; i++) {
 | 
					 | 
				
			||||||
		path = substr(path, 1);
 | 
							path = substr(path, 1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return {path.data(), path.bytes()};
 | 
						return {path.data(), path.bytes()};
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										33
									
								
								deps/ox/src/ox/fs/filesystem/passthroughfs.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								deps/ox/src/ox/fs/filesystem/passthroughfs.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -29,29 +29,27 @@ class PassThroughFS: public FileSystem {
 | 
				
			|||||||
		std::filesystem::path m_path;
 | 
							std::filesystem::path m_path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
		explicit PassThroughFS(CRStringView dirPath);
 | 
							explicit PassThroughFS(StringViewCR dirPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		~PassThroughFS() noexcept override;
 | 
							~PassThroughFS() noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		String basePath() const noexcept;
 | 
							String basePath() const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error mkdir(CRStringView path, bool recursive) noexcept override;
 | 
							Error mkdir(StringViewCR path, bool recursive) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error move(CRStringView src, CRStringView dest) noexcept override;
 | 
							Error move(StringViewCR src, StringViewCR dest) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<Vector<String>> ls(CRStringView dir) const noexcept override;
 | 
							Result<Vector<String>> ls(StringViewCR dir) const noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename F>
 | 
							template<typename F>
 | 
				
			||||||
		Error ls(CRStringView dir, F cb) const noexcept;
 | 
							Error ls(StringViewCR dir, F cb) const noexcept;
 | 
				
			||||||
 | 
					 | 
				
			||||||
		Error remove(CRStringView path, bool recursive) noexcept override;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error resize(uint64_t size, void *buffer) noexcept override;
 | 
							Error resize(uint64_t size, void *buffer) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<FileStat> statInode(uint64_t inode) const noexcept override;
 | 
							Result<FileStat> statInode(uint64_t inode) const noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<FileStat> statPath(CRStringView path) const noexcept override;
 | 
							Result<FileStat> statPath(StringViewCR path) const noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		uint64_t spaceNeeded(uint64_t size) const noexcept override;
 | 
							uint64_t spaceNeeded(uint64_t size) const noexcept override;
 | 
				
			||||||
@@ -69,13 +67,18 @@ class PassThroughFS: public FileSystem {
 | 
				
			|||||||
		bool valid() const noexcept override;
 | 
							bool valid() const noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected:
 | 
						protected:
 | 
				
			||||||
		Error readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept override;
 | 
							Error readFilePath(StringViewCR path, void *buffer, std::size_t buffSize) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept override;
 | 
							Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Error readFilePathRange(
 | 
				
			||||||
 | 
								StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override;
 | 
							Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept override;
 | 
							Error removePath(StringViewCR path, bool recursive) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Error writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept override;
 | 
							Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -89,14 +92,14 @@ class PassThroughFS: public FileSystem {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename F>
 | 
					template<typename F>
 | 
				
			||||||
Error PassThroughFS::ls(CRStringView dir, F cb) const noexcept {
 | 
					Error PassThroughFS::ls(StringViewCR dir, F cb) const noexcept {
 | 
				
			||||||
	std::error_code ec;
 | 
						std::error_code ec;
 | 
				
			||||||
	const auto di = std::filesystem::directory_iterator(m_path / stripSlash(dir), ec);
 | 
						const auto di = std::filesystem::directory_iterator(m_path / stripSlash(dir), ec);
 | 
				
			||||||
	oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: ls failed"));
 | 
						OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: ls failed"));
 | 
				
			||||||
	for (auto &p : di) {
 | 
						for (auto &p : di) {
 | 
				
			||||||
		oxReturnError(cb(p.path().filename().c_str(), 0));
 | 
							OX_RETURN_ERROR(cb(p.path().filename().c_str(), 0));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										36
									
								
								deps/ox/src/ox/fs/filesystem/pathiterator.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								deps/ox/src/ox/fs/filesystem/pathiterator.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -11,6 +11,8 @@
 | 
				
			|||||||
#include <ox/std/trace.hpp>
 | 
					#include <ox/std/trace.hpp>
 | 
				
			||||||
#include "pathiterator.hpp"
 | 
					#include "pathiterator.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ox {
 | 
					namespace ox {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PathIterator::PathIterator(const char *path, std::size_t maxSize, std::size_t iterator) {
 | 
					PathIterator::PathIterator(const char *path, std::size_t maxSize, std::size_t iterator) {
 | 
				
			||||||
@@ -22,7 +24,7 @@ PathIterator::PathIterator(const char *path, std::size_t maxSize, std::size_t it
 | 
				
			|||||||
PathIterator::PathIterator(const char *path): PathIterator(path, ox::strlen(path)) {
 | 
					PathIterator::PathIterator(const char *path): PathIterator(path, ox::strlen(path)) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PathIterator::PathIterator(CRStringView path): PathIterator(path.data(), path.bytes()) {
 | 
					PathIterator::PathIterator(StringViewCR path): PathIterator(path.data(), path.bytes()) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -30,13 +32,13 @@ PathIterator::PathIterator(CRStringView path): PathIterator(path.data(), path.by
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
Error PathIterator::dirPath(char *out, std::size_t outSize) {
 | 
					Error PathIterator::dirPath(char *out, std::size_t outSize) {
 | 
				
			||||||
	const auto idx = ox::lastIndexOf(m_path, '/', m_maxSize);
 | 
						const auto idx = ox::lastIndexOf(m_path, '/', m_maxSize);
 | 
				
			||||||
	const auto size = static_cast<std::size_t>(idx + 1);
 | 
						const auto size = static_cast<std::size_t>(idx) + 1;
 | 
				
			||||||
	if (idx >= 0 && size < outSize) {
 | 
						if (idx >= 0 && size < outSize) {
 | 
				
			||||||
		ox::memcpy(out, m_path, size);
 | 
							ox::memcpy(out, m_path, size);
 | 
				
			||||||
		out[size] = 0;
 | 
							out[size] = 0;
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -45,11 +47,11 @@ Error PathIterator::get(StringView &fileName) {
 | 
				
			|||||||
	std::size_t size = 0;
 | 
						std::size_t size = 0;
 | 
				
			||||||
	if (m_iterator >= m_maxSize) {
 | 
						if (m_iterator >= m_maxSize) {
 | 
				
			||||||
		oxTracef("ox.fs.PathIterator.get", "m_iterator ({}) >= m_maxSize ({})", m_iterator, m_maxSize);
 | 
							oxTracef("ox.fs.PathIterator.get", "m_iterator ({}) >= m_maxSize ({})", m_iterator, m_maxSize);
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!ox::strlen(&m_path[m_iterator])) {
 | 
						if (!ox::strlen(&m_path[m_iterator])) {
 | 
				
			||||||
		oxTrace("ox.fs.PathIterator.get", "!ox::strlen(&m_path[m_iterator])");
 | 
							oxTrace("ox.fs.PathIterator.get", "!ox::strlen(&m_path[m_iterator])");
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto start = m_iterator;
 | 
						auto start = m_iterator;
 | 
				
			||||||
	if (m_path[start] == '/') {
 | 
						if (m_path[start] == '/') {
 | 
				
			||||||
@@ -65,14 +67,14 @@ Error PathIterator::get(StringView &fileName) {
 | 
				
			|||||||
	size = end - start;
 | 
						size = end - start;
 | 
				
			||||||
	// cannot fit the output in the output parameter
 | 
						// cannot fit the output in the output parameter
 | 
				
			||||||
	if (size >= MaxFileNameLength || size == 0) {
 | 
						if (size >= MaxFileNameLength || size == 0) {
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fileName = ox::substr(m_path, start, start + size);
 | 
						fileName = ox::substr(m_path, start, start + size);
 | 
				
			||||||
	// truncate trailing /
 | 
						// truncate trailing /
 | 
				
			||||||
	if (size && fileName[size - 1] == '/') {
 | 
						if (size && fileName[size - 1] == '/') {
 | 
				
			||||||
		fileName = ox::substr(m_path, start, start + size - 1);
 | 
							fileName = ox::substr(m_path, start, start + size - 1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxAssert(fileName[fileName.len()-1] != '/', "name ends in /");
 | 
						oxAssert(fileName[fileName.size()-1] != '/', "name ends in /");
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -81,9 +83,9 @@ Error PathIterator::get(StringView &fileName) {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
Error PathIterator::next(StringView &fileName) {
 | 
					Error PathIterator::next(StringView &fileName) {
 | 
				
			||||||
	std::size_t size = 0;
 | 
						std::size_t size = 0;
 | 
				
			||||||
	auto retval = OxError(1);
 | 
						auto retval = ox::Error(1);
 | 
				
			||||||
	if (m_iterator < m_maxSize && ox::strlen(&m_path[m_iterator])) {
 | 
						if (m_iterator < m_maxSize && ox::strlen(&m_path[m_iterator])) {
 | 
				
			||||||
		retval = OxError(0);
 | 
							retval = {};
 | 
				
			||||||
		if (m_path[m_iterator] == '/') {
 | 
							if (m_path[m_iterator] == '/') {
 | 
				
			||||||
			m_iterator++;
 | 
								m_iterator++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -98,25 +100,25 @@ Error PathIterator::next(StringView &fileName) {
 | 
				
			|||||||
		size = end - start;
 | 
							size = end - start;
 | 
				
			||||||
		// cannot fit the output in the output parameter
 | 
							// cannot fit the output in the output parameter
 | 
				
			||||||
		if (size >= MaxFileNameLength) {
 | 
							if (size >= MaxFileNameLength) {
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fileName = ox::substr(m_path, start, start + size);
 | 
							fileName = ox::substr(m_path, start, start + size);
 | 
				
			||||||
		// truncate trailing /
 | 
							// truncate trailing /
 | 
				
			||||||
		while (fileName.len() && fileName[fileName.len() - 1] == '/') {
 | 
							while (fileName.size() && fileName[fileName.size() - 1] == '/') {
 | 
				
			||||||
			fileName = ox::substr(m_path, start, start + size);
 | 
								fileName = ox::substr(m_path, start, start + size);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		m_iterator += size;
 | 
							m_iterator += size;
 | 
				
			||||||
		oxAssert(fileName.len() == 0 || fileName[fileName.len()-1] != '/', "name ends in /");
 | 
							oxAssert(fileName.size() == 0 || fileName[fileName.size()-1] != '/', "name ends in /");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return retval;
 | 
						return retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<std::size_t> PathIterator::nextSize() const {
 | 
					Result<std::size_t> PathIterator::nextSize() const {
 | 
				
			||||||
	std::size_t size = 0;
 | 
						std::size_t size = 0;
 | 
				
			||||||
	auto retval = OxError(1);
 | 
						auto retval = ox::Error(1);
 | 
				
			||||||
	auto it = m_iterator;
 | 
						auto it = m_iterator;
 | 
				
			||||||
	if (it < m_maxSize && ox::strlen(&m_path[it])) {
 | 
						if (it < m_maxSize && ox::strlen(&m_path[it])) {
 | 
				
			||||||
		retval = OxError(0);
 | 
							retval = {};
 | 
				
			||||||
		if (m_path[it] == '/') {
 | 
							if (m_path[it] == '/') {
 | 
				
			||||||
			it++;
 | 
								it++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -183,3 +185,5 @@ const char *PathIterator::fullPath() const {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_CLANG_NOWARN_END
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -25,7 +25,7 @@ class PathIterator {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		PathIterator(const char *path);
 | 
							PathIterator(const char *path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		PathIterator(CRStringView path);
 | 
							PathIterator(StringViewCR path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error dirPath(char *pathOut, std::size_t pathOutSize);
 | 
							Error dirPath(char *pathOut, std::size_t pathOutSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/fs/filesystem/types.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/fs/filesystem/types.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/fs/fs.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/fs/fs.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										34
									
								
								deps/ox/src/ox/fs/ptrarith/nodebuffer.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								deps/ox/src/ox/fs/ptrarith/nodebuffer.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -13,6 +13,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "ptr.hpp"
 | 
					#include "ptr.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ox::ptrarith {
 | 
					namespace ox::ptrarith {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t, typename Item>
 | 
					template<typename size_t, typename Item>
 | 
				
			||||||
@@ -282,14 +284,14 @@ Result<typename NodeBuffer<size_t, Item>::ItemPtr> NodeBuffer<size_t, Item>::mal
 | 
				
			|||||||
				addr = m_header.firstItem;
 | 
									addr = m_header.firstItem;
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "NodeBuffer is in invalid state.");
 | 
									oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "NodeBuffer is in invalid state.");
 | 
				
			||||||
				return OxError(1, "NodeBuffer is in invalid state.");
 | 
									return ox::Error(1, "NodeBuffer is in invalid state.");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		oxTracef("ox.ptrarith.NodeBuffer.malloc", "buffer size: {}; addr: {}; fullSize: {}", m_header.size.get(), addr, fullSize);
 | 
							oxTracef("ox.ptrarith.NodeBuffer.malloc", "buffer size: {}; addr: {}; fullSize: {}", m_header.size.get(), addr, fullSize);
 | 
				
			||||||
		auto out = ItemPtr(this, m_header.size, addr, fullSize);
 | 
							auto out = ItemPtr(this, m_header.size, addr, fullSize);
 | 
				
			||||||
		if (!out.valid()) {
 | 
							if (!out.valid()) {
 | 
				
			||||||
			oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "Unknown");
 | 
								oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "Unknown");
 | 
				
			||||||
			return OxError(1, "NodeBuffer::malloc: unknown failure");
 | 
								return ox::Error(1, "NodeBuffer::malloc: unknown failure");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ox::memset(out, 0, fullSize);
 | 
							ox::memset(out, 0, fullSize);
 | 
				
			||||||
		new (out) Item;
 | 
							new (out) Item;
 | 
				
			||||||
@@ -302,7 +304,7 @@ Result<typename NodeBuffer<size_t, Item>::ItemPtr> NodeBuffer<size_t, Item>::mal
 | 
				
			|||||||
			first->prev = out.offset();
 | 
								first->prev = out.offset();
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "NodeBuffer malloc failed due to invalid first element pointer.");
 | 
								oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "NodeBuffer malloc failed due to invalid first element pointer.");
 | 
				
			||||||
			return OxError(1, "NodeBuffer malloc failed due to invalid first element pointer.");
 | 
								return ox::Error(1, "NodeBuffer malloc failed due to invalid first element pointer.");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (oldLast.valid()) {
 | 
							if (oldLast.valid()) {
 | 
				
			||||||
@@ -312,7 +314,7 @@ Result<typename NodeBuffer<size_t, Item>::ItemPtr> NodeBuffer<size_t, Item>::mal
 | 
				
			|||||||
			if (out.offset() != first.offset()) {
 | 
								if (out.offset() != first.offset()) {
 | 
				
			||||||
				// if this is not the first allocation, there should be an oldLast
 | 
									// if this is not the first allocation, there should be an oldLast
 | 
				
			||||||
				oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "NodeBuffer malloc failed due to invalid last element pointer.");
 | 
									oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "NodeBuffer malloc failed due to invalid last element pointer.");
 | 
				
			||||||
				return OxError(1, "NodeBuffer malloc failed due to invalid last element pointer.");
 | 
									return ox::Error(1, "NodeBuffer malloc failed due to invalid last element pointer.");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			out->prev = out.offset();
 | 
								out->prev = out.offset();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -321,7 +323,7 @@ Result<typename NodeBuffer<size_t, Item>::ItemPtr> NodeBuffer<size_t, Item>::mal
 | 
				
			|||||||
		return out;
 | 
							return out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxTracef("ox.ptrarith.NodeBuffer.malloc.fail", "Insufficient space: {} needed, {} available", fullSize, available());
 | 
						oxTracef("ox.ptrarith.NodeBuffer.malloc.fail", "Insufficient space: {} needed, {} available", fullSize, available());
 | 
				
			||||||
	return OxError(1);
 | 
						return ox::Error(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t, typename Item>
 | 
					template<typename size_t, typename Item>
 | 
				
			||||||
@@ -344,15 +346,15 @@ Error NodeBuffer<size_t, Item>::free(ItemPtr item) noexcept {
 | 
				
			|||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (!prev.valid()) {
 | 
							if (!prev.valid()) {
 | 
				
			||||||
			oxTracef("ox.ptrarith.NodeBuffer.free.fail", "NodeBuffer free failed due to invalid prev element pointer: {}", prev.offset());
 | 
								oxTracef("ox.ptrarith.NodeBuffer.free.fail", "NodeBuffer free failed due to invalid prev element pointer: {}", prev.offset());
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (!next.valid()) {
 | 
							if (!next.valid()) {
 | 
				
			||||||
			oxTracef("ox.ptrarith.NodeBuffer.free.fail", "NodeBuffer free failed due to invalid next element pointer: {}", next.offset());
 | 
								oxTracef("ox.ptrarith.NodeBuffer.free.fail", "NodeBuffer free failed due to invalid next element pointer: {}", next.offset());
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	m_header.bytesUsed -= item.size();
 | 
						m_header.bytesUsed -= item.size();
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t, typename Item>
 | 
					template<typename size_t, typename Item>
 | 
				
			||||||
@@ -363,12 +365,12 @@ Error NodeBuffer<size_t, Item>::setSize(std::size_t size) noexcept {
 | 
				
			|||||||
	oxTracef("ox.ptrarith.NodeBuffer.setSize", "end: {}", end);
 | 
						oxTracef("ox.ptrarith.NodeBuffer.setSize", "end: {}", end);
 | 
				
			||||||
	if (end > size) {
 | 
						if (end > size) {
 | 
				
			||||||
		// resizing to less than buffer size
 | 
							// resizing to less than buffer size
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		m_header.size = static_cast<size_t>(size);
 | 
							m_header.size = static_cast<size_t>(size);
 | 
				
			||||||
		auto data = reinterpret_cast<uint8_t*>(this) + end;
 | 
							auto data = reinterpret_cast<uint8_t*>(this) + end;
 | 
				
			||||||
		ox::memset(data, 0, size - end);
 | 
							ox::memset(data, 0, size - end);
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -399,14 +401,14 @@ Error NodeBuffer<size_t, Item>::compact(F cb) noexcept {
 | 
				
			|||||||
	auto dest = ptr(sizeof(*this));
 | 
						auto dest = ptr(sizeof(*this));
 | 
				
			||||||
	while (dest.offset() <= src.offset()) {
 | 
						while (dest.offset() <= src.offset()) {
 | 
				
			||||||
		if (!src.valid()) {
 | 
							if (!src.valid()) {
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (!dest.valid()) {
 | 
							if (!dest.valid()) {
 | 
				
			||||||
			return OxError(2);
 | 
								return ox::Error(2);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// move node
 | 
							// move node
 | 
				
			||||||
		ox::memcpy(dest, src, src->fullSize());
 | 
							ox::memcpy(dest, src, src->fullSize());
 | 
				
			||||||
		oxReturnError(cb(src, dest));
 | 
							OX_RETURN_ERROR(cb(src, dest));
 | 
				
			||||||
		// update surrounding nodes
 | 
							// update surrounding nodes
 | 
				
			||||||
		auto prev = ptr(dest->prev);
 | 
							auto prev = ptr(dest->prev);
 | 
				
			||||||
		if (prev.valid()) {
 | 
							if (prev.valid()) {
 | 
				
			||||||
@@ -420,7 +422,7 @@ Error NodeBuffer<size_t, Item>::compact(F cb) noexcept {
 | 
				
			|||||||
		src = ptr(dest->next);
 | 
							src = ptr(dest->next);
 | 
				
			||||||
		dest = uninitializedPtr(dest.offset() + dest->fullSize());
 | 
							dest = uninitializedPtr(dest.offset() + dest->fullSize());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename size_t, typename Item>
 | 
					template<typename size_t, typename Item>
 | 
				
			||||||
@@ -449,3 +451,5 @@ struct OX_PACKED Item {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_CLANG_NOWARN_END
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								deps/ox/src/ox/fs/ptrarith/ptr.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								deps/ox/src/ox/fs/ptrarith/ptr.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -10,6 +10,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <ox/std/std.hpp>
 | 
					#include <ox/std/std.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ox::ptrarith {
 | 
					namespace ox::ptrarith {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T, typename size_t, size_t minOffset = 1>
 | 
					template<typename T, typename size_t, size_t minOffset = 1>
 | 
				
			||||||
@@ -252,7 +254,9 @@ constexpr Result<Ptr<T, size_t, minOffset>> Ptr<T, size_t, minOffset>::validate(
 | 
				
			|||||||
	 if (valid()) {
 | 
						 if (valid()) {
 | 
				
			||||||
	 	return *this;
 | 
						 	return *this;
 | 
				
			||||||
	 }
 | 
						 }
 | 
				
			||||||
	 return OxError(1);
 | 
						 return ox::Error(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_CLANG_NOWARN_END
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										51
									
								
								deps/ox/src/ox/fs/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										51
									
								
								deps/ox/src/ox/fs/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -52,19 +52,19 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
 | 
				
			|||||||
				oxAssert(buffer->free(a1), "Free failed.");
 | 
									oxAssert(buffer->free(a1), "Free failed.");
 | 
				
			||||||
				oxAssert(buffer->free(a2), "Free failed.");
 | 
									oxAssert(buffer->free(a2), "Free failed.");
 | 
				
			||||||
				oxAssert(buffer->setSize(buffer->size() - buffer->available()), "Resize failed.");
 | 
									oxAssert(buffer->setSize(buffer->size() - buffer->available()), "Resize failed.");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"PathIterator::next1",
 | 
								"PathIterator::next1",
 | 
				
			||||||
			[](ox::StringView) {
 | 
								[](ox::StringView) {
 | 
				
			||||||
				auto constexpr path = ox::StringLiteral("/usr/share/charset.gbag");
 | 
									auto constexpr path = ox::StringLiteral("/usr/share/charset.gbag");
 | 
				
			||||||
				ox::PathIterator it(path.c_str(), path.len());
 | 
									ox::PathIterator it(path.c_str(), path.size());
 | 
				
			||||||
				ox::StringView buff;
 | 
									ox::StringView buff;
 | 
				
			||||||
				oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next");
 | 
									oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next");
 | 
				
			||||||
				oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next");
 | 
									oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next");
 | 
				
			||||||
				oxAssert(it.next(buff) == 0 && buff == "charset.gbag", "PathIterator shows wrong next");
 | 
									oxAssert(it.next(buff) == 0 && buff == "charset.gbag", "PathIterator shows wrong next");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -77,17 +77,17 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
 | 
				
			|||||||
				oxExpect(buff, "usr");
 | 
									oxExpect(buff, "usr");
 | 
				
			||||||
				oxAssert(it.next(buff), "PathIterator::next returned error");
 | 
									oxAssert(it.next(buff), "PathIterator::next returned error");
 | 
				
			||||||
				oxExpect(buff, "share");
 | 
									oxExpect(buff, "share");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"PathIterator::next3",
 | 
								"PathIterator::next3",
 | 
				
			||||||
			[](ox::StringView) {
 | 
								[](ox::StringView) {
 | 
				
			||||||
				auto const path = ox::String("/");
 | 
									auto const path = ox::String("/");
 | 
				
			||||||
				ox::PathIterator it(path.c_str(), path.len());
 | 
									ox::PathIterator it(path.c_str(), path.size());
 | 
				
			||||||
				ox::StringView buff;
 | 
									ox::StringView buff;
 | 
				
			||||||
				oxAssert(it.next(buff) == 0 && buff == "\0", "PathIterator shows wrong next");
 | 
									oxAssert(it.next(buff) == 0 && buff == "\0", "PathIterator shows wrong next");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -99,38 +99,42 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
 | 
				
			|||||||
				oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next");
 | 
									oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next");
 | 
				
			||||||
				oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next");
 | 
									oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next");
 | 
				
			||||||
				oxAssert(it.next(buff) == 0 && buff == "charset.gbag", "PathIterator shows wrong next");
 | 
									oxAssert(it.next(buff) == 0 && buff == "charset.gbag", "PathIterator shows wrong next");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"PathIterator::next5",
 | 
								"PathIterator::next5",
 | 
				
			||||||
			[](ox::StringView) {
 | 
								[](ox::StringView) {
 | 
				
			||||||
				auto const path = ox::String("usr/share/");
 | 
									auto const path = ox::String("usr/share/");
 | 
				
			||||||
				ox::PathIterator it(path.c_str(), path.len());
 | 
									ox::PathIterator it(path.c_str(), path.size());
 | 
				
			||||||
				ox::StringView buff;
 | 
									ox::StringView buff;
 | 
				
			||||||
				oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next");
 | 
									oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next");
 | 
				
			||||||
				oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next");
 | 
									oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"PathIterator::dirPath",
 | 
								"PathIterator::dirPath",
 | 
				
			||||||
			[] (ox::StringView) {
 | 
								[] (ox::StringView) {
 | 
				
			||||||
				auto constexpr path = ox::StringLiteral("/usr/share/charset.gbag");
 | 
									auto constexpr path = ox::StringLiteral("/usr/share/charset.gbag");
 | 
				
			||||||
				ox::PathIterator it(path.c_str(), path.len());
 | 
									ox::PathIterator it(path.c_str(), path.size());
 | 
				
			||||||
				auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
 | 
									auto buff = static_cast<char*>(ox_alloca(path.size() + 1));
 | 
				
			||||||
				oxAssert(it.dirPath(buff, path.len()) == 0 && ox::strcmp(buff, "/usr/share/") == 0, "PathIterator shows incorrect dir path");
 | 
									OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
				return OxError(0);
 | 
									oxAssert(it.dirPath(buff, path.size()) == 0 && ox::strcmp(buff, "/usr/share/") == 0, "PathIterator shows incorrect dir path");
 | 
				
			||||||
 | 
									OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"PathIterator::hasNext",
 | 
								"PathIterator::hasNext",
 | 
				
			||||||
			[](ox::StringView) {
 | 
								[](ox::StringView) {
 | 
				
			||||||
				const auto path = "/file1";
 | 
									const auto path = "/file1";
 | 
				
			||||||
 | 
									OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
				ox::PathIterator it(path, ox::strlen(path));
 | 
									ox::PathIterator it(path, ox::strlen(path));
 | 
				
			||||||
 | 
									OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
				oxAssert(it.hasNext(), "PathIterator shows incorrect hasNext");
 | 
									oxAssert(it.hasNext(), "PathIterator shows incorrect hasNext");
 | 
				
			||||||
				oxAssert(!it.next().hasNext(), "PathIterator shows incorrect hasNext");
 | 
									oxAssert(!it.next().hasNext(), "PathIterator shows incorrect hasNext");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -142,7 +146,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				auto subPtr = p.subPtr<uint64_t>(50);
 | 
									auto subPtr = p.subPtr<uint64_t>(50);
 | 
				
			||||||
				oxAssert(subPtr.valid(), "Ptr::subPtr: Ptr subPtr is invalid.");
 | 
									oxAssert(subPtr.valid(), "Ptr::subPtr: Ptr subPtr is invalid.");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -155,7 +159,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
 | 
				
			|||||||
				auto first = list->firstItem();
 | 
									auto first = list->firstItem();
 | 
				
			||||||
				oxAssert(first.valid(), "NodeBuffer::insert: Could not access first item");
 | 
									oxAssert(first.valid(), "NodeBuffer::insert: Could not access first item");
 | 
				
			||||||
				oxAssert(first->size() == 50, "NodeBuffer::insert: First item size invalid");
 | 
									oxAssert(first->size() == 50, "NodeBuffer::insert: First item size invalid");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -163,9 +167,11 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
 | 
				
			|||||||
			[](ox::StringView) {
 | 
								[](ox::StringView) {
 | 
				
			||||||
				constexpr auto buffLen = 5000;
 | 
									constexpr auto buffLen = 5000;
 | 
				
			||||||
				constexpr auto str1 = "Hello, World!";
 | 
									constexpr auto str1 = "Hello, World!";
 | 
				
			||||||
 | 
									OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
				constexpr auto str1Len = ox::strlen(str1) + 1;
 | 
									constexpr auto str1Len = ox::strlen(str1) + 1;
 | 
				
			||||||
				constexpr auto str2 = "Hello, Moon!";
 | 
									constexpr auto str2 = "Hello, Moon!";
 | 
				
			||||||
				constexpr auto str2Len = ox::strlen(str2) + 1;
 | 
									constexpr auto str2Len = ox::strlen(str2) + 1;
 | 
				
			||||||
 | 
									OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
				auto list = new (ox_alloca(buffLen)) ox::ptrarith::NodeBuffer<uint32_t, ox::FileStoreItem<uint32_t>>(buffLen);
 | 
									auto list = new (ox_alloca(buffLen)) ox::ptrarith::NodeBuffer<uint32_t, ox::FileStoreItem<uint32_t>>(buffLen);
 | 
				
			||||||
				oxAssert(ox::FileStore32::format(list, buffLen), "FileStore::format failed.");
 | 
									oxAssert(ox::FileStore32::format(list, buffLen), "FileStore::format failed.");
 | 
				
			||||||
				ox::FileStore32 fileStore(list, buffLen);
 | 
									ox::FileStore32 fileStore(list, buffLen);
 | 
				
			||||||
@@ -176,7 +182,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
 | 
				
			|||||||
				size_t str1ReadSize = 0;
 | 
									size_t str1ReadSize = 0;
 | 
				
			||||||
				oxAssert(fileStore.read(4, reinterpret_cast<void*>(str1Read), str1Len, &str1ReadSize), "FileStore::read 1 failed.");
 | 
									oxAssert(fileStore.read(4, reinterpret_cast<void*>(str1Read), str1Len, &str1ReadSize), "FileStore::read 1 failed.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -203,7 +209,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
 | 
				
			|||||||
				oxTrace("ox.fs.test.Directory") << "write 3";
 | 
									oxTrace("ox.fs.test.Directory") << "write 3";
 | 
				
			||||||
				oxAssert(dir.write("/file2", 2), "Directory write of file2 failed");
 | 
									oxAssert(dir.write("/file2", 2), "Directory write of file2 failed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -220,19 +226,20 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
 | 
				
			|||||||
				oxAssert(fs.stat("/l1d1/l2d1/l3d1").error, "mkdir failed");
 | 
									oxAssert(fs.stat("/l1d1/l2d1/l3d1").error, "mkdir failed");
 | 
				
			||||||
				oxAssert(fs.mkdir("/l1d1/l2d2", true), "mkdir failed");
 | 
									oxAssert(fs.mkdir("/l1d1/l2d2", true), "mkdir failed");
 | 
				
			||||||
				oxAssert(fs.stat("/l1d1/l2d2").error, "mkdir failed");
 | 
									oxAssert(fs.stat("/l1d1/l2d2").error, "mkdir failed");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, const char **args) {
 | 
					int main(int argc, const char **argv) {
 | 
				
			||||||
	if (argc < 2) {
 | 
						if (argc < 2) {
 | 
				
			||||||
		oxError("Must specify test to run");
 | 
							oxError("Must specify test to run");
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						auto const args = ox::Span{argv, static_cast<size_t>(argc)};
 | 
				
			||||||
	ox::StringView const testName = args[1];
 | 
						ox::StringView const testName = args[1];
 | 
				
			||||||
	ox::StringView const testArg = args[2] ? args[2] : nullptr;
 | 
						ox::StringView const testArg = argc >= 3 ? args[2] : nullptr;
 | 
				
			||||||
	auto const func = tests.find(testName);
 | 
						auto const func = tests.find(testName);
 | 
				
			||||||
	if (func != tests.end()) {
 | 
						if (func != tests.end()) {
 | 
				
			||||||
		oxAssert(func->second(testArg), "Test returned Error");
 | 
							oxAssert(func->second(testArg), "Test returned Error");
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										47
									
								
								deps/ox/src/ox/fs/tool.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										47
									
								
								deps/ox/src/ox/fs/tool.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -20,7 +20,7 @@ static ox::Result<Buff> loadFsBuff(const char *path) noexcept {
 | 
				
			|||||||
	std::ifstream file(path, std::ios::binary | std::ios::ate);
 | 
						std::ifstream file(path, std::ios::binary | std::ios::ate);
 | 
				
			||||||
	if (!file.good()) {
 | 
						if (!file.good()) {
 | 
				
			||||||
		oxErrorf("Could not find OxFS file: {}", path);
 | 
							oxErrorf("Could not find OxFS file: {}", path);
 | 
				
			||||||
		return OxError(1, "Could not find OxFS file");
 | 
							return ox::Error(1, "Could not find OxFS file");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	try {
 | 
						try {
 | 
				
			||||||
		const auto size = static_cast<std::size_t>(file.tellg());
 | 
							const auto size = static_cast<std::size_t>(file.tellg());
 | 
				
			||||||
@@ -30,51 +30,54 @@ static ox::Result<Buff> loadFsBuff(const char *path) noexcept {
 | 
				
			|||||||
		return Buff{buff, size};
 | 
							return Buff{buff, size};
 | 
				
			||||||
	} catch (const std::ios_base::failure &e) {
 | 
						} catch (const std::ios_base::failure &e) {
 | 
				
			||||||
		oxErrorf("Could not read OxFS file: {}", e.what());
 | 
							oxErrorf("Could not read OxFS file: {}", e.what());
 | 
				
			||||||
		return OxError(2, "Could not read OxFS file");
 | 
							return ox::Error(2, "Could not read OxFS file");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ox::Result<ox::UniquePtr<ox::FileSystem>> loadFs(const char *path) noexcept {
 | 
					static ox::Result<ox::UniquePtr<ox::FileSystem>> loadFs(const char *path) noexcept {
 | 
				
			||||||
	oxRequire(buff, loadFsBuff(path));
 | 
						OX_REQUIRE(buff, loadFsBuff(path));
 | 
				
			||||||
	return {ox::make_unique<ox::FileSystem32>(buff.data, buff.size)};
 | 
						return {ox::make_unique<ox::FileSystem32>(buff.data, buff.size)};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ox::Error runLs(ox::FileSystem *fs, int argc, const char **argv) noexcept {
 | 
					static ox::Error runLs(ox::FileSystem *fs, ox::Span<const char*> args) noexcept {
 | 
				
			||||||
	if (argc < 2) {
 | 
						if (args.size() < 2) {
 | 
				
			||||||
		oxErr("Must provide a directory to ls\n");
 | 
							oxErr("Must provide a directory to ls\n");
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxRequire(files, fs->ls(argv[1]));
 | 
						OX_REQUIRE(files, fs->ls(args[1]));
 | 
				
			||||||
	for (const auto &file : files) {
 | 
						for (const auto &file : files) {
 | 
				
			||||||
		oxOutf("{}\n", file);
 | 
							oxOutf("{}\n", file);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ox::Error runRead(ox::FileSystem *fs, int argc, const char **argv) noexcept {
 | 
					static ox::Error runRead(ox::FileSystem *fs, ox::Span<const char*> args) noexcept {
 | 
				
			||||||
	if (argc < 2) {
 | 
						if (args.size() < 2) {
 | 
				
			||||||
		oxErr("Must provide a path to a file to read\n");
 | 
							oxErr("Must provide a path to a file to read\n");
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxRequire(buff, fs->read(ox::StringView(argv[1])));
 | 
						OX_REQUIRE(buff, fs->read(ox::StringView(args[1])));
 | 
				
			||||||
	fwrite(buff.data(), sizeof(decltype(buff)::value_type), buff.size(), stdout);
 | 
						OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
	return OxError(0);
 | 
						std::ignore = fwrite(buff.data(), sizeof(decltype(buff)::value_type), buff.size(), stdout);
 | 
				
			||||||
 | 
						OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ox::Error run(int argc, const char **argv) noexcept {
 | 
					static ox::Error run(int argc, const char **argv) noexcept {
 | 
				
			||||||
	if (argc < 3) {
 | 
						if (argc < 3) {
 | 
				
			||||||
		oxErr("OxFS file and subcommand arguments are required\n");
 | 
							oxErr("OxFS file and subcommand arguments are required\n");
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	const auto fsPath = argv[1];
 | 
						auto const args = ox::Span{argv, static_cast<size_t>(argc)};
 | 
				
			||||||
	ox::String subCmd(argv[2]);
 | 
						auto const fsPath = args[1];
 | 
				
			||||||
	oxRequire(fs, loadFs(fsPath));
 | 
						ox::String subCmd(args[2]);
 | 
				
			||||||
 | 
						OX_REQUIRE(fs, loadFs(fsPath));
 | 
				
			||||||
	if (subCmd == "ls") {
 | 
						if (subCmd == "ls") {
 | 
				
			||||||
		return runLs(fs.get(), argc - 2, argv + 2);
 | 
							return runLs(fs.get(), args + 2);
 | 
				
			||||||
	} else if (subCmd == "read") {
 | 
						} else if (subCmd == "read") {
 | 
				
			||||||
		return runRead(fs.get(), argc - 2, argv + 2);
 | 
							return runRead(fs.get(), args + 2);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1);
 | 
						return ox::Error(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, const char **argv) {
 | 
					int main(int argc, const char **argv) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								deps/ox/src/ox/logconn/circularbuff.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								deps/ox/src/ox/logconn/circularbuff.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -34,7 +34,7 @@ class CirculerBuffer {
 | 
				
			|||||||
		constexpr ox::Error put(char v) noexcept {
 | 
							constexpr ox::Error put(char v) noexcept {
 | 
				
			||||||
			return write(&v, 1);
 | 
								return write(&v, 1);
 | 
				
			||||||
			if (1 > avail()) {
 | 
								if (1 > avail()) {
 | 
				
			||||||
				return OxError(1, "Insufficient space in buffer");
 | 
									return ox::Error(1, "Insufficient space in buffer");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			m_buff[m_writePt] = v;
 | 
								m_buff[m_writePt] = v;
 | 
				
			||||||
			++m_writePt;
 | 
								++m_writePt;
 | 
				
			||||||
@@ -43,8 +43,9 @@ class CirculerBuffer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		constexpr ox::Error write(const char *buff, std::size_t sz) noexcept {
 | 
							constexpr ox::Error write(const char *buff, std::size_t sz) noexcept {
 | 
				
			||||||
			if (sz > avail()) {
 | 
								if (sz > avail()) {
 | 
				
			||||||
				return OxError(1, "Insufficient space in buffer");
 | 
									return ox::Error(1, "Insufficient space in buffer");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
			// write seg 1
 | 
								// write seg 1
 | 
				
			||||||
			const auto seg1Sz = ox::min(sz, m_buff.size() - m_writePt);
 | 
								const auto seg1Sz = ox::min(sz, m_buff.size() - m_writePt);
 | 
				
			||||||
			ox::listcpy(&m_buff[m_writePt], &buff[0], seg1Sz);
 | 
								ox::listcpy(&m_buff[m_writePt], &buff[0], seg1Sz);
 | 
				
			||||||
@@ -56,12 +57,13 @@ class CirculerBuffer {
 | 
				
			|||||||
				ox::listcpy(&m_buff[0], &buff[seg1Sz], seg2Sz);
 | 
									ox::listcpy(&m_buff[0], &buff[seg1Sz], seg2Sz);
 | 
				
			||||||
				oxAssert(m_buff[0] == buff[seg1Sz], "break");
 | 
									oxAssert(m_buff[0] == buff[seg1Sz], "break");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
			return {};
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		constexpr ox::Error seekp(std::size_t bytesFwd) noexcept {
 | 
							constexpr ox::Error seekp(std::size_t bytesFwd) noexcept {
 | 
				
			||||||
			if (bytesFwd > avail()) {
 | 
								if (bytesFwd > avail()) {
 | 
				
			||||||
				return OxError(1, "Insufficient space in buffer to seek that far ahead");
 | 
									return ox::Error(1, "Insufficient space in buffer to seek that far ahead");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			m_writePt += bytesFwd;
 | 
								m_writePt += bytesFwd;
 | 
				
			||||||
			if (m_writePt > m_buff.size()) {
 | 
								if (m_writePt > m_buff.size()) {
 | 
				
			||||||
@@ -71,7 +73,7 @@ class CirculerBuffer {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		constexpr ox::Error seekp(int, ios_base::seekdir) noexcept {
 | 
							constexpr ox::Error seekp(int, ios_base::seekdir) noexcept {
 | 
				
			||||||
			return OxError(1, "Unimplemented");
 | 
								return ox::Error(1, "Unimplemented");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
@@ -90,7 +92,9 @@ class CirculerBuffer {
 | 
				
			|||||||
				m_readPt -= m_buff.size();
 | 
									m_readPt -= m_buff.size();
 | 
				
			||||||
				// read seg 2
 | 
									// read seg 2
 | 
				
			||||||
				const auto seg2Sz = bytesRead - seg1Sz;
 | 
									const auto seg2Sz = bytesRead - seg1Sz;
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
				ox::listcpy(&out[seg1Sz], &m_buff[0], seg2Sz);
 | 
									ox::listcpy(&out[seg1Sz], &m_buff[0], seg2Sz);
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return bytesRead;
 | 
								return bytesRead;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								deps/ox/src/ox/logconn/def.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								deps/ox/src/ox/logconn/def.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -14,7 +14,7 @@
 | 
				
			|||||||
    { \
 | 
					    { \
 | 
				
			||||||
		const auto loggerErr = (loggerName).initConn(appName); \
 | 
							const auto loggerErr = (loggerName).initConn(appName); \
 | 
				
			||||||
		if (loggerErr) { \
 | 
							if (loggerErr) { \
 | 
				
			||||||
			oxErrf("Could not connect to logger: {} ({}:{})\n", toStr(loggerErr), loggerErr.file, loggerErr.line); \
 | 
								oxErrf("Could not connect to logger: {} ({}:{})\n", toStr(loggerErr), loggerErr.src.file_name(), loggerErr.src.line()); \
 | 
				
			||||||
		} else { \
 | 
							} else { \
 | 
				
			||||||
			ox::trace::setLogger(&(loggerName)); \
 | 
								ox::trace::setLogger(&(loggerName)); \
 | 
				
			||||||
		} \
 | 
							} \
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										39
									
								
								deps/ox/src/ox/logconn/logconn.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								deps/ox/src/ox/logconn/logconn.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -9,8 +9,8 @@
 | 
				
			|||||||
#ifdef OX_USE_STDLIB
 | 
					#ifdef OX_USE_STDLIB
 | 
				
			||||||
#include <cstdio>
 | 
					#include <cstdio>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <sys/types.h>
 | 
					 | 
				
			||||||
#ifndef _WIN32
 | 
					#ifndef _WIN32
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
#include <sys/socket.h>
 | 
					#include <sys/socket.h>
 | 
				
			||||||
#include <arpa/inet.h>
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
#include <netinet/in.h>
 | 
					#include <netinet/in.h>
 | 
				
			||||||
@@ -25,15 +25,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "logconn.hpp"
 | 
					#include "logconn.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <ox/std/bit.hpp>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ox {
 | 
					namespace ox {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					using Socket = SOCKET;
 | 
				
			||||||
 | 
					using LenType = int;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					using Socket = int;
 | 
				
			||||||
 | 
					using LenType = size_t;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace trace;
 | 
					using namespace trace;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void closeSock(auto s) noexcept {
 | 
					static void closeSock(auto s) noexcept {
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
	closesocket(s);
 | 
						closesocket(static_cast<Socket>(s));
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	close(s);
 | 
						close(s);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -51,13 +58,13 @@ LoggerConn::~LoggerConn() noexcept {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ox::Error LoggerConn::initConn(ox::CRStringView appName) noexcept {
 | 
					ox::Error LoggerConn::initConn(ox::StringViewCR appName) noexcept {
 | 
				
			||||||
	sockaddr_in addr{};
 | 
						sockaddr_in addr{};
 | 
				
			||||||
	addr.sin_family = AF_INET;
 | 
						addr.sin_family = AF_INET;
 | 
				
			||||||
	addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
 | 
						addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
 | 
				
			||||||
	addr.sin_port = htons(5590);
 | 
						addr.sin_port = htons(5590);
 | 
				
			||||||
	m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 | 
						m_socket = static_cast<int>(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
 | 
				
			||||||
	oxReturnError(OxError(static_cast<ox::ErrorCode>(connect(m_socket, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)))));
 | 
						OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(connect(static_cast<Socket>(m_socket), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)))));
 | 
				
			||||||
	return sendInit({.appName = ox::BasicString<128>(appName)});
 | 
						return sendInit({.appName = ox::BasicString<128>(appName)});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -65,10 +72,10 @@ ox::Error LoggerConn::send(const char *buff, std::size_t len) const noexcept {
 | 
				
			|||||||
	std::size_t totalSent = 0;
 | 
						std::size_t totalSent = 0;
 | 
				
			||||||
	while (totalSent < len) {
 | 
						while (totalSent < len) {
 | 
				
			||||||
		//std::fprintf(stdout, "Sending %lu/%lu bytes on socket %d\n", len, totalSent, m_socket);
 | 
							//std::fprintf(stdout, "Sending %lu/%lu bytes on socket %d\n", len, totalSent, m_socket);
 | 
				
			||||||
		const auto sent = ::send(m_socket, buff, len, 0);
 | 
							const auto sent = ::send(static_cast<Socket>(m_socket), buff, static_cast<LenType>(len), 0);
 | 
				
			||||||
		if (sent < 0) {
 | 
							if (sent < 0) {
 | 
				
			||||||
			std::fprintf(stderr, "Could not send msg\n");
 | 
								std::ignore = std::fprintf(stderr, "Could not send msg\n");
 | 
				
			||||||
			return OxError(1, "Could not send msg");
 | 
								return ox::Error(1, "Could not send msg");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		totalSent += static_cast<std::size_t>(sent);
 | 
							totalSent += static_cast<std::size_t>(sent);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -84,23 +91,29 @@ ox::Error LoggerConn::sendInit(const InitTraceMsg &msg) noexcept {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void LoggerConn::msgSend() noexcept {
 | 
					void LoggerConn::msgSend() noexcept {
 | 
				
			||||||
 | 
						try {
 | 
				
			||||||
		while (true) {
 | 
							while (true) {
 | 
				
			||||||
			std::unique_lock lk(m_waitMut);
 | 
								std::unique_lock lk(m_waitMut);
 | 
				
			||||||
			m_waitCond.wait(lk);
 | 
								m_waitCond.wait(lk);
 | 
				
			||||||
			if (!m_running) {
 | 
								if (!m_running) {
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		std::lock_guard buffLk(m_buffMut);
 | 
								std::lock_guard const buffLk(m_buffMut);
 | 
				
			||||||
			while (true) {
 | 
								while (true) {
 | 
				
			||||||
			ox::Array<char, ox::units::KB> tmp;
 | 
									Array<char, units::KB> tmp;
 | 
				
			||||||
				const auto read = m_buff.read(tmp.data(), tmp.size());
 | 
									const auto read = m_buff.read(tmp.data(), tmp.size());
 | 
				
			||||||
				if (!read) {
 | 
									if (!read) {
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									oxAssert(read <= tmp.size(), "logger trying to read too much data");
 | 
				
			||||||
				//std::printf("LoggerConn: sending %lu bytes\n", read);
 | 
									//std::printf("LoggerConn: sending %lu bytes\n", read);
 | 
				
			||||||
				std::ignore = send(tmp.data(), read);
 | 
									std::ignore = send(tmp.data(), read);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						} catch (std::exception const &e) {
 | 
				
			||||||
 | 
							oxErrf("Exception in logger thread: {}\n", e.what());
 | 
				
			||||||
 | 
							oxAssert(false, "logger thread exception");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								deps/ox/src/ox/logconn/logconn.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								deps/ox/src/ox/logconn/logconn.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -38,20 +38,20 @@ class LoggerConn: public trace::Logger {
 | 
				
			|||||||
		LoggerConn &operator=(const LoggerConn&) noexcept = delete;
 | 
							LoggerConn &operator=(const LoggerConn&) noexcept = delete;
 | 
				
			||||||
		ox::Error send(const trace::TraceMsg&) noexcept final;
 | 
							ox::Error send(const trace::TraceMsg&) noexcept final;
 | 
				
			||||||
		ox::Error sendInit(const trace::InitTraceMsg&) noexcept final;
 | 
							ox::Error sendInit(const trace::InitTraceMsg&) noexcept final;
 | 
				
			||||||
		ox::Error initConn(ox::CRStringView appName) noexcept;
 | 
							ox::Error initConn(ox::StringViewCR appName) noexcept;
 | 
				
			||||||
		ox::Error send(const char *buff, std::size_t len) const noexcept;
 | 
							ox::Error send(const char *buff, std::size_t len) const noexcept;
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		void msgSend() noexcept;
 | 
							void msgSend() noexcept;
 | 
				
			||||||
		ox::Error send(trace::MsgId msgId, const auto &msg) noexcept {
 | 
							ox::Error send(trace::MsgId msgId, const auto &msg) noexcept {
 | 
				
			||||||
			ox::Array<char, 10 * ox::units::KB> buff;
 | 
								ox::Array<char, 10 * ox::units::KB> buff;
 | 
				
			||||||
			std::size_t sz = 0;
 | 
								std::size_t sz = 0;
 | 
				
			||||||
			oxReturnError(ox::writeMC(&buff[0], buff.size(), msg, &sz));
 | 
								OX_RETURN_ERROR(ox::writeMC(&buff[0], buff.size(), msg, &sz));
 | 
				
			||||||
			//std::printf("sz: %lu\n", sz);
 | 
								//std::printf("sz: %lu\n", sz);
 | 
				
			||||||
			oxRequire(szBuff, serialize(static_cast<uint32_t>(sz)));
 | 
								OX_REQUIRE(szBuff, serialize(static_cast<uint32_t>(sz)));
 | 
				
			||||||
			std::unique_lock buffLk(m_buffMut);
 | 
								std::unique_lock buffLk(m_buffMut);
 | 
				
			||||||
			oxReturnError(m_buff.put(static_cast<char>(msgId)));
 | 
								OX_RETURN_ERROR(m_buff.put(static_cast<char>(msgId)));
 | 
				
			||||||
			oxReturnError(m_buff.write(szBuff.data(), szBuff.size()));
 | 
								OX_RETURN_ERROR(m_buff.write(szBuff.data(), szBuff.size()));
 | 
				
			||||||
			oxReturnError(m_buff.write(buff.data(), sz));
 | 
								OX_RETURN_ERROR(m_buff.write(buff.data(), sz));
 | 
				
			||||||
			buffLk.unlock();
 | 
								buffLk.unlock();
 | 
				
			||||||
			m_waitCond.notify_one();
 | 
								m_waitCond.notify_one();
 | 
				
			||||||
			return {};
 | 
								return {};
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/mc/err.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/mc/err.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										32
									
								
								deps/ox/src/ox/mc/intops.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								deps/ox/src/ox/mc/intops.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -57,7 +57,7 @@ static_assert(highestBit(uint64_t(1) << 31) == 31);
 | 
				
			|||||||
static_assert(highestBit(uint64_t(1) << 63) == 63);
 | 
					static_assert(highestBit(uint64_t(1) << 63) == 63);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct McInt {
 | 
					struct McInt {
 | 
				
			||||||
	uint8_t data[9] = {};
 | 
						ox::Array<uint8_t, 9> data{};
 | 
				
			||||||
	// length of integer in bytes
 | 
						// length of integer in bytes
 | 
				
			||||||
	std::size_t length = 0;
 | 
						std::size_t length = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -71,7 +71,9 @@ constexpr McInt encodeInteger(I pInput) noexcept {
 | 
				
			|||||||
	// move input to uint64_t to allow consistent bit manipulation, and to avoid
 | 
						// move input to uint64_t to allow consistent bit manipulation, and to avoid
 | 
				
			||||||
	// overflow concerns
 | 
						// overflow concerns
 | 
				
			||||||
	uint64_t val = 0;
 | 
						uint64_t val = 0;
 | 
				
			||||||
 | 
						OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
	ox::memcpy(&val, &input, sizeof(input));
 | 
						ox::memcpy(&val, &input, sizeof(input));
 | 
				
			||||||
 | 
						OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
	if (val) {
 | 
						if (val) {
 | 
				
			||||||
		// bits needed to represent number factoring in space possibly
 | 
							// bits needed to represent number factoring in space possibly
 | 
				
			||||||
		// needed for signed bit
 | 
							// needed for signed bit
 | 
				
			||||||
@@ -94,7 +96,9 @@ constexpr McInt encodeInteger(I pInput) noexcept {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		if (bytes == 9) {
 | 
							if (bytes == 9) {
 | 
				
			||||||
			out.data[0] = bytesIndicator;
 | 
								out.data[0] = bytesIndicator;
 | 
				
			||||||
 | 
								OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
			ox::memcpy(&out.data[1], &leVal, 8);
 | 
								ox::memcpy(&out.data[1], &leVal, 8);
 | 
				
			||||||
 | 
								OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
			if (inputNegative) {
 | 
								if (inputNegative) {
 | 
				
			||||||
				out.data[1] |= 0b1000'0000;
 | 
									out.data[1] |= 0b1000'0000;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -104,7 +108,9 @@ constexpr McInt encodeInteger(I pInput) noexcept {
 | 
				
			|||||||
			auto intermediate =
 | 
								auto intermediate =
 | 
				
			||||||
				static_cast<uint64_t>(leVal.raw() | (negBit << (valBits - 1))) << bytes |
 | 
									static_cast<uint64_t>(leVal.raw() | (negBit << (valBits - 1))) << bytes |
 | 
				
			||||||
				static_cast<uint64_t>(bytesIndicator);
 | 
									static_cast<uint64_t>(bytesIndicator);
 | 
				
			||||||
			ox::memcpy(out.data, &intermediate, sizeof(intermediate));
 | 
								OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
 | 
								ox::memcpy(&out.data[0], &intermediate, sizeof(intermediate));
 | 
				
			||||||
 | 
								OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		out.length = bytes;
 | 
							out.length = bytes;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -135,19 +141,19 @@ static_assert(countBytes(0b1111'1111) == 9);
 | 
				
			|||||||
template<typename I>
 | 
					template<typename I>
 | 
				
			||||||
constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noexcept {
 | 
					constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noexcept {
 | 
				
			||||||
	uint8_t firstByte = 0;
 | 
						uint8_t firstByte = 0;
 | 
				
			||||||
	oxReturnError(rdr.read(&firstByte, 1));
 | 
						OX_RETURN_ERROR(rdr.read(&firstByte, 1));
 | 
				
			||||||
	oxReturnError(rdr.seekg(-1, ox::ios_base::cur));
 | 
						OX_RETURN_ERROR(rdr.seekg(-1, ox::ios_base::cur));
 | 
				
			||||||
	const auto bytes = countBytes(firstByte);
 | 
						const auto bytes = countBytes(firstByte);
 | 
				
			||||||
	if (bytes == 9) {
 | 
						if (bytes == 9) {
 | 
				
			||||||
		*bytesRead = bytes;
 | 
							*bytesRead = bytes;
 | 
				
			||||||
		I out = 0;
 | 
							I out = 0;
 | 
				
			||||||
		oxReturnError(rdr.seekg(1, ox::ios_base::cur));
 | 
							OX_RETURN_ERROR(rdr.seekg(1, ox::ios_base::cur));
 | 
				
			||||||
		oxReturnError(rdr.read(&out, sizeof(I)));
 | 
							OX_RETURN_ERROR(rdr.read(&out, sizeof(I)));
 | 
				
			||||||
		return fromLittleEndian<I>(out);
 | 
							return fromLittleEndian<I>(out);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	*bytesRead = bytes;
 | 
						*bytesRead = bytes;
 | 
				
			||||||
	uint64_t decoded = 0;
 | 
						uint64_t decoded = 0;
 | 
				
			||||||
	oxReturnError(rdr.read(&decoded, bytes));
 | 
						OX_RETURN_ERROR(rdr.read(&decoded, bytes));
 | 
				
			||||||
	decoded >>= bytes;
 | 
						decoded >>= bytes;
 | 
				
			||||||
	// move sign bit
 | 
						// move sign bit
 | 
				
			||||||
	if constexpr(is_signed_v<I>) {
 | 
						if constexpr(is_signed_v<I>) {
 | 
				
			||||||
@@ -160,7 +166,9 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
 | 
				
			|||||||
			ox::Array<uint32_t, 2> d = {};
 | 
								ox::Array<uint32_t, 2> d = {};
 | 
				
			||||||
			//d[0] = decoded & 0xffff'ffff;
 | 
								//d[0] = decoded & 0xffff'ffff;
 | 
				
			||||||
			//d[1] = decoded >> 32;
 | 
								//d[1] = decoded >> 32;
 | 
				
			||||||
			 ox::memcpy(d.data(), &decoded, sizeof(decoded));
 | 
							 	OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
 | 
								ox::memcpy(&d[0], &decoded, sizeof(decoded));
 | 
				
			||||||
 | 
							 	OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
			auto bit = negBit;
 | 
								auto bit = negBit;
 | 
				
			||||||
			for (; bit < ox::min<std::size_t>(Bits<I>, 32); ++bit) {
 | 
								for (; bit < ox::min<std::size_t>(Bits<I>, 32); ++bit) {
 | 
				
			||||||
				d[0] |= 1 << bit;
 | 
									d[0] |= 1 << bit;
 | 
				
			||||||
@@ -175,7 +183,9 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
 | 
				
			|||||||
				d[0] = d[1];
 | 
									d[0] = d[1];
 | 
				
			||||||
				d[1] = d0Tmp;
 | 
									d[1] = d0Tmp;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			 ox::memcpy(&out, d.data(), sizeof(out));
 | 
							 	OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
 | 
								ox::memcpy(&out, &d[0], sizeof(out));
 | 
				
			||||||
 | 
								OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
			return out;
 | 
								return out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -185,7 +195,7 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
 | 
				
			|||||||
template<typename I>
 | 
					template<typename I>
 | 
				
			||||||
Result<I> decodeInteger(McInt m) noexcept {
 | 
					Result<I> decodeInteger(McInt m) noexcept {
 | 
				
			||||||
	std::size_t bytesRead{};
 | 
						std::size_t bytesRead{};
 | 
				
			||||||
	BufferReader br({reinterpret_cast<const char*>(m.data), 9});
 | 
						BufferReader br({reinterpret_cast<const char*>(m.data.data()), 9});
 | 
				
			||||||
	return decodeInteger<I>(br, &bytesRead);
 | 
						return decodeInteger<I>(br, &bytesRead);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/mc/mc.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/mc/mc.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/mc/presenceindicator.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/mc/presenceindicator.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								deps/ox/src/ox/mc/presenceindicator.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								deps/ox/src/ox/mc/presenceindicator.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -47,7 +47,7 @@ constexpr Result<bool> FieldBitmapReader<Reader>::get(std::size_t idx) const noe
 | 
				
			|||||||
	constexpr auto blockBits = sizeof(m_mapBlock);
 | 
						constexpr auto blockBits = sizeof(m_mapBlock);
 | 
				
			||||||
	auto const blockIdx = idx / blockBits;
 | 
						auto const blockIdx = idx / blockBits;
 | 
				
			||||||
	if (m_mapBlockIdx != blockIdx) [[unlikely]] {
 | 
						if (m_mapBlockIdx != blockIdx) [[unlikely]] {
 | 
				
			||||||
		oxReturnError(loadMapBlock(blockIdx));
 | 
							OX_RETURN_ERROR(loadMapBlock(blockIdx));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	idx %= blockBits;
 | 
						idx %= blockBits;
 | 
				
			||||||
	return (m_mapBlock >> idx) & 1;
 | 
						return (m_mapBlock >> idx) & 1;
 | 
				
			||||||
@@ -55,12 +55,12 @@ constexpr Result<bool> FieldBitmapReader<Reader>::get(std::size_t idx) const noe
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<Reader_c Reader>
 | 
					template<Reader_c Reader>
 | 
				
			||||||
constexpr ox::Error FieldBitmapReader<Reader>::loadMapBlock(std::size_t idx) const noexcept {
 | 
					constexpr ox::Error FieldBitmapReader<Reader>::loadMapBlock(std::size_t idx) const noexcept {
 | 
				
			||||||
	oxRequire(g, m_reader.tellg());
 | 
						OX_REQUIRE(g, m_reader.tellg());
 | 
				
			||||||
	oxReturnError(m_reader.seekg(static_cast<int>(m_mapStart + idx), ox::ios_base::beg));
 | 
						OX_RETURN_ERROR(m_reader.seekg(static_cast<int>(m_mapStart + idx), ox::ios_base::beg));
 | 
				
			||||||
	ox::Array<char, sizeof(m_mapBlock)> mapBlock{};
 | 
						ox::Array<char, sizeof(m_mapBlock)> mapBlock{};
 | 
				
			||||||
	oxReturnError(m_reader.read(mapBlock.data(), sizeof(m_mapBlock)));
 | 
						OX_RETURN_ERROR(m_reader.read(mapBlock.data(), sizeof(m_mapBlock)));
 | 
				
			||||||
	// Warning: narrow-conv
 | 
						// Warning: narrow-conv
 | 
				
			||||||
	oxReturnError(m_reader.seekg(static_cast<int>(g), ox::ios_base::beg));
 | 
						OX_RETURN_ERROR(m_reader.seekg(static_cast<int>(g), ox::ios_base::beg));
 | 
				
			||||||
	m_mapBlock = 0;
 | 
						m_mapBlock = 0;
 | 
				
			||||||
	for (auto i = 0ull; auto b : mapBlock) {
 | 
						for (auto i = 0ull; auto b : mapBlock) {
 | 
				
			||||||
		m_mapBlock |= static_cast<uint64_t>(std::bit_cast<uint8_t>(b)) << i;
 | 
							m_mapBlock |= static_cast<uint64_t>(std::bit_cast<uint8_t>(b)) << i;
 | 
				
			||||||
@@ -110,7 +110,7 @@ constexpr Result<bool> FieldBitmapWriterBase<T>::get(std::size_t i) const noexce
 | 
				
			|||||||
	if (i / 8 < m_mapLen) {
 | 
						if (i / 8 < m_mapLen) {
 | 
				
			||||||
		return (m_map[i / 8] >> (i % 8)) & 1;
 | 
							return (m_map[i / 8] >> (i % 8)) & 1;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return OxError(McPresenceMapOverflow);
 | 
							return ox::Error(McPresenceMapOverflow);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -147,14 +147,16 @@ constexpr FieldBitmap::FieldBitmap(uint8_t *map, std::size_t maxLen) noexcept:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
constexpr Error FieldBitmap::set(std::size_t i, bool on) noexcept {
 | 
					constexpr Error FieldBitmap::set(std::size_t i, bool on) noexcept {
 | 
				
			||||||
	if (i / 8 < m_mapLen) {
 | 
						if (i / 8 < m_mapLen) {
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
		if (on) {
 | 
							if (on) {
 | 
				
			||||||
			m_map[i / 8] |= 1 << (i % 8);
 | 
								m_map[i / 8] |= 1 << (i % 8);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			m_map[i / 8] &= ~static_cast<uint8_t>(1 << (i % 8));
 | 
								m_map[i / 8] &= ~static_cast<uint8_t>(1 << (i % 8));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return OxError(McPresenceMapOverflow);
 | 
							return ox::Error(McPresenceMapOverflow);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/mc/read.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/mc/read.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										108
									
								
								deps/ox/src/ox/mc/read.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										108
									
								
								deps/ox/src/ox/mc/read.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -194,10 +194,10 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, bool *val) n
 | 
				
			|||||||
	if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
 | 
						if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
 | 
				
			||||||
		auto const result = m_fieldPresence.get(static_cast<std::size_t>(m_field));
 | 
							auto const result = m_fieldPresence.get(static_cast<std::size_t>(m_field));
 | 
				
			||||||
		*val = result.value;
 | 
							*val = result.value;
 | 
				
			||||||
		oxReturnError(result);
 | 
							OX_RETURN_ERROR(result);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// array handler
 | 
					// array handler
 | 
				
			||||||
@@ -207,18 +207,20 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, auto *v
 | 
				
			|||||||
		if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
							if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
			// read the length
 | 
								// read the length
 | 
				
			||||||
			std::size_t bytesRead = 0;
 | 
								std::size_t bytesRead = 0;
 | 
				
			||||||
			oxRequire(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
 | 
								OX_REQUIRE(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
 | 
				
			||||||
			// read the list
 | 
								// read the list
 | 
				
			||||||
			if (valLen >= len) {
 | 
								if (valLen >= len) {
 | 
				
			||||||
				auto reader = child({});
 | 
									auto reader = child({});
 | 
				
			||||||
				auto &handler = *reader.interface();
 | 
									auto &handler = *reader.interface();
 | 
				
			||||||
				oxReturnError(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
 | 
									OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
 | 
				
			||||||
				for (std::size_t i = 0; i < len; ++i) {
 | 
									for (std::size_t i = 0; i < len; ++i) {
 | 
				
			||||||
					oxReturnError(handler.field({}, &val[i]));
 | 
					OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
 | 
										OX_RETURN_ERROR(handler.field({}, &val[i]));
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				oxTracef("ox.mc.read.field(T)", "{}, length: {}", name, valLen);
 | 
									oxTracef("ox.mc.read.field(T)", "{}, length: {}", name, valLen);
 | 
				
			||||||
				return OxError(McOutputBuffEnded);
 | 
									return ox::Error(McOutputBuffEnded);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -232,29 +234,29 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, HashMap<Stri
 | 
				
			|||||||
	if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
 | 
						if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
 | 
				
			||||||
		if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
							if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
			// read the length
 | 
								// read the length
 | 
				
			||||||
			oxRequire(g, m_reader.tellg());
 | 
								OX_REQUIRE(g, m_reader.tellg());
 | 
				
			||||||
			std::size_t bytesRead = 0;
 | 
								std::size_t bytesRead = 0;
 | 
				
			||||||
			oxRequire(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
 | 
								OX_REQUIRE(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
 | 
				
			||||||
			oxReturnError(m_reader.seekg(g));
 | 
								OX_RETURN_ERROR(m_reader.seekg(g));
 | 
				
			||||||
			// read the list
 | 
								// read the list
 | 
				
			||||||
			auto reader = child("");
 | 
								auto reader = child("");
 | 
				
			||||||
			auto &handler = *reader.interface();
 | 
								auto &handler = *reader.interface();
 | 
				
			||||||
			oxReturnError(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
 | 
								OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
 | 
				
			||||||
			// this loop body needs to be in a lambda because of the potential alloca call
 | 
								// this loop body needs to be in a lambda because of the potential alloca call
 | 
				
			||||||
			constexpr auto loopBody = [](auto &handler, auto &val) {
 | 
								constexpr auto loopBody = [](auto &handler, auto &val) {
 | 
				
			||||||
				oxRequire(keyLen, handler.stringLength(nullptr));
 | 
									OX_REQUIRE(keyLen, handler.stringLength(nullptr));
 | 
				
			||||||
				auto wkey = ox_malloca(keyLen + 1, char, 0);
 | 
									auto wkey = ox_malloca(keyLen + 1, char, 0);
 | 
				
			||||||
				auto wkeyPtr = wkey.get();
 | 
									auto wkeyPtr = wkey.get();
 | 
				
			||||||
				oxReturnError(handler.fieldCString("", &wkeyPtr, keyLen + 1));
 | 
									OX_RETURN_ERROR(handler.fieldCString("", &wkeyPtr, keyLen + 1));
 | 
				
			||||||
				return handler.field("", &val[wkeyPtr]);
 | 
									return handler.field("", &val[wkeyPtr]);
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
			for (std::size_t i = 0; i < len; ++i) {
 | 
								for (std::size_t i = 0; i < len; ++i) {
 | 
				
			||||||
				oxReturnError(loopBody(handler, *val));
 | 
									OX_RETURN_ERROR(loopBody(handler, *val));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Reader_c Reader>
 | 
					template<Reader_c Reader>
 | 
				
			||||||
@@ -264,11 +266,11 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, T *val)
 | 
				
			|||||||
		if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
 | 
							if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
 | 
				
			||||||
			// set size of val if the field is present, don't worry about it if not
 | 
								// set size of val if the field is present, don't worry about it if not
 | 
				
			||||||
			if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
								if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
				oxRequire(len, arrayLength(name, false));
 | 
									OX_REQUIRE(len, arrayLength(name, false));
 | 
				
			||||||
				oxReturnError(ox::resizeVector(*val, len));
 | 
									OX_RETURN_ERROR(ox::resizeVector(*val, len));
 | 
				
			||||||
				return field(name, val->data(), val->size());
 | 
									return field(name, val->data(), val->size());
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			oxReturnError(ox::resizeVector(*val, 0));
 | 
								OX_RETURN_ERROR(ox::resizeVector(*val, 0));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		++m_field;
 | 
							++m_field;
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
@@ -276,9 +278,9 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, T *val)
 | 
				
			|||||||
		if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
 | 
							if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
 | 
				
			||||||
			// set size of val if the field is present, don't worry about it if not
 | 
								// set size of val if the field is present, don't worry about it if not
 | 
				
			||||||
			if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
								if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
				oxRequire(len, arrayLength(name, false));
 | 
									OX_REQUIRE(len, arrayLength(name, false));
 | 
				
			||||||
				if (len > val->size()) {
 | 
									if (len > val->size()) {
 | 
				
			||||||
					return OxError(1, "Input array is too long");
 | 
										return ox::Error(1, "Input array is too long");
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return field(name, val->data(), val->size());
 | 
								return field(name, val->data(), val->size());
 | 
				
			||||||
@@ -289,7 +291,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, T *val)
 | 
				
			|||||||
		if ((!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) && val) {
 | 
							if ((!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) && val) {
 | 
				
			||||||
			if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
								if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
				auto reader = child("");
 | 
									auto reader = child("");
 | 
				
			||||||
				oxReturnError(model(reader.interface(), val));
 | 
									OX_RETURN_ERROR(model(reader.interface(), val));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		++m_field;
 | 
							++m_field;
 | 
				
			||||||
@@ -303,7 +305,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, UnionView<U,
 | 
				
			|||||||
	if ((!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) && val.get()) {
 | 
						if ((!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) && val.get()) {
 | 
				
			||||||
		if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
							if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
			auto reader = child("", ox::Optional<int>(ox::in_place, val.idx()));
 | 
								auto reader = child("", ox::Optional<int>(ox::in_place, val.idx()));
 | 
				
			||||||
			oxReturnError(model(reader.interface(), val.get()));
 | 
								OX_RETURN_ERROR(model(reader.interface(), val.get()));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
@@ -317,18 +319,18 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, BasicString<
 | 
				
			|||||||
		if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
							if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
			// read the length
 | 
								// read the length
 | 
				
			||||||
			std::size_t bytesRead = 0;
 | 
								std::size_t bytesRead = 0;
 | 
				
			||||||
			oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
 | 
								OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
 | 
				
			||||||
			const auto cap = size;
 | 
								const auto cap = size;
 | 
				
			||||||
			*val = BasicString<SmallStringSize>(cap);
 | 
								*val = BasicString<SmallStringSize>(cap);
 | 
				
			||||||
			auto data = val->data();
 | 
								auto data = val->data();
 | 
				
			||||||
			// read the string
 | 
								// read the string
 | 
				
			||||||
			oxReturnError(m_reader.read(data, size));
 | 
								OX_RETURN_ERROR(m_reader.read(data, size));
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			*val = "";
 | 
								*val = "";
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Reader_c Reader>
 | 
					template<Reader_c Reader>
 | 
				
			||||||
@@ -338,12 +340,12 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, IString<L> *
 | 
				
			|||||||
		if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
							if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
			// read the length
 | 
								// read the length
 | 
				
			||||||
			std::size_t bytesRead = 0;
 | 
								std::size_t bytesRead = 0;
 | 
				
			||||||
			oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
 | 
								OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
 | 
				
			||||||
			*val = IString<L>();
 | 
								*val = IString<L>();
 | 
				
			||||||
			oxReturnError(val->resize(size));
 | 
								OX_RETURN_ERROR(val->resize(size));
 | 
				
			||||||
			auto const data = val->data();
 | 
								auto const data = val->data();
 | 
				
			||||||
			// read the string
 | 
								// read the string
 | 
				
			||||||
			oxReturnError(m_reader.read(data, size));
 | 
								OX_RETURN_ERROR(m_reader.read(data, size));
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			*val = "";
 | 
								*val = "";
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -357,18 +359,18 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
 | 
				
			|||||||
	if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
						if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
		// read the length
 | 
							// read the length
 | 
				
			||||||
		std::size_t bytesRead = 0;
 | 
							std::size_t bytesRead = 0;
 | 
				
			||||||
		oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
 | 
							OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
 | 
				
			||||||
		if (size > buffLen) {
 | 
							if (size > buffLen) {
 | 
				
			||||||
			return OxError(McOutputBuffEnded);
 | 
								return ox::Error(McOutputBuffEnded);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// re-allocate in case too small
 | 
							// re-allocate in case too small
 | 
				
			||||||
		auto data = val;
 | 
							auto data = val;
 | 
				
			||||||
		// read the string
 | 
							// read the string
 | 
				
			||||||
		oxReturnError(m_reader.read(data, size));
 | 
							OX_RETURN_ERROR(m_reader.read(data, size));
 | 
				
			||||||
		data[size] = 0;
 | 
							data[size] = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Reader_c Reader>
 | 
					template<Reader_c Reader>
 | 
				
			||||||
@@ -376,17 +378,17 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
 | 
				
			|||||||
	if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
						if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
		// read the length
 | 
							// read the length
 | 
				
			||||||
		std::size_t bytesRead = 0;
 | 
							std::size_t bytesRead = 0;
 | 
				
			||||||
		oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
 | 
							OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
 | 
				
			||||||
		// re-allocate in case too small
 | 
							// re-allocate in case too small
 | 
				
			||||||
		safeDelete(*val);
 | 
							safeDelete(*val);
 | 
				
			||||||
		*val = new char[size + 1];
 | 
							*val = new char[size + 1];
 | 
				
			||||||
		auto data = *val;
 | 
							auto data = ox::Span{*val, size + 1};
 | 
				
			||||||
		// read the string
 | 
							// read the string
 | 
				
			||||||
		oxReturnError(m_reader.read(data, size));
 | 
							OX_RETURN_ERROR(m_reader.read(data.data(), size));
 | 
				
			||||||
		data[size] = 0;
 | 
							data[size] = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Reader_c Reader>
 | 
					template<Reader_c Reader>
 | 
				
			||||||
@@ -395,16 +397,16 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
 | 
				
			|||||||
		if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
							if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
			// read the length
 | 
								// read the length
 | 
				
			||||||
			std::size_t bytesRead = 0;
 | 
								std::size_t bytesRead = 0;
 | 
				
			||||||
			oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
 | 
								OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
 | 
				
			||||||
			// re-allocate if too small
 | 
								// re-allocate if too small
 | 
				
			||||||
			if (buffLen < size + 1) {
 | 
								if (buffLen < size + 1) {
 | 
				
			||||||
				safeDelete(*val);
 | 
									safeDelete(*val);
 | 
				
			||||||
				*val = new char[size + 1];
 | 
									*val = new char[size + 1];
 | 
				
			||||||
				buffLen = size + 1;
 | 
									buffLen = size + 1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			auto data = *val;
 | 
								auto data = ox::Span{*val, size + 1};
 | 
				
			||||||
			// read the string
 | 
								// read the string
 | 
				
			||||||
			oxReturnError(m_reader.read(data, size));
 | 
								OX_RETURN_ERROR(m_reader.read(data.data(), size));
 | 
				
			||||||
			data[size] = 0;
 | 
								data[size] = 0;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			auto data = *val;
 | 
								auto data = *val;
 | 
				
			||||||
@@ -414,7 +416,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Reader_c Reader>
 | 
					template<Reader_c Reader>
 | 
				
			||||||
@@ -423,15 +425,15 @@ constexpr Result<ArrayLength> MetalClawReaderTemplate<Reader>::arrayLength(const
 | 
				
			|||||||
		if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
							if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
			// read the length
 | 
								// read the length
 | 
				
			||||||
			std::size_t bytesRead = 0;
 | 
								std::size_t bytesRead = 0;
 | 
				
			||||||
			oxRequire(g, m_reader.tellg());
 | 
								OX_REQUIRE(g, m_reader.tellg());
 | 
				
			||||||
			oxRequire(out, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
 | 
								OX_REQUIRE(out, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
 | 
				
			||||||
			if (!pass) {
 | 
								if (!pass) {
 | 
				
			||||||
				oxReturnError(m_reader.seekg(g));
 | 
									OX_RETURN_ERROR(m_reader.seekg(g));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return out;
 | 
								return out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1);
 | 
						return ox::Error(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Reader_c Reader>
 | 
					template<Reader_c Reader>
 | 
				
			||||||
@@ -441,7 +443,7 @@ constexpr Result<StringLength> MetalClawReaderTemplate<Reader>::stringLength(con
 | 
				
			|||||||
			// read the length
 | 
								// read the length
 | 
				
			||||||
			std::size_t bytesRead = 0;
 | 
								std::size_t bytesRead = 0;
 | 
				
			||||||
			auto len = mc::decodeInteger<StringLength>(m_reader, &bytesRead);
 | 
								auto len = mc::decodeInteger<StringLength>(m_reader, &bytesRead);
 | 
				
			||||||
			oxReturnError(m_reader.seekg(-static_cast<int64_t>(bytesRead), ox::ios_base::cur));
 | 
								OX_RETURN_ERROR(m_reader.seekg(-static_cast<int64_t>(bytesRead), ox::ios_base::cur));
 | 
				
			||||||
			return len;
 | 
								return len;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -455,14 +457,14 @@ constexpr Error MetalClawReaderTemplate<Reader>::readInteger(I *val) noexcept {
 | 
				
			|||||||
		if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
							if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
			std::size_t bytesRead = 0;
 | 
								std::size_t bytesRead = 0;
 | 
				
			||||||
			auto const result = mc::decodeInteger<I>(m_reader, &bytesRead);
 | 
								auto const result = mc::decodeInteger<I>(m_reader, &bytesRead);
 | 
				
			||||||
			oxReturnError(result);
 | 
								OX_RETURN_ERROR(result);
 | 
				
			||||||
			*val = result.value;
 | 
								*val = result.value;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			*val = 0;
 | 
								*val = 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Reader_c Reader>
 | 
					template<Reader_c Reader>
 | 
				
			||||||
@@ -472,20 +474,20 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, CB cb) noexc
 | 
				
			|||||||
		if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
							if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
 | 
				
			||||||
			// read the length
 | 
								// read the length
 | 
				
			||||||
			std::size_t bytesRead = 0;
 | 
								std::size_t bytesRead = 0;
 | 
				
			||||||
			oxRequire(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
 | 
								OX_REQUIRE(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
 | 
				
			||||||
			// read the list
 | 
								// read the list
 | 
				
			||||||
			auto reader = child("");
 | 
								auto reader = child("");
 | 
				
			||||||
			auto &handler = *reader.interface();
 | 
								auto &handler = *reader.interface();
 | 
				
			||||||
			oxReturnError(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
 | 
								OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
 | 
				
			||||||
			for (std::size_t i = 0; i < len; ++i) {
 | 
								for (std::size_t i = 0; i < len; ++i) {
 | 
				
			||||||
				T val;
 | 
									T val;
 | 
				
			||||||
				oxReturnError(handler.field("", &val));
 | 
									OX_RETURN_ERROR(handler.field("", &val));
 | 
				
			||||||
				oxReturnError(cb(i, &val));
 | 
									OX_RETURN_ERROR(cb(i, &val));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Reader_c Reader>
 | 
					template<Reader_c Reader>
 | 
				
			||||||
@@ -546,7 +548,7 @@ Error readMC(ox::BufferView buff, T &val) noexcept {
 | 
				
			|||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
Result<T> readMC(ox::BufferView buff) noexcept {
 | 
					Result<T> readMC(ox::BufferView buff) noexcept {
 | 
				
			||||||
	Result<T> val;
 | 
						Result<T> val;
 | 
				
			||||||
	oxReturnError(readMC(buff, val.value));
 | 
						OX_RETURN_ERROR(readMC(buff, val.value));
 | 
				
			||||||
	return val;
 | 
						return val;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										113
									
								
								deps/ox/src/ox/mc/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										113
									
								
								deps/ox/src/ox/mc/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -62,47 +62,47 @@ struct TestStruct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcept {
 | 
					constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcept {
 | 
				
			||||||
	oxReturnError(io->template setTypeInfo<TestUnion>());
 | 
						OX_RETURN_ERROR(io->template setTypeInfo<TestUnion>());
 | 
				
			||||||
	oxReturnError(io->field("Bool", &obj->Bool));
 | 
						OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
 | 
				
			||||||
	oxReturnError(io->field("Int", &obj->Int));
 | 
						OX_RETURN_ERROR(io->field("Int", &obj->Int));
 | 
				
			||||||
	oxReturnError(io->fieldCString("CString", &obj->CString));
 | 
						OX_RETURN_ERROR(io->fieldCString("CString", &obj->CString));
 | 
				
			||||||
	return OxError(0);
 | 
						return ox::Error(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oxModelBegin(TestStructNest)
 | 
					OX_MODEL_BEGIN(TestStructNest)
 | 
				
			||||||
	oxModelField(Bool)
 | 
						OX_MODEL_FIELD(Bool)
 | 
				
			||||||
	oxModelField(Int)
 | 
						OX_MODEL_FIELD(Int)
 | 
				
			||||||
	oxModelField(IString)
 | 
						OX_MODEL_FIELD(IString)
 | 
				
			||||||
oxModelEnd()
 | 
					OX_MODEL_END()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) noexcept {
 | 
					constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) noexcept {
 | 
				
			||||||
	oxReturnError(io->template setTypeInfo<TestStruct>());
 | 
						OX_RETURN_ERROR(io->template setTypeInfo<TestStruct>());
 | 
				
			||||||
	oxReturnError(io->field("Bool", &obj->Bool));
 | 
						OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
 | 
				
			||||||
	oxReturnError(io->field("Int", &obj->Int));
 | 
						OX_RETURN_ERROR(io->field("Int", &obj->Int));
 | 
				
			||||||
	oxReturnError(io->field("Int1", &obj->Int1));
 | 
						OX_RETURN_ERROR(io->field("Int1", &obj->Int1));
 | 
				
			||||||
	oxReturnError(io->field("Int2", &obj->Int2));
 | 
						OX_RETURN_ERROR(io->field("Int2", &obj->Int2));
 | 
				
			||||||
	oxReturnError(io->field("Int3", &obj->Int3));
 | 
						OX_RETURN_ERROR(io->field("Int3", &obj->Int3));
 | 
				
			||||||
	oxReturnError(io->field("Int4", &obj->Int4));
 | 
						OX_RETURN_ERROR(io->field("Int4", &obj->Int4));
 | 
				
			||||||
	oxReturnError(io->field("Int5", &obj->Int5));
 | 
						OX_RETURN_ERROR(io->field("Int5", &obj->Int5));
 | 
				
			||||||
	oxReturnError(io->field("Int6", &obj->Int6));
 | 
						OX_RETURN_ERROR(io->field("Int6", &obj->Int6));
 | 
				
			||||||
	oxReturnError(io->field("Int7", &obj->Int7));
 | 
						OX_RETURN_ERROR(io->field("Int7", &obj->Int7));
 | 
				
			||||||
	oxReturnError(io->field("Int8", &obj->Int8));
 | 
						OX_RETURN_ERROR(io->field("Int8", &obj->Int8));
 | 
				
			||||||
	oxReturnError(io->field("unionIdx", &obj->unionIdx));
 | 
						OX_RETURN_ERROR(io->field("unionIdx", &obj->unionIdx));
 | 
				
			||||||
	if constexpr(T::opType() == ox::OpType::Reflect) {
 | 
						if constexpr(T::opType() == ox::OpType::Reflect) {
 | 
				
			||||||
		oxReturnError(io->field("Union", ox::UnionView{&obj->Union, 0}));
 | 
							OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, 0}));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		oxReturnError(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
 | 
							OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(io->field("String", &obj->String));
 | 
						OX_RETURN_ERROR(io->field("String", &obj->String));
 | 
				
			||||||
	oxReturnError(io->field("IString", &obj->IString));
 | 
						OX_RETURN_ERROR(io->field("IString", &obj->IString));
 | 
				
			||||||
	oxReturnError(io->field("List", obj->List, 4));
 | 
						OX_RETURN_ERROR(io->field("List", obj->List, 4));
 | 
				
			||||||
	oxReturnError(io->field("Vector", &obj->Vector));
 | 
						OX_RETURN_ERROR(io->field("Vector", &obj->Vector));
 | 
				
			||||||
	oxReturnError(io->field("Vector2", &obj->Vector2));
 | 
						OX_RETURN_ERROR(io->field("Vector2", &obj->Vector2));
 | 
				
			||||||
	oxReturnError(io->field("Map", &obj->Map));
 | 
						OX_RETURN_ERROR(io->field("Map", &obj->Map));
 | 
				
			||||||
	oxReturnError(io->field("Struct", &obj->Struct));
 | 
						OX_RETURN_ERROR(io->field("Struct", &obj->Struct));
 | 
				
			||||||
	oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
 | 
						OX_RETURN_ERROR(io->field("EmptyStruct", &obj->EmptyStruct));
 | 
				
			||||||
	return OxError(0);
 | 
						return ox::Error(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
					std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			||||||
@@ -114,9 +114,9 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				// doesn't segfault
 | 
									// doesn't segfault
 | 
				
			||||||
				ox::Array<char, 1024> buff;
 | 
									ox::Array<char, 1024> buff;
 | 
				
			||||||
				TestStruct ts;
 | 
									TestStruct ts;
 | 
				
			||||||
				oxReturnError(ox::writeMC(buff.data(), buff.size(), ts));
 | 
									OX_RETURN_ERROR(ox::writeMC(buff.data(), buff.size(), ts));
 | 
				
			||||||
				oxReturnError(ox::writeMC(ts));
 | 
									OX_RETURN_ERROR(ox::writeMC(ts));
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -157,7 +157,6 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				oxAssert(testIn.Int8                == testOut.Int8,                "Int8 value mismatch");
 | 
									oxAssert(testIn.Int8                == testOut.Int8,                "Int8 value mismatch");
 | 
				
			||||||
				oxAssert(testIn.Union.Int           == testOut.Union.Int,           "Union.Int value mismatch");
 | 
									oxAssert(testIn.Union.Int           == testOut.Union.Int,           "Union.Int value mismatch");
 | 
				
			||||||
				oxAssert(testIn.String              == testOut.String,              "String value mismatch");
 | 
									oxAssert(testIn.String              == testOut.String,              "String value mismatch");
 | 
				
			||||||
				oxDebugf("{}", testOut.IString.len());
 | 
					 | 
				
			||||||
				oxExpect(testIn.IString,               testOut.IString);
 | 
									oxExpect(testIn.IString,               testOut.IString);
 | 
				
			||||||
				oxAssert(testIn.List[0]             == testOut.List[0],             "List[0] value mismatch");
 | 
									oxAssert(testIn.List[0]             == testOut.List[0],             "List[0] value mismatch");
 | 
				
			||||||
				oxAssert(testIn.List[1]             == testOut.List[1],             "List[1] value mismatch");
 | 
									oxAssert(testIn.List[1]             == testOut.List[1],             "List[1] value mismatch");
 | 
				
			||||||
@@ -176,7 +175,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				oxAssert(testIn.Struct.Int          == testOut.Struct.Int,          "Struct.Int value mismatch");
 | 
									oxAssert(testIn.Struct.Int          == testOut.Struct.Int,          "Struct.Int value mismatch");
 | 
				
			||||||
				oxAssert(testIn.Struct.IString      == testOut.Struct.IString,      "Struct.IString value mismatch");
 | 
									oxAssert(testIn.Struct.IString      == testOut.Struct.IString,      "Struct.IString value mismatch");
 | 
				
			||||||
				oxAssert(testIn.Struct.Bool         == testOut.Struct.Bool,         "Struct.Bool value mismatch");
 | 
									oxAssert(testIn.Struct.Bool         == testOut.Struct.Bool,         "Struct.Bool value mismatch");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -189,28 +188,28 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				static constexpr auto check = [](McInt val, const ox::Vector<uint8_t, 9> &expected) {
 | 
									static constexpr auto check = [](McInt val, const ox::Vector<uint8_t, 9> &expected) {
 | 
				
			||||||
					if (val.length != expected.size()) {
 | 
										if (val.length != expected.size()) {
 | 
				
			||||||
						std::cout << "val.length: " << val.length << ", expected: " << expected.size() << '\n';
 | 
											std::cout << "val.length: " << val.length << ", expected: " << expected.size() << '\n';
 | 
				
			||||||
						return OxError(1);
 | 
											return ox::Error(1);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					for (std::size_t i = 0; i < expected.size(); i++) {
 | 
										for (std::size_t i = 0; i < expected.size(); i++) {
 | 
				
			||||||
						if (expected[i] != val.data[i]) {
 | 
											if (expected[i] != val.data[i]) {
 | 
				
			||||||
							std::cout << "decoded: " << static_cast<uint32_t>(val.data[i]) << ", expected: " << static_cast<uint32_t>(expected[i]) << '\n';
 | 
												std::cout << "decoded: " << static_cast<uint32_t>(val.data[i]) << ", expected: " << static_cast<uint32_t>(expected[i]) << '\n';
 | 
				
			||||||
							std::cout << "decoded: " << i << ": " << static_cast<uint32_t>(val.data[i]) << '\n';
 | 
												std::cout << "decoded: " << i << ": " << static_cast<uint32_t>(val.data[i]) << '\n';
 | 
				
			||||||
							return OxError(1);
 | 
												return ox::Error(1);
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					return OxError(0);
 | 
										return ox::Error(0);
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
				constexpr auto check64 = [](McInt val, auto expected) {
 | 
									constexpr auto check64 = [](McInt val, auto expected) {
 | 
				
			||||||
					if (val.length != 9) {
 | 
										if (val.length != 9) {
 | 
				
			||||||
						std::cout << "val.length: " << val.length << '\n';
 | 
											std::cout << "val.length: " << val.length << '\n';
 | 
				
			||||||
						return OxError(1);
 | 
											return ox::Error(1);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					ox::LittleEndian<decltype(expected)> decoded = *reinterpret_cast<decltype(expected)*>(&val.data[1]);
 | 
										ox::LittleEndian<decltype(expected)> decoded = *reinterpret_cast<decltype(expected)*>(&val.data[1]);
 | 
				
			||||||
					if (expected != decoded) {
 | 
										if (expected != decoded) {
 | 
				
			||||||
						std::cout << "decoded: " << decoded << ", expected: " << expected << '\n';
 | 
											std::cout << "decoded: " << decoded << ", expected: " << expected << '\n';
 | 
				
			||||||
						return OxError(1);
 | 
											return ox::Error(1);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					return OxError(0);
 | 
										return ox::Error(0);
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
				// signed positive
 | 
									// signed positive
 | 
				
			||||||
				oxAssert(check(encodeInteger(int64_t(1)), {0b000'0001'0}), "Encode 1 fail");
 | 
									oxAssert(check(encodeInteger(int64_t(1)), {0b000'0001'0}), "Encode 1 fail");
 | 
				
			||||||
@@ -247,7 +246,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				// code deduplication
 | 
									// code deduplication
 | 
				
			||||||
				oxAssert(check64(encodeInteger(MaxValue<int64_t>), MaxValue<int64_t>), "Encode MaxValue<int64_t> fail");
 | 
									oxAssert(check64(encodeInteger(MaxValue<int64_t>), MaxValue<int64_t>), "Encode MaxValue<int64_t> fail");
 | 
				
			||||||
				oxAssert(check64(encodeInteger(MaxValue<uint64_t>), MaxValue<uint64_t>), "Encode MaxValue<uint64_t> fail");
 | 
									oxAssert(check64(encodeInteger(MaxValue<uint64_t>), MaxValue<uint64_t>), "Encode MaxValue<uint64_t> fail");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -260,12 +259,12 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				using ox::mc::decodeInteger;
 | 
									using ox::mc::decodeInteger;
 | 
				
			||||||
				static constexpr auto check = [](auto val) {
 | 
									static constexpr auto check = [](auto val) {
 | 
				
			||||||
					auto result = decodeInteger<decltype(val)>(encodeInteger(val));
 | 
										auto result = decodeInteger<decltype(val)>(encodeInteger(val));
 | 
				
			||||||
					oxReturnError(result.error);
 | 
										OX_RETURN_ERROR(result.error);
 | 
				
			||||||
					if (result.value != val) {
 | 
										if (result.value != val) {
 | 
				
			||||||
						std::cout << "Bad value: " << result.value << ", expected: " << val << '\n';
 | 
											std::cout << "Bad value: " << result.value << ", expected: " << val << '\n';
 | 
				
			||||||
						return OxError(1);
 | 
											return ox::Error(1);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					return OxError(0);
 | 
										return ox::Error(0);
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
				oxAssert(check(uint32_t(14)), "Decode of 14 failed.");
 | 
									oxAssert(check(uint32_t(14)), "Decode of 14 failed.");
 | 
				
			||||||
				oxAssert(check(int8_t(-1)), "Decode of -1 failed.");
 | 
									oxAssert(check(int8_t(-1)), "Decode of -1 failed.");
 | 
				
			||||||
@@ -291,7 +290,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				oxAssert(check(0xffffffff), "Decode of 0xffffffff failed.");
 | 
									oxAssert(check(0xffffffff), "Decode of 0xffffffff failed.");
 | 
				
			||||||
				oxAssert(check(0xffffffffffff), "Decode of 0xffffffffffff failed.");
 | 
									oxAssert(check(0xffffffffffff), "Decode of 0xffffffffffff failed.");
 | 
				
			||||||
				oxAssert(check(0xffffffffffffffff), "Decode of U64 max failed.");
 | 
									oxAssert(check(0xffffffffffffffff), "Decode of U64 max failed.");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -316,10 +315,10 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				testIn.Union.Int = 93;
 | 
									testIn.Union.Int = 93;
 | 
				
			||||||
				oxAssert(ox::writeMC(dataBuff.data(), dataBuff.size(), testIn), "Data generation failed");
 | 
									oxAssert(ox::writeMC(dataBuff.data(), dataBuff.size(), testIn), "Data generation failed");
 | 
				
			||||||
				ox::TypeStore typeStore;
 | 
									ox::TypeStore typeStore;
 | 
				
			||||||
				const auto [type, typeErr] = ox::buildTypeDef(&typeStore, &testIn);
 | 
									const auto [type, typeErr] = ox::buildTypeDef(typeStore, testIn);
 | 
				
			||||||
				oxAssert(typeErr, "Descriptor write failed");
 | 
									oxAssert(typeErr, "Descriptor write failed");
 | 
				
			||||||
				ox::ModelObject testOut;
 | 
									ox::ModelObject testOut;
 | 
				
			||||||
				oxReturnError(testOut.setType(type));
 | 
									OX_RETURN_ERROR(testOut.setType(type));
 | 
				
			||||||
				oxAssert(ox::readMC(dataBuff, testOut), "Data read failed");
 | 
									oxAssert(ox::readMC(dataBuff, testOut), "Data read failed");
 | 
				
			||||||
				oxAssert(testOut.at("Int").unwrap()->get<int>() == testIn.Int, "testOut.Int failed");
 | 
									oxAssert(testOut.at("Int").unwrap()->get<int>() == testIn.Int, "testOut.Int failed");
 | 
				
			||||||
				oxAssert(testOut.at("Bool").unwrap()->get<bool>() == testIn.Bool, "testOut.Bool failed");
 | 
									oxAssert(testOut.at("Bool").unwrap()->get<bool>() == testIn.Bool, "testOut.Bool failed");
 | 
				
			||||||
@@ -344,7 +343,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				oxAssert(testOutStructCopy.at("IString").unwrap()->get<ox::String>() == testIn.Struct.IString.c_str(), "testOut.Struct.IString (copy) failed");
 | 
									oxAssert(testOutStructCopy.at("IString").unwrap()->get<ox::String>() == testIn.Struct.IString.c_str(), "testOut.Struct.IString (copy) failed");
 | 
				
			||||||
				oxAssert(testOutListCopy[0].get<uint32_t>() == testIn.List[0], "testOut.Struct.List[0] (copy) failed");
 | 
									oxAssert(testOutListCopy[0].get<uint32_t>() == testIn.List[0], "testOut.Struct.List[0] (copy) failed");
 | 
				
			||||||
				oxAssert(testOutListCopy[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] (copy) failed");
 | 
									oxAssert(testOutListCopy[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] (copy) failed");
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -368,10 +367,10 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				 testIn.Struct.IString = "Test String 2";
 | 
									 testIn.Struct.IString = "Test String 2";
 | 
				
			||||||
				 oxAssert(ox::writeMC(dataBuff, dataBuffLen, testIn), "Data generation failed");
 | 
									 oxAssert(ox::writeMC(dataBuff, dataBuffLen, testIn), "Data generation failed");
 | 
				
			||||||
				 ox::TypeStore typeStore;
 | 
									 ox::TypeStore typeStore;
 | 
				
			||||||
				 const auto [type, typeErr] = ox::buildTypeDef(&typeStore, &testIn);
 | 
									 const auto [type, typeErr] = ox::buildTypeDef(typeStore, testIn);
 | 
				
			||||||
				 oxAssert(typeErr, "Descriptor write failed");
 | 
									 oxAssert(typeErr, "Descriptor write failed");
 | 
				
			||||||
				 ox::BufferReader br({dataBuff, dataBuffLen});
 | 
									 ox::BufferReader br({dataBuff, dataBuffLen});
 | 
				
			||||||
				 oxReturnError(ox::walkModel<ox::MetalClawReader>(type, br,
 | 
									 OX_RETURN_ERROR(ox::walkModel<ox::MetalClawReader>(type, br,
 | 
				
			||||||
					[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::String>&, const ox::DescriptorField &f, ox::MetalClawReader *rdr) -> ox::Error {
 | 
										[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::String>&, const ox::DescriptorField &f, ox::MetalClawReader *rdr) -> ox::Error {
 | 
				
			||||||
						//std::cout << f.fieldName.c_str() << '\n';
 | 
											//std::cout << f.fieldName.c_str() << '\n';
 | 
				
			||||||
						auto fieldName = f.fieldName.c_str();
 | 
											auto fieldName = f.fieldName.c_str();
 | 
				
			||||||
@@ -454,10 +453,10 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
							case ox::PrimitiveType::Union:
 | 
												case ox::PrimitiveType::Union:
 | 
				
			||||||
								break;
 | 
													break;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						return OxError(0);
 | 
											return ox::Error(0);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				));
 | 
									));
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/mc/types.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/mc/types.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/mc/write.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/mc/write.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										109
									
								
								deps/ox/src/ox/mc/write.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								deps/ox/src/ox/mc/write.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -117,12 +117,12 @@ class MetalClawWriter {
 | 
				
			|||||||
			bool fieldSet = false;
 | 
								bool fieldSet = false;
 | 
				
			||||||
			if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
 | 
								if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
 | 
				
			||||||
				auto mi = mc::encodeInteger(val);
 | 
									auto mi = mc::encodeInteger(val);
 | 
				
			||||||
				oxReturnError(m_writer.write(reinterpret_cast<const char*>(mi.data), mi.length));
 | 
									OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(mi.data.data()), mi.length));
 | 
				
			||||||
				fieldSet = true;
 | 
									fieldSet = true;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
								OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
				
			||||||
			++m_field;
 | 
								++m_field;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -181,50 +181,55 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const uint64_t *val)
 | 
				
			|||||||
template<Writer_c Writer>
 | 
					template<Writer_c Writer>
 | 
				
			||||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const bool *val) noexcept {
 | 
					constexpr Error MetalClawWriter<Writer>::field(const char*, const bool *val) noexcept {
 | 
				
			||||||
	if (!m_unionIdx.has_value() || *m_unionIdx == m_field) {
 | 
						if (!m_unionIdx.has_value() || *m_unionIdx == m_field) {
 | 
				
			||||||
		oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), *val));
 | 
							OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), *val));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Writer_c Writer>
 | 
					template<Writer_c Writer>
 | 
				
			||||||
template<std::size_t SmallStringSize>
 | 
					template<std::size_t SmallStringSize>
 | 
				
			||||||
constexpr Error MetalClawWriter<Writer>::field(const char*, const BasicString<SmallStringSize> *val) noexcept {
 | 
					constexpr Error MetalClawWriter<Writer>::field(const char*, const BasicString<SmallStringSize> *val) noexcept {
 | 
				
			||||||
	bool fieldSet = false;
 | 
						bool fieldSet = false;
 | 
				
			||||||
	if (val->len() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
 | 
						if (val->size() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
 | 
				
			||||||
		// write the length
 | 
							// write the length
 | 
				
			||||||
		const auto strLen = mc::encodeInteger(val->len());
 | 
							const auto strLen = mc::encodeInteger(val->size());
 | 
				
			||||||
		oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLen.data), strLen.length));
 | 
							OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(strLen.data.data()), strLen.length));
 | 
				
			||||||
		// write the string
 | 
							// write the string
 | 
				
			||||||
		oxReturnError(m_writer.write(val->c_str(), static_cast<std::size_t>(val->len())));
 | 
							OX_RETURN_ERROR(m_writer.write(val->c_str(), static_cast<std::size_t>(val->size())));
 | 
				
			||||||
		fieldSet = true;
 | 
							fieldSet = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
						OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Writer_c Writer>
 | 
					template<Writer_c Writer>
 | 
				
			||||||
template<std::size_t L>
 | 
					template<std::size_t L>
 | 
				
			||||||
constexpr Error MetalClawWriter<Writer>::field(const char *name, const IString<L> *val) noexcept {
 | 
					constexpr Error MetalClawWriter<Writer>::field(const char *name, const IString<L> *val) noexcept {
 | 
				
			||||||
	return fieldCString(name, val->data(), val->len());
 | 
						return fieldCString(name, val->data(), val->size());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Writer_c Writer>
 | 
					template<Writer_c Writer>
 | 
				
			||||||
constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *const*val, std::size_t) noexcept {
 | 
					constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *const*val, std::size_t) noexcept {
 | 
				
			||||||
	bool fieldSet = false;
 | 
						bool fieldSet = false;
 | 
				
			||||||
	if (!m_unionIdx.has_value() || *m_unionIdx == m_field) {
 | 
						if (!m_unionIdx.has_value() || *m_unionIdx == m_field) {
 | 
				
			||||||
 | 
							OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
 | 
							// this strlen is tolerated because sometimes 0 gets passed to
 | 
				
			||||||
 | 
							// the size param, which is a lie
 | 
				
			||||||
 | 
							// this code should be cleaned up at some point...
 | 
				
			||||||
		const auto strLen = *val ? ox::strlen(*val) : 0;
 | 
							const auto strLen = *val ? ox::strlen(*val) : 0;
 | 
				
			||||||
 | 
							OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
		// write the length
 | 
							// write the length
 | 
				
			||||||
		const auto strLenBuff = mc::encodeInteger(strLen);
 | 
							const auto strLenBuff = mc::encodeInteger(strLen);
 | 
				
			||||||
		oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length));
 | 
							OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
 | 
				
			||||||
		// write the string
 | 
							// write the string
 | 
				
			||||||
		oxReturnError(m_writer.write(*val, static_cast<std::size_t>(strLen)));
 | 
							OX_RETURN_ERROR(m_writer.write(*val, static_cast<std::size_t>(strLen)));
 | 
				
			||||||
		fieldSet = true;
 | 
							fieldSet = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
						OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Writer_c Writer>
 | 
					template<Writer_c Writer>
 | 
				
			||||||
@@ -243,14 +248,14 @@ constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *v
 | 
				
			|||||||
	if (strLen && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
 | 
						if (strLen && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
 | 
				
			||||||
		// write the length
 | 
							// write the length
 | 
				
			||||||
		const auto strLenBuff = mc::encodeInteger(strLen);
 | 
							const auto strLenBuff = mc::encodeInteger(strLen);
 | 
				
			||||||
		oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length));
 | 
							OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
 | 
				
			||||||
		// write the string
 | 
							// write the string
 | 
				
			||||||
		oxReturnError(m_writer.write(val, static_cast<std::size_t>(strLen)));
 | 
							OX_RETURN_ERROR(m_writer.write(val, static_cast<std::size_t>(strLen)));
 | 
				
			||||||
		fieldSet = true;
 | 
							fieldSet = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
						OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Writer_c Writer>
 | 
					template<Writer_c Writer>
 | 
				
			||||||
@@ -264,11 +269,11 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val) noexce
 | 
				
			|||||||
			auto const writeIdx = m_writer.tellp();
 | 
								auto const writeIdx = m_writer.tellp();
 | 
				
			||||||
			MetalClawWriter<Writer> writer(m_writer);
 | 
								MetalClawWriter<Writer> writer(m_writer);
 | 
				
			||||||
			ModelHandlerInterface<MetalClawWriter<Writer>> handler{&writer};
 | 
								ModelHandlerInterface<MetalClawWriter<Writer>> handler{&writer};
 | 
				
			||||||
			oxReturnError(model(&handler, val));
 | 
								OX_RETURN_ERROR(model(&handler, val));
 | 
				
			||||||
			oxReturnError(writer.finalize());
 | 
								OX_RETURN_ERROR(writer.finalize());
 | 
				
			||||||
			fieldSet = writeIdx != m_writer.tellp();
 | 
								fieldSet = writeIdx != m_writer.tellp();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
							OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
				
			||||||
		++m_field;
 | 
							++m_field;
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -282,11 +287,11 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, UnionView<U, force>
 | 
				
			|||||||
		auto const writeIdx = m_writer.tellp();
 | 
							auto const writeIdx = m_writer.tellp();
 | 
				
			||||||
		MetalClawWriter<Writer> writer(m_writer, ox::Optional<int>(ox::in_place, val.idx()));
 | 
							MetalClawWriter<Writer> writer(m_writer, ox::Optional<int>(ox::in_place, val.idx()));
 | 
				
			||||||
		ModelHandlerInterface handler{&writer};
 | 
							ModelHandlerInterface handler{&writer};
 | 
				
			||||||
		oxReturnError(model(&handler, val.get()));
 | 
							OX_RETURN_ERROR(model(&handler, val.get()));
 | 
				
			||||||
		oxReturnError(writer.finalize());
 | 
							OX_RETURN_ERROR(writer.finalize());
 | 
				
			||||||
		fieldSet = writeIdx != m_writer.tellp();
 | 
							fieldSet = writeIdx != m_writer.tellp();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
						OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -298,21 +303,23 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val, std::s
 | 
				
			|||||||
	if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
 | 
						if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
 | 
				
			||||||
		// write the length
 | 
							// write the length
 | 
				
			||||||
		const auto arrLen = mc::encodeInteger(len);
 | 
							const auto arrLen = mc::encodeInteger(len);
 | 
				
			||||||
		oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length));
 | 
							OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
 | 
				
			||||||
		auto const writeIdx = m_writer.tellp();
 | 
							auto const writeIdx = m_writer.tellp();
 | 
				
			||||||
		MetalClawWriter<Writer> writer(m_writer);
 | 
							MetalClawWriter<Writer> writer(m_writer);
 | 
				
			||||||
		ModelHandlerInterface handler{&writer};
 | 
							ModelHandlerInterface handler{&writer};
 | 
				
			||||||
		oxReturnError(handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len)));
 | 
							OX_RETURN_ERROR(handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len)));
 | 
				
			||||||
		// write the array
 | 
							// write the array
 | 
				
			||||||
		for (std::size_t i = 0; i < len; ++i) {
 | 
							for (std::size_t i = 0; i < len; ++i) {
 | 
				
			||||||
			oxReturnError(handler.field("", &val[i]));
 | 
					OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
 | 
								OX_RETURN_ERROR(handler.field("", &val[i]));
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		oxReturnError(writer.finalize());
 | 
							OX_RETURN_ERROR(writer.finalize());
 | 
				
			||||||
		fieldSet = writeIdx != m_writer.tellp();
 | 
							fieldSet = writeIdx != m_writer.tellp();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
						OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Writer_c Writer>
 | 
					template<Writer_c Writer>
 | 
				
			||||||
@@ -324,32 +331,32 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const HashMap<String
 | 
				
			|||||||
	if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
 | 
						if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
 | 
				
			||||||
		// write the length
 | 
							// write the length
 | 
				
			||||||
		const auto arrLen = mc::encodeInteger(len);
 | 
							const auto arrLen = mc::encodeInteger(len);
 | 
				
			||||||
		oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length));
 | 
							OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
 | 
				
			||||||
		// write map
 | 
							// write map
 | 
				
			||||||
		MetalClawWriter<Writer> writer(m_writer);
 | 
							MetalClawWriter<Writer> writer(m_writer);
 | 
				
			||||||
		ModelHandlerInterface handler{&writer};
 | 
							ModelHandlerInterface handler{&writer};
 | 
				
			||||||
		// double len for both key and value
 | 
							// double len for both key and value
 | 
				
			||||||
		oxReturnError(handler.setTypeInfo("Map", 0, {}, len * 2));
 | 
							OX_RETURN_ERROR(handler.setTypeInfo("Map", 0, {}, len * 2));
 | 
				
			||||||
		// this loop body needs to be in a lambda because of the potential alloca call
 | 
							// this loop body needs to be in a lambda because of the potential alloca call
 | 
				
			||||||
		constexpr auto loopBody = [](auto &handler, auto const&key, auto const&val) -> ox::Error {
 | 
							constexpr auto loopBody = [](auto &handler, auto const&key, auto const&val) -> ox::Error {
 | 
				
			||||||
			const auto keyLen = key.len();
 | 
								const auto keyLen = key.size();
 | 
				
			||||||
			auto wkey = ox_malloca(keyLen + 1, char, 0);
 | 
								auto wkey = ox_malloca(keyLen + 1, char, 0);
 | 
				
			||||||
			memcpy(wkey.get(), key.c_str(), keyLen + 1);
 | 
								memcpy(wkey.get(), key.c_str(), keyLen + 1);
 | 
				
			||||||
			oxReturnError(handler.fieldCString("", wkey.get(), keyLen));
 | 
								OX_RETURN_ERROR(handler.fieldCString("", wkey.get(), keyLen));
 | 
				
			||||||
			oxRequireM(value, val.at(key));
 | 
								OX_REQUIRE_M(value, val.at(key));
 | 
				
			||||||
			return handler.field("", value);
 | 
								return handler.field("", value);
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		// write the array
 | 
							// write the array
 | 
				
			||||||
		for (std::size_t i = 0; i < len; ++i) {
 | 
							for (std::size_t i = 0; i < len; ++i) {
 | 
				
			||||||
			auto const&key = keys[i];
 | 
								auto const&key = keys[i];
 | 
				
			||||||
			oxReturnError(loopBody(handler, key, *val));
 | 
								OX_RETURN_ERROR(loopBody(handler, key, *val));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		oxReturnError(writer.finalize());
 | 
							OX_RETURN_ERROR(writer.finalize());
 | 
				
			||||||
		fieldSet = true;
 | 
							fieldSet = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
						OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
 | 
				
			||||||
	++m_field;
 | 
						++m_field;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<Writer_c Writer>
 | 
					template<Writer_c Writer>
 | 
				
			||||||
@@ -360,7 +367,7 @@ constexpr ox::Error MetalClawWriter<Writer>::setTypeInfo(
 | 
				
			|||||||
		const Vector<String>&,
 | 
							const Vector<String>&,
 | 
				
			||||||
		std::size_t fields) noexcept {
 | 
							std::size_t fields) noexcept {
 | 
				
			||||||
	const auto fieldPresenceLen = (fields - 1) / 8 + 1;
 | 
						const auto fieldPresenceLen = (fields - 1) / 8 + 1;
 | 
				
			||||||
	oxReturnError(m_writer.write(nullptr, fieldPresenceLen));
 | 
						OX_RETURN_ERROR(m_writer.write(nullptr, fieldPresenceLen));
 | 
				
			||||||
	m_presenceMapBuff.resize(fieldPresenceLen);
 | 
						m_presenceMapBuff.resize(fieldPresenceLen);
 | 
				
			||||||
	m_fieldPresence.setBuffer(m_presenceMapBuff.data(), m_presenceMapBuff.size());
 | 
						m_fieldPresence.setBuffer(m_presenceMapBuff.data(), m_presenceMapBuff.size());
 | 
				
			||||||
	m_fieldPresence.setFields(static_cast<int>(fields));
 | 
						m_fieldPresence.setFields(static_cast<int>(fields));
 | 
				
			||||||
@@ -370,33 +377,33 @@ constexpr ox::Error MetalClawWriter<Writer>::setTypeInfo(
 | 
				
			|||||||
template<Writer_c Writer>
 | 
					template<Writer_c Writer>
 | 
				
			||||||
ox::Error MetalClawWriter<Writer>::finalize() noexcept {
 | 
					ox::Error MetalClawWriter<Writer>::finalize() noexcept {
 | 
				
			||||||
	const auto end = m_writer.tellp();
 | 
						const auto end = m_writer.tellp();
 | 
				
			||||||
	oxReturnError(m_writer.seekp(m_writerBeginP));
 | 
						OX_RETURN_ERROR(m_writer.seekp(m_writerBeginP));
 | 
				
			||||||
	oxReturnError(m_writer.write(
 | 
						OX_RETURN_ERROR(m_writer.write(
 | 
				
			||||||
			reinterpret_cast<const char*>(m_presenceMapBuff.data()),
 | 
								reinterpret_cast<const char*>(m_presenceMapBuff.data()),
 | 
				
			||||||
			m_presenceMapBuff.size()));
 | 
								m_presenceMapBuff.size()));
 | 
				
			||||||
	oxReturnError(m_writer.seekp(end));
 | 
						OX_RETURN_ERROR(m_writer.seekp(end));
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<Buffer> writeMC(Writer_c auto &writer, const auto &val) noexcept {
 | 
					Result<Buffer> writeMC(Writer_c auto &writer, const auto &val) noexcept {
 | 
				
			||||||
	MetalClawWriter mcWriter(writer);
 | 
						MetalClawWriter mcWriter(writer);
 | 
				
			||||||
	ModelHandlerInterface handler{&mcWriter};
 | 
						ModelHandlerInterface handler{&mcWriter};
 | 
				
			||||||
	oxReturnError(model(&handler, &val));
 | 
						OX_RETURN_ERROR(model(&handler, &val));
 | 
				
			||||||
	oxReturnError(mcWriter.finalize());
 | 
						OX_RETURN_ERROR(mcWriter.finalize());
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<Buffer> writeMC(auto const&val, std::size_t buffReserveSz = 2 * units::KB) noexcept {
 | 
					Result<Buffer> writeMC(auto const&val, std::size_t buffReserveSz = 2 * units::KB) noexcept {
 | 
				
			||||||
	Buffer buff(buffReserveSz);
 | 
						Buffer buff(buffReserveSz);
 | 
				
			||||||
	BufferWriter bw(&buff, 0);
 | 
						BufferWriter bw(&buff, 0);
 | 
				
			||||||
	oxReturnError(writeMC(bw, val));
 | 
						OX_RETURN_ERROR(writeMC(bw, val));
 | 
				
			||||||
	buff.resize(bw.tellp());
 | 
						buff.resize(bw.tellp());
 | 
				
			||||||
	return buff;
 | 
						return buff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error writeMC(char *buff, std::size_t buffLen, auto const&val, std::size_t *sizeOut = nullptr) noexcept {
 | 
					Error writeMC(char *buff, std::size_t buffLen, auto const&val, std::size_t *sizeOut = nullptr) noexcept {
 | 
				
			||||||
	CharBuffWriter bw(buff, buffLen);
 | 
						CharBuffWriter bw{{buff, buffLen}};
 | 
				
			||||||
	oxReturnError(writeMC(bw, val));
 | 
						OX_RETURN_ERROR(writeMC(bw, val));
 | 
				
			||||||
	if (sizeOut) {
 | 
						if (sizeOut) {
 | 
				
			||||||
		*sizeOut = bw.tellp();
 | 
							*sizeOut = bw.tellp();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								deps/ox/src/ox/model/def.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								deps/ox/src/ox/model/def.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -11,9 +11,9 @@
 | 
				
			|||||||
#include <ox/std/concepts.hpp>
 | 
					#include <ox/std/concepts.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// oxModelFwdDecl is necessary because Apple-Clang is broken...
 | 
					// oxModelFwdDecl is necessary because Apple-Clang is broken...
 | 
				
			||||||
#define oxModelFwdDecl(modelName) constexpr ox::Error model(auto *io, ox::CommonPtrWith<modelName> auto *o) noexcept
 | 
					#define OX_MODEL_FWD_DECL(modelName) constexpr ox::Error model(auto *io, ox::CommonPtrWith<modelName> auto *o) noexcept
 | 
				
			||||||
#define oxModelBegin(modelName) constexpr ox::Error model(auto *io, [[maybe_unused]] ox::CommonPtrWith<modelName> auto *o) noexcept { oxReturnError(io->template setTypeInfo<modelName>());
 | 
					#define OX_MODEL_BEGIN(modelName) constexpr ox::Error model(auto *io, [[maybe_unused]] ox::CommonPtrWith<modelName> auto *o) noexcept { OX_RETURN_ERROR(io->template setTypeInfo<modelName>());
 | 
				
			||||||
#define oxModelEnd() return OxError(0); }
 | 
					#define OX_MODEL_END() return {}; }
 | 
				
			||||||
#define oxModelField(fieldName) oxReturnError(io->field(#fieldName, &o->fieldName));
 | 
					#define OX_MODEL_FIELD(fieldName) OX_RETURN_ERROR(io->field(#fieldName, &o->fieldName));
 | 
				
			||||||
#define oxModelFieldRename(objFieldName, serFieldName) oxReturnError(io->field(#serFieldName, &o->objFieldName));
 | 
					#define OX_MODEL_FIELD_RENAME(objFieldName, serFieldName) OX_RETURN_ERROR(io->field(#serFieldName, &o->objFieldName));
 | 
				
			||||||
#define oxModelFriend(modelName) friend constexpr ox::Error model(auto *io, ox::CommonPtrWith<modelName> auto *o) noexcept
 | 
					#define OX_MODEL_FRIEND(modelName) friend constexpr ox::Error model(auto *io, ox::CommonPtrWith<modelName> auto *o) noexcept
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/model/descread.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/model/descread.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/model/desctypes.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/model/desctypes.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										59
									
								
								deps/ox/src/ox/model/desctypes.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										59
									
								
								deps/ox/src/ox/model/desctypes.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -35,7 +35,7 @@ constexpr auto buildTypeId() noexcept {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static constexpr auto buildTypeId(
 | 
					static constexpr auto buildTypeId(
 | 
				
			||||||
		CRStringView name, int version,
 | 
							StringViewCR name, int version,
 | 
				
			||||||
		const TypeParamPack &typeParams = {}) noexcept {
 | 
							const TypeParamPack &typeParams = {}) noexcept {
 | 
				
			||||||
	String tp;
 | 
						String tp;
 | 
				
			||||||
	if (!typeParams.empty()) {
 | 
						if (!typeParams.empty()) {
 | 
				
			||||||
@@ -43,7 +43,7 @@ static constexpr auto buildTypeId(
 | 
				
			|||||||
		for (const auto &p : typeParams) {
 | 
							for (const auto &p : typeParams) {
 | 
				
			||||||
			tp += p + ",";
 | 
								tp += p + ",";
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		tp.resize(tp.len() - 1);
 | 
							tp.resize(tp.size() - 1);
 | 
				
			||||||
		tp += "#";
 | 
							tp += "#";
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ox::sfmt("{}{};{}", name, tp, version);
 | 
						return ox::sfmt("{}{};{}", name, tp, version);
 | 
				
			||||||
@@ -76,21 +76,21 @@ struct Subscript {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr Error model(T *io, CommonPtrWith<Subscript> auto *type) noexcept {
 | 
					constexpr Error model(T *io, CommonPtrWith<Subscript> auto *type) noexcept {
 | 
				
			||||||
	oxReturnError(io->template setTypeInfo<Subscript>());
 | 
						OX_RETURN_ERROR(io->template setTypeInfo<Subscript>());
 | 
				
			||||||
	if constexpr(T::opType() == OpType::Reflect) {
 | 
						if constexpr(T::opType() == OpType::Reflect) {
 | 
				
			||||||
		uint32_t st = 0;
 | 
							uint32_t st = 0;
 | 
				
			||||||
		oxReturnError(io->field("subscriptType", &st));
 | 
							OX_RETURN_ERROR(io->field("subscriptType", &st));
 | 
				
			||||||
	} else if constexpr(T::opType() == OpType::Write) {
 | 
						} else if constexpr(T::opType() == OpType::Write) {
 | 
				
			||||||
		auto pt = type ? static_cast<uint8_t>(type->subscriptType) : 0;
 | 
							auto pt = type ? static_cast<uint8_t>(type->subscriptType) : 0;
 | 
				
			||||||
		oxReturnError(io->field("subscriptType", &pt));
 | 
							OX_RETURN_ERROR(io->field("subscriptType", &pt));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		auto pt = type ? static_cast<uint32_t>(type->subscriptType) : 0;
 | 
							auto pt = type ? static_cast<uint32_t>(type->subscriptType) : 0;
 | 
				
			||||||
		oxReturnError(io->field("subscriptType", &pt));
 | 
							OX_RETURN_ERROR(io->field("subscriptType", &pt));
 | 
				
			||||||
		type->subscriptType = static_cast<Subscript::SubscriptType>(pt);
 | 
							type->subscriptType = static_cast<Subscript::SubscriptType>(pt);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(io->field("length", &type->length));
 | 
						OX_RETURN_ERROR(io->field("length", &type->length));
 | 
				
			||||||
	oxReturnError(io->field("smallSzLen", &type->smallSzLen));
 | 
						OX_RETURN_ERROR(io->field("smallSzLen", &type->smallSzLen));
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using SubscriptStack = Vector<Subscript, 3>;
 | 
					using SubscriptStack = Vector<Subscript, 3>;
 | 
				
			||||||
@@ -119,6 +119,7 @@ struct DescriptorField {
 | 
				
			|||||||
		subscriptLevels(pSubscriptLevels),
 | 
							subscriptLevels(pSubscriptLevels),
 | 
				
			||||||
		subscriptStack(std::move(pSubscriptType)),
 | 
							subscriptStack(std::move(pSubscriptType)),
 | 
				
			||||||
		typeId(std::move(pTypeId)) {
 | 
							typeId(std::move(pTypeId)) {
 | 
				
			||||||
 | 
							oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "Subscript level mismatch");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constexpr DescriptorField(const DescriptorField &other) noexcept:
 | 
						constexpr DescriptorField(const DescriptorField &other) noexcept:
 | 
				
			||||||
@@ -184,38 +185,38 @@ constexpr auto buildTypeId(const DescriptorType &t) noexcept {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr Error model(T *io, CommonPtrWith<DescriptorType> auto *type) noexcept {
 | 
					constexpr Error model(T *io, CommonPtrWith<DescriptorType> auto *type) noexcept {
 | 
				
			||||||
	oxReturnError(io->template setTypeInfo<DescriptorType>());
 | 
						OX_RETURN_ERROR(io->template setTypeInfo<DescriptorType>());
 | 
				
			||||||
	oxReturnError(io->field("typeName", &type->typeName));
 | 
						OX_RETURN_ERROR(io->field("typeName", &type->typeName));
 | 
				
			||||||
	oxReturnError(io->field("typeVersion", &type->typeVersion));
 | 
						OX_RETURN_ERROR(io->field("typeVersion", &type->typeVersion));
 | 
				
			||||||
	if constexpr(T::opType() == OpType::Reflect) {
 | 
						if constexpr(T::opType() == OpType::Reflect) {
 | 
				
			||||||
		uint8_t pt = 0;
 | 
							uint8_t pt = 0;
 | 
				
			||||||
		oxReturnError(io->field("primitiveType", &pt));
 | 
							OX_RETURN_ERROR(io->field("primitiveType", &pt));
 | 
				
			||||||
	} else if constexpr(T::opType() == OpType::Write) {
 | 
						} else if constexpr(T::opType() == OpType::Write) {
 | 
				
			||||||
		auto pt = type ? static_cast<uint8_t>(type->primitiveType) : 0;
 | 
							auto pt = type ? static_cast<uint8_t>(type->primitiveType) : 0;
 | 
				
			||||||
		oxReturnError(io->field("primitiveType", &pt));
 | 
							OX_RETURN_ERROR(io->field("primitiveType", &pt));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		auto pt = type ? static_cast<uint8_t>(type->primitiveType) : 0;
 | 
							auto pt = type ? static_cast<uint8_t>(type->primitiveType) : 0;
 | 
				
			||||||
		oxReturnError(io->field("primitiveType", &pt));
 | 
							OX_RETURN_ERROR(io->field("primitiveType", &pt));
 | 
				
			||||||
		type->primitiveType = static_cast<PrimitiveType>(pt);
 | 
							type->primitiveType = static_cast<PrimitiveType>(pt);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(io->field("typeParams", &type->typeParams));
 | 
						OX_RETURN_ERROR(io->field("typeParams", &type->typeParams));
 | 
				
			||||||
	oxReturnError(io->field("fieldList", &type->fieldList));
 | 
						OX_RETURN_ERROR(io->field("fieldList", &type->fieldList));
 | 
				
			||||||
	oxReturnError(io->field("length", &type->length));
 | 
						OX_RETURN_ERROR(io->field("length", &type->length));
 | 
				
			||||||
	oxReturnError(io->field("preloadable", &type->preloadable));
 | 
						OX_RETURN_ERROR(io->field("preloadable", &type->preloadable));
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr Error model(T *io, CommonPtrWith<DescriptorField> auto *field) noexcept {
 | 
					constexpr Error model(T *io, CommonPtrWith<DescriptorField> auto *field) noexcept {
 | 
				
			||||||
	oxReturnError(io->template setTypeInfo<DescriptorField>());
 | 
						OX_RETURN_ERROR(io->template setTypeInfo<DescriptorField>());
 | 
				
			||||||
	oxReturnError(io->field("typeId", &field->typeId));
 | 
						OX_RETURN_ERROR(io->field("typeId", &field->typeId));
 | 
				
			||||||
	oxReturnError(io->field("fieldName", &field->fieldName));
 | 
						OX_RETURN_ERROR(io->field("fieldName", &field->fieldName));
 | 
				
			||||||
	oxReturnError(io->field("subscriptLevels", &field->subscriptLevels));
 | 
						OX_RETURN_ERROR(io->field("subscriptLevels", &field->subscriptLevels));
 | 
				
			||||||
	oxReturnError(io->field("subscriptStack", &field->subscriptStack));
 | 
						OX_RETURN_ERROR(io->field("subscriptStack", &field->subscriptStack));
 | 
				
			||||||
	// defaultValue is unused now, but leave placeholder for backwards compatibility
 | 
						// defaultValue is unused now, but leave placeholder for backwards compatibility
 | 
				
			||||||
	int defaultValue = 0;
 | 
						int defaultValue = 0;
 | 
				
			||||||
	oxReturnError(io->field("defaultValue", &defaultValue));
 | 
						OX_RETURN_ERROR(io->field("defaultValue", &defaultValue));
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename ReaderBase>
 | 
					template<typename ReaderBase>
 | 
				
			||||||
@@ -243,7 +244,7 @@ constexpr Error model(TypeDescReader<T> *io, CommonPtrWith<DescriptorField> auto
 | 
				
			|||||||
	// defaultValue is unused now, but placeholder for backwards compatibility
 | 
						// defaultValue is unused now, but placeholder for backwards compatibility
 | 
				
			||||||
	int defaultValue = 0;
 | 
						int defaultValue = 0;
 | 
				
			||||||
	oxReturnError(io->field("defaultValue", &defaultValue));
 | 
						oxReturnError(io->field("defaultValue", &defaultValue));
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/model/descwrite.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/model/descwrite.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										77
									
								
								deps/ox/src/ox/model/descwrite.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										77
									
								
								deps/ox/src/ox/model/descwrite.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -91,23 +91,29 @@ class TypeDescWriter {
 | 
				
			|||||||
		constexpr ~TypeDescWriter() noexcept = default;
 | 
							constexpr ~TypeDescWriter() noexcept = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename T = std::nullptr_t>
 | 
							template<typename T = std::nullptr_t>
 | 
				
			||||||
		constexpr ox::Error setTypeInfo(CRStringView name = T::TypeName,
 | 
							constexpr ox::Error setTypeInfo(StringViewCR name = T::TypeName,
 | 
				
			||||||
		                                int version = T::TypeVersion,
 | 
							                                int version = T::TypeVersion,
 | 
				
			||||||
		                                const TypeParamPack &typeParams = {},
 | 
							                                const TypeParamPack &typeParams = {},
 | 
				
			||||||
		                                std::size_t fields = ModelFieldCount_v<T>) noexcept;
 | 
							                                std::size_t fields = ModelFieldCount_v<T>) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename T>
 | 
							template<typename T>
 | 
				
			||||||
		constexpr Error field(CRStringView name, const T *val, std::size_t valLen,
 | 
							constexpr Error field(
 | 
				
			||||||
		                      const SubscriptStack &subscriptStack = {}) noexcept;
 | 
									StringViewCR name,
 | 
				
			||||||
 | 
									T const*val,
 | 
				
			||||||
		template<typename T, bool force>
 | 
									std::size_t valLen,
 | 
				
			||||||
		constexpr Error field(CRStringView name, UnionView<T, force> val) noexcept;
 | 
									SubscriptStack const&subscriptStack) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename T>
 | 
							template<typename T>
 | 
				
			||||||
		constexpr Error field(CRStringView name, const T *val) noexcept;
 | 
							constexpr Error field(StringViewCR name, T const*val, std::size_t valLen) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							template<typename T, bool force>
 | 
				
			||||||
 | 
							constexpr Error field(StringViewCR name, UnionView<T, force> val) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							template<typename T>
 | 
				
			||||||
 | 
							constexpr Error field(StringViewCR name, const T *val) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename ...Args>
 | 
							template<typename ...Args>
 | 
				
			||||||
		constexpr Error fieldCString(CRStringView name, Args&&...) noexcept;
 | 
							constexpr Error fieldCString(StringViewCR name, Args&&...) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		constexpr DescriptorType *definition() noexcept {
 | 
							constexpr DescriptorType *definition() noexcept {
 | 
				
			||||||
@@ -167,7 +173,7 @@ class TypeDescWriter {
 | 
				
			|||||||
		constexpr const DescriptorType *type(UnionView<U> val) const noexcept;
 | 
							constexpr const DescriptorType *type(UnionView<U> val) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		constexpr const DescriptorType *getType(CRStringView tn, int typeVersion, PrimitiveType t, int b,
 | 
							constexpr const DescriptorType *getType(StringViewCR tn, int typeVersion, PrimitiveType t, int b,
 | 
				
			||||||
		                                        const TypeParamPack &typeParams = {}) const noexcept;
 | 
							                                        const TypeParamPack &typeParams = {}) const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -176,7 +182,7 @@ constexpr TypeDescWriter::TypeDescWriter(TypeStore *typeStore) noexcept: m_typeS
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr ox::Error TypeDescWriter::setTypeInfo(
 | 
					constexpr ox::Error TypeDescWriter::setTypeInfo(
 | 
				
			||||||
		CRStringView typeName, int typeVersion,
 | 
							StringViewCR typeName, int typeVersion,
 | 
				
			||||||
		const TypeParamPack &typeParams, std::size_t) noexcept {
 | 
							const TypeParamPack &typeParams, std::size_t) noexcept {
 | 
				
			||||||
	PrimitiveType pt;
 | 
						PrimitiveType pt;
 | 
				
			||||||
	if constexpr(is_union_v<T>) {
 | 
						if constexpr(is_union_v<T>) {
 | 
				
			||||||
@@ -193,30 +199,45 @@ constexpr ox::Error TypeDescWriter::setTypeInfo(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// array handler
 | 
					// array handler
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr Error TypeDescWriter::field(CRStringView name, const T*, std::size_t, const SubscriptStack &subscriptStack) noexcept {
 | 
					constexpr Error TypeDescWriter::field(StringViewCR name, T const*, std::size_t, SubscriptStack const&subscriptStack) noexcept {
 | 
				
			||||||
	if (m_type) {
 | 
						if (m_type) {
 | 
				
			||||||
		constexpr typename remove_pointer<T>::type *p = nullptr;
 | 
							constexpr typename remove_pointer<T>::type *p = nullptr;
 | 
				
			||||||
		const auto t = type(p);
 | 
							const auto t = type(p);
 | 
				
			||||||
		oxAssert(t != nullptr, "field(const char *name, T *val, std::size_t): Type not found or generated");
 | 
							oxAssert(t != nullptr, "field(const char *name, T *val, std::size_t): Type not found or generated");
 | 
				
			||||||
		m_type->fieldList.emplace_back(t, String(name), detail::indirectionLevels_v<T> + 1, subscriptStack, buildTypeId(*t));
 | 
							m_type->fieldList.emplace_back(t, String(name), detail::indirectionLevels_v<T> + 1, subscriptStack, buildTypeId(*t));
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1);
 | 
						return ox::Error(1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// array handler
 | 
				
			||||||
 | 
					template<typename T>
 | 
				
			||||||
 | 
					constexpr Error TypeDescWriter::field(StringViewCR name, T const*, std::size_t) noexcept {
 | 
				
			||||||
 | 
						if (m_type) {
 | 
				
			||||||
 | 
							constexpr typename remove_pointer<T>::type *p = nullptr;
 | 
				
			||||||
 | 
							const auto t = type(p);
 | 
				
			||||||
 | 
							oxAssert(t != nullptr, "field(const char *name, T *val, std::size_t): Type not found or generated");
 | 
				
			||||||
 | 
							auto const lvls = detail::indirectionLevels_v<T> + 1;
 | 
				
			||||||
 | 
							SubscriptStack subscriptStack{lvls};
 | 
				
			||||||
 | 
							m_type->fieldList.emplace_back(t, String(name), lvls, subscriptStack, buildTypeId(*t));
 | 
				
			||||||
 | 
							return {};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ox::Error(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T, bool force>
 | 
					template<typename T, bool force>
 | 
				
			||||||
constexpr Error TypeDescWriter::field(CRStringView name, UnionView<T, force> val) noexcept {
 | 
					constexpr Error TypeDescWriter::field(StringViewCR name, UnionView<T, force> val) noexcept {
 | 
				
			||||||
	if (m_type) {
 | 
						if (m_type) {
 | 
				
			||||||
		const auto t = type(val);
 | 
							const auto t = type(val);
 | 
				
			||||||
		oxAssert(t != nullptr, "field(const char *name, T val): Type not found or generated");
 | 
							oxAssert(t != nullptr, "field(const char *name, T val): Type not found or generated");
 | 
				
			||||||
		m_type->fieldList.emplace_back(t, String(name), 0, SubscriptStack{}, ox::String(t->typeName));
 | 
							m_type->fieldList.emplace_back(t, String(name), 0, SubscriptStack{}, ox::String(t->typeName));
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1);
 | 
						return ox::Error(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr Error TypeDescWriter::field(CRStringView name, const T *val) noexcept {
 | 
					constexpr Error TypeDescWriter::field(StringViewCR name, const T *val) noexcept {
 | 
				
			||||||
	if (m_type) {
 | 
						if (m_type) {
 | 
				
			||||||
		if constexpr(isVector_v<T> || isArray_v<T>) {
 | 
							if constexpr(isVector_v<T> || isArray_v<T>) {
 | 
				
			||||||
			typename T::value_type *data = nullptr;
 | 
								typename T::value_type *data = nullptr;
 | 
				
			||||||
@@ -233,11 +254,11 @@ constexpr Error TypeDescWriter::field(CRStringView name, const T *val) noexcept
 | 
				
			|||||||
			return {};
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1);
 | 
						return ox::Error(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename ...Args>
 | 
					template<typename ...Args>
 | 
				
			||||||
constexpr Error TypeDescWriter::fieldCString(CRStringView name, Args&&...) noexcept {
 | 
					constexpr Error TypeDescWriter::fieldCString(StringViewCR name, Args&&...) noexcept {
 | 
				
			||||||
	constexpr auto s = "";
 | 
						constexpr auto s = "";
 | 
				
			||||||
	const auto t = type(s);
 | 
						const auto t = type(s);
 | 
				
			||||||
	m_type->fieldList.emplace_back(t, String(name), 0, SubscriptStack{}, ox::String(t->typeName));
 | 
						m_type->fieldList.emplace_back(t, String(name), 0, SubscriptStack{}, ox::String(t->typeName));
 | 
				
			||||||
@@ -339,7 +360,7 @@ constexpr const DescriptorType *TypeDescWriter::type(const IString<sz>*) const n
 | 
				
			|||||||
	return getType(types::BString, 0, PT, 0);
 | 
						return getType(types::BString, 0, PT, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr const DescriptorType *TypeDescWriter::getType(CRStringView tn, int typeVersion, PrimitiveType pt, int b,
 | 
					constexpr const DescriptorType *TypeDescWriter::getType(StringViewCR tn, int typeVersion, PrimitiveType pt, int b,
 | 
				
			||||||
                                                        const TypeParamPack &typeParams) const noexcept {
 | 
					                                                        const TypeParamPack &typeParams) const noexcept {
 | 
				
			||||||
	auto t = m_typeStore->get(tn, typeVersion, typeParams);
 | 
						auto t = m_typeStore->get(tn, typeVersion, typeParams);
 | 
				
			||||||
	if (!t.error) {
 | 
						if (!t.error) {
 | 
				
			||||||
@@ -357,26 +378,26 @@ constexpr const DescriptorType *TypeDescWriter::getType(CRStringView tn, int typ
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr Result<DescriptorType*> buildTypeDef(TypeStore *typeStore) noexcept {
 | 
					constexpr Result<DescriptorType*> buildTypeDef(TypeStore &typeStore) noexcept {
 | 
				
			||||||
	TypeDescWriter writer(typeStore);
 | 
						TypeDescWriter writer(&typeStore);
 | 
				
			||||||
	ModelHandlerInterface<TypeDescWriter, ox::OpType::Reflect> handler(&writer);
 | 
						ModelHandlerInterface<TypeDescWriter, ox::OpType::Reflect> handler(&writer);
 | 
				
			||||||
	if (std::is_constant_evaluated()) {
 | 
						if (std::is_constant_evaluated()) {
 | 
				
			||||||
		std::allocator<T> a;
 | 
							std::allocator<T> a;
 | 
				
			||||||
		T *t = a.allocate(1);
 | 
							T *t = a.allocate(1);
 | 
				
			||||||
		oxReturnError(model(&handler, t));
 | 
							OX_RETURN_ERROR(model(&handler, t));
 | 
				
			||||||
		a.deallocate(t, 1);
 | 
							a.deallocate(t, 1);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		auto t = ox_malloca(sizeof(T), T);
 | 
							auto t = ox_malloca(sizeof(T), T);
 | 
				
			||||||
		oxReturnError(model(&handler, t.get()));
 | 
							OX_RETURN_ERROR(model(&handler, t.get()));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return writer.definition();
 | 
						return writer.definition();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr Result<DescriptorType*> buildTypeDef(TypeStore *typeStore, T *val) noexcept {
 | 
					constexpr Result<DescriptorType*> buildTypeDef(TypeStore &typeStore, T &val) noexcept {
 | 
				
			||||||
	TypeDescWriter writer(typeStore);
 | 
						TypeDescWriter writer(&typeStore);
 | 
				
			||||||
	ModelHandlerInterface<TypeDescWriter, ox::OpType::Reflect> handler(&writer);
 | 
						ModelHandlerInterface<TypeDescWriter, ox::OpType::Reflect> handler(&writer);
 | 
				
			||||||
	oxReturnError(model(&handler, val));
 | 
						OX_RETURN_ERROR(model(&handler, &val));
 | 
				
			||||||
	return writer.definition();
 | 
						return writer.definition();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								deps/ox/src/ox/model/fieldcounter.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								deps/ox/src/ox/model/fieldcounter.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -24,32 +24,32 @@ class FieldCounter {
 | 
				
			|||||||
		std::size_t fields = 0;
 | 
							std::size_t fields = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename U = std::nullptr_t>
 | 
							template<typename U = std::nullptr_t>
 | 
				
			||||||
		constexpr ox::Error setTypeInfo(CRStringView = "", int = 0, const Vector<String>& = {}, std::size_t = 0) {
 | 
							constexpr ox::Error setTypeInfo(StringViewCR = "", int = 0, const Vector<String>& = {}, std::size_t = 0) {
 | 
				
			||||||
			return {};
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename U>
 | 
							template<typename U>
 | 
				
			||||||
		constexpr ox::Error field(CRStringView, U) noexcept {
 | 
							constexpr ox::Error field(StringViewCR, U) noexcept {
 | 
				
			||||||
			++fields;
 | 
								++fields;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename U>
 | 
							template<typename U>
 | 
				
			||||||
		constexpr ox::Error field(CRStringView, U, std::size_t) noexcept {
 | 
							constexpr ox::Error field(StringViewCR, U, std::size_t) noexcept {
 | 
				
			||||||
			++fields;
 | 
								++fields;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename U, typename Handler>
 | 
							template<typename U, typename Handler>
 | 
				
			||||||
		constexpr Error field(CRStringView, Handler) {
 | 
							constexpr Error field(StringViewCR, Handler) {
 | 
				
			||||||
			++fields;
 | 
								++fields;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename ...Args>
 | 
							template<typename ...Args>
 | 
				
			||||||
		constexpr Error fieldCString(Args&&...) noexcept {
 | 
							constexpr Error fieldCString(Args&&...) noexcept {
 | 
				
			||||||
			++fields;
 | 
								++fields;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static constexpr auto opType() noexcept {
 | 
							static constexpr auto opType() noexcept {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/model/metadata.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/model/metadata.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/model/model.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/model/model.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								deps/ox/src/ox/model/modelhandleradaptor.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								deps/ox/src/ox/model/modelhandleradaptor.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -135,8 +135,8 @@ class ModelHandlerInterface {
 | 
				
			|||||||
					return m_handler->field(name, &v->template get<ModelValueArray>());
 | 
										return m_handler->field(name, &v->template get<ModelValueArray>());
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			oxErrf("invalid type: {}: {}\n", name, static_cast<int>(v->type()));
 | 
								oxErrf("invalid type: {}: {}\n", name, static_cast<int>(v->type()));
 | 
				
			||||||
			oxPanic(OxError(1), "invalid type");
 | 
								oxPanic(ox::Error(1), "invalid type");
 | 
				
			||||||
			return OxError(1, "invalid type");
 | 
								return ox::Error(1, "invalid type");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// array handler, with callback to allow handling individual elements
 | 
							// array handler, with callback to allow handling individual elements
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										32
									
								
								deps/ox/src/ox/model/modelops.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								deps/ox/src/ox/model/modelops.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -56,19 +56,19 @@ class MemberList {
 | 
				
			|||||||
		template<typename T>
 | 
							template<typename T>
 | 
				
			||||||
		constexpr Error field(const char*, T *v) noexcept {
 | 
							constexpr Error field(const char*, T *v) noexcept {
 | 
				
			||||||
			vars[m_i++] = static_cast<void*>(v);
 | 
								vars[m_i++] = static_cast<void*>(v);
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename T>
 | 
							template<typename T>
 | 
				
			||||||
		constexpr Error field(const char*, T *v, int) noexcept {
 | 
							constexpr Error field(const char*, T *v, int) noexcept {
 | 
				
			||||||
			vars[m_i++] = static_cast<void*>(v);
 | 
								vars[m_i++] = static_cast<void*>(v);
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename U, bool force = false>
 | 
							template<typename U, bool force = false>
 | 
				
			||||||
		constexpr Error field(const char*, UnionView<U, force> u) noexcept {
 | 
							constexpr Error field(const char*, UnionView<U, force> u) noexcept {
 | 
				
			||||||
			vars[m_i++] = static_cast<void*>(u.get());
 | 
								vars[m_i++] = static_cast<void*>(u.get());
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename T>
 | 
							template<typename T>
 | 
				
			||||||
@@ -107,7 +107,7 @@ class Copier {
 | 
				
			|||||||
				auto &dst = *cbit_cast<FT*>(m_dst->vars[m_i]);
 | 
									auto &dst = *cbit_cast<FT*>(m_dst->vars[m_i]);
 | 
				
			||||||
				dst = src;
 | 
									dst = src;
 | 
				
			||||||
				++m_i;
 | 
									++m_i;
 | 
				
			||||||
				return OxError(0);
 | 
									return {};
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -119,7 +119,7 @@ class Copier {
 | 
				
			|||||||
				dst = src;
 | 
									dst = src;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			++m_i;
 | 
								++m_i;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename U, bool force = false>
 | 
							template<typename U, bool force = false>
 | 
				
			||||||
@@ -128,7 +128,7 @@ class Copier {
 | 
				
			|||||||
			auto &src = *u.get();
 | 
								auto &src = *u.get();
 | 
				
			||||||
			dst = src;
 | 
								dst = src;
 | 
				
			||||||
			++m_i;
 | 
								++m_i;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename T = void>
 | 
							template<typename T = void>
 | 
				
			||||||
@@ -168,7 +168,7 @@ class Mover {
 | 
				
			|||||||
				dst = std::move(src);
 | 
									dst = std::move(src);
 | 
				
			||||||
				src = FT{};
 | 
									src = FT{};
 | 
				
			||||||
				++m_i;
 | 
									++m_i;
 | 
				
			||||||
				return OxError(0);
 | 
									return {};
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -181,7 +181,7 @@ class Mover {
 | 
				
			|||||||
				src = FT{};
 | 
									src = FT{};
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			++m_i;
 | 
								++m_i;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename U, bool force = false>
 | 
							template<typename U, bool force = false>
 | 
				
			||||||
@@ -190,7 +190,7 @@ class Mover {
 | 
				
			|||||||
			auto &src = *u.get();
 | 
								auto &src = *u.get();
 | 
				
			||||||
			dst = std::move(src);
 | 
								dst = std::move(src);
 | 
				
			||||||
			++m_i;
 | 
								++m_i;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename T = void>
 | 
							template<typename T = void>
 | 
				
			||||||
@@ -228,10 +228,10 @@ class Equals {
 | 
				
			|||||||
			const auto &dst = std::bit_cast<FT>(*m_other->vars[m_i]);
 | 
								const auto &dst = std::bit_cast<FT>(*m_other->vars[m_i]);
 | 
				
			||||||
			++m_i;
 | 
								++m_i;
 | 
				
			||||||
			if (dst == src) {
 | 
								if (dst == src) {
 | 
				
			||||||
				return OxError(0);
 | 
									return {};
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				this->value = false;
 | 
									this->value = false;
 | 
				
			||||||
				return OxError(1);
 | 
									return ox::Error(1);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -242,11 +242,11 @@ class Equals {
 | 
				
			|||||||
				const auto &dst = cbit_cast<FT*>(m_other->vars[m_i])[i];
 | 
									const auto &dst = cbit_cast<FT*>(m_other->vars[m_i])[i];
 | 
				
			||||||
				if (!(dst == src)) {
 | 
									if (!(dst == src)) {
 | 
				
			||||||
					this->value = false;
 | 
										this->value = false;
 | 
				
			||||||
					return OxError(1);
 | 
										return ox::Error(1);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			++m_i;
 | 
								++m_i;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename U, bool force = false>
 | 
							template<typename U, bool force = false>
 | 
				
			||||||
@@ -255,10 +255,10 @@ class Equals {
 | 
				
			|||||||
			const auto &src = *u.get();
 | 
								const auto &src = *u.get();
 | 
				
			||||||
			++m_i;
 | 
								++m_i;
 | 
				
			||||||
			if (dst == src) {
 | 
								if (dst == src) {
 | 
				
			||||||
				return OxError(0);
 | 
									return {};
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				this->value = false;
 | 
									this->value = false;
 | 
				
			||||||
				return OxError(1);
 | 
									return ox::Error(1);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								deps/ox/src/ox/model/modelvalue.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								deps/ox/src/ox/model/modelvalue.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -12,12 +12,12 @@ namespace ox {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static_assert([]() -> ox::Error {
 | 
					static_assert([]() -> ox::Error {
 | 
				
			||||||
	ox::ModelValue v;
 | 
						ox::ModelValue v;
 | 
				
			||||||
	oxReturnError(v.setType<int32_t>());
 | 
						OX_RETURN_ERROR(v.setType<int32_t>());
 | 
				
			||||||
	if (v.type() != ModelValue::Type::SignedInteger32) {
 | 
						if (v.type() != ModelValue::Type::SignedInteger32) {
 | 
				
			||||||
		return OxError(1, "type is wrong");
 | 
							return ox::Error(1, "type is wrong");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	//oxReturnError(v.set<int32_t>(5));
 | 
						//oxReturnError(v.set<int32_t>(5));
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}() == OxError(0));
 | 
					}() == ox::Error{});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										109
									
								
								deps/ox/src/ox/model/modelvalue.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								deps/ox/src/ox/model/modelvalue.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -168,7 +168,7 @@ class ModelValue {
 | 
				
			|||||||
		constexpr const auto &get() const noexcept {
 | 
							constexpr const auto &get() const noexcept {
 | 
				
			||||||
			constexpr auto type = getType<T>();
 | 
								constexpr auto type = getType<T>();
 | 
				
			||||||
			if (m_type != type) [[unlikely]] {
 | 
								if (m_type != type) [[unlikely]] {
 | 
				
			||||||
				oxPanic(OxError(1), "invalid cast");
 | 
									oxPanic(ox::Error(1), "invalid cast");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return getValue<type>(*this);
 | 
								return getValue<type>(*this);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -178,7 +178,7 @@ class ModelValue {
 | 
				
			|||||||
		constexpr auto &get() noexcept {
 | 
							constexpr auto &get() noexcept {
 | 
				
			||||||
			constexpr auto type = getType<T>();
 | 
								constexpr auto type = getType<T>();
 | 
				
			||||||
			if (m_type != type) [[unlikely]] {
 | 
								if (m_type != type) [[unlikely]] {
 | 
				
			||||||
				oxPanic(OxError(1), "invalid cast");
 | 
									oxPanic(ox::Error(1), "invalid cast");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return getValue<type>(*this);
 | 
								return getValue<type>(*this);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -188,8 +188,8 @@ class ModelValue {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		constexpr Error setType(
 | 
							constexpr Error setType(
 | 
				
			||||||
				DescriptorType const*type,
 | 
									DescriptorType const*type,
 | 
				
			||||||
				int subscriptLevels = 0,
 | 
									SubscriptStack const& = {},
 | 
				
			||||||
				SubscriptStack const& = {}) noexcept;
 | 
									int subscriptLevels = 0) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename T>
 | 
							template<typename T>
 | 
				
			||||||
		constexpr Error setType() noexcept;
 | 
							constexpr Error setType() noexcept;
 | 
				
			||||||
@@ -242,7 +242,7 @@ class ModelValueArray {
 | 
				
			|||||||
			m_vec.resize(sz);
 | 
								m_vec.resize(sz);
 | 
				
			||||||
			if (sz > oldSz) {
 | 
								if (sz > oldSz) {
 | 
				
			||||||
				for (auto i = oldSz; i < sz; ++i) {
 | 
									for (auto i = oldSz; i < sz; ++i) {
 | 
				
			||||||
					oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels));
 | 
										OX_RETURN_ERROR(m_vec[i].setType(m_type, m_subscriptStack, m_typeSubscriptLevels));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return {};
 | 
								return {};
 | 
				
			||||||
@@ -276,8 +276,9 @@ class ModelValueArray {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		constexpr Error setType(
 | 
							constexpr Error setType(
 | 
				
			||||||
				DescriptorType const*type,
 | 
									DescriptorType const*type,
 | 
				
			||||||
				int subscriptLevels,
 | 
									SubscriptStack subscriptStack,
 | 
				
			||||||
				SubscriptStack subscriptStack) noexcept {
 | 
									int subscriptLevels) noexcept {
 | 
				
			||||||
 | 
								oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
 | 
				
			||||||
			m_type = type;
 | 
								m_type = type;
 | 
				
			||||||
			m_typeSubscriptLevels = subscriptLevels;
 | 
								m_typeSubscriptLevels = subscriptLevels;
 | 
				
			||||||
			m_subscriptStack = std::move(subscriptStack);
 | 
								m_subscriptStack = std::move(subscriptStack);
 | 
				
			||||||
@@ -400,7 +401,7 @@ class ModelValueVector {
 | 
				
			|||||||
			m_vec.resize(sz);
 | 
								m_vec.resize(sz);
 | 
				
			||||||
			if (sz > oldSz) {
 | 
								if (sz > oldSz) {
 | 
				
			||||||
				for (auto i = oldSz; i < sz; ++i) {
 | 
									for (auto i = oldSz; i < sz; ++i) {
 | 
				
			||||||
					oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels, m_subscriptStack));
 | 
										OX_RETURN_ERROR(m_vec[i].setType(m_type, m_subscriptStack, m_typeSubscriptLevels));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return {};
 | 
								return {};
 | 
				
			||||||
@@ -418,8 +419,9 @@ class ModelValueVector {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		constexpr Error setType(
 | 
							constexpr Error setType(
 | 
				
			||||||
				DescriptorType const*type,
 | 
									DescriptorType const*type,
 | 
				
			||||||
				int subscriptLevels,
 | 
									SubscriptStack subscriptStack,
 | 
				
			||||||
				SubscriptStack subscriptStack) noexcept {
 | 
									int subscriptLevels) noexcept {
 | 
				
			||||||
 | 
								oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
 | 
				
			||||||
			m_type = type;
 | 
								m_type = type;
 | 
				
			||||||
			m_typeSubscriptLevels = subscriptLevels;
 | 
								m_typeSubscriptLevels = subscriptLevels;
 | 
				
			||||||
			m_subscriptStack = std::move(subscriptStack);
 | 
								m_subscriptStack = std::move(subscriptStack);
 | 
				
			||||||
@@ -517,7 +519,7 @@ class ModelObject {
 | 
				
			|||||||
			ModelValue value;
 | 
								ModelValue value;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	protected:
 | 
						protected:
 | 
				
			||||||
		oxModelFriend(ModelObject);
 | 
							OX_MODEL_FRIEND(ModelObject);
 | 
				
			||||||
		friend ModelValue;
 | 
							friend ModelValue;
 | 
				
			||||||
		Vector<UniquePtr<Field>> m_fieldsOrder;
 | 
							Vector<UniquePtr<Field>> m_fieldsOrder;
 | 
				
			||||||
		HashMap<String, ModelValue*> m_fields;
 | 
							HashMap<String, ModelValue*> m_fields;
 | 
				
			||||||
@@ -632,18 +634,18 @@ class ModelObject {
 | 
				
			|||||||
			if (m_fields.contains(k)) {
 | 
								if (m_fields.contains(k)) {
 | 
				
			||||||
				return *m_fields.at(k).value;
 | 
									return *m_fields.at(k).value;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename T>
 | 
							template<typename T>
 | 
				
			||||||
		constexpr Error set(const String &k, T &&val) noexcept {
 | 
							constexpr Error set(const String &k, T &&val) noexcept {
 | 
				
			||||||
			oxRequire(t, m_fields.at(k));
 | 
								OX_REQUIRE(t, m_fields.at(k));
 | 
				
			||||||
			*t = ox::forward<T>(val);
 | 
								*t = ox::forward<T>(val);
 | 
				
			||||||
			return {};
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept {
 | 
							constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept {
 | 
				
			||||||
			oxRequire(v, m_fields.at(k));
 | 
								OX_REQUIRE(v, m_fields.at(k));
 | 
				
			||||||
			return *v;
 | 
								return *v;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -652,7 +654,7 @@ class ModelObject {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		constexpr CRString typeName() const noexcept {
 | 
							constexpr StringCR typeName() const noexcept {
 | 
				
			||||||
			return m_type->typeName;
 | 
								return m_type->typeName;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -668,17 +670,17 @@ class ModelObject {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		constexpr Error setType(const DescriptorType *type) noexcept {
 | 
							constexpr Error setType(const DescriptorType *type) noexcept {
 | 
				
			||||||
			if (type->primitiveType != PrimitiveType::Struct && type->primitiveType != PrimitiveType::Union) {
 | 
								if (type->primitiveType != PrimitiveType::Struct && type->primitiveType != PrimitiveType::Union) {
 | 
				
			||||||
				return OxError(1, "Cannot load a non-struct type to ModelObject");
 | 
									return ox::Error(1, "Cannot load a non-struct type to ModelObject");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			m_type = type;
 | 
								m_type = type;
 | 
				
			||||||
			for (const auto &f : type->fieldList) {
 | 
								for (const auto &f : type->fieldList) {
 | 
				
			||||||
				auto field = make_unique<Field>();
 | 
									auto field = make_unique<Field>();
 | 
				
			||||||
				field->name = f.fieldName;
 | 
									field->name = f.fieldName;
 | 
				
			||||||
				oxReturnError(field->value.setType(f.type, f.subscriptLevels, f.subscriptStack));
 | 
									OX_RETURN_ERROR(field->value.setType(f.type, f.subscriptStack, f.subscriptLevels));
 | 
				
			||||||
				m_fields[field->name] = &field->value;
 | 
									m_fields[field->name] = &field->value;
 | 
				
			||||||
				m_fieldsOrder.emplace_back(std::move(field));
 | 
									m_fieldsOrder.emplace_back(std::move(field));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -720,7 +722,7 @@ class ModelUnion {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		static constexpr Result<UniquePtr<ModelUnion>> make(const DescriptorType *type) noexcept {
 | 
							static constexpr Result<UniquePtr<ModelUnion>> make(const DescriptorType *type) noexcept {
 | 
				
			||||||
			UniquePtr<ModelUnion> out(new ModelUnion);
 | 
								UniquePtr<ModelUnion> out(new ModelUnion);
 | 
				
			||||||
			oxReturnError(out->setType(type));
 | 
								OX_RETURN_ERROR(out->setType(type));
 | 
				
			||||||
			return out;
 | 
								return out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -729,7 +731,7 @@ class ModelUnion {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept {
 | 
							constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept {
 | 
				
			||||||
			oxRequire(v, m_fields.at(k));
 | 
								OX_REQUIRE(v, m_fields.at(k));
 | 
				
			||||||
			return &(*v)->value;
 | 
								return &(*v)->value;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -761,7 +763,7 @@ class ModelUnion {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		constexpr Result<const ModelValue*> get(StringView const&k) const noexcept {
 | 
							constexpr Result<const ModelValue*> get(StringView const&k) const noexcept {
 | 
				
			||||||
			oxRequire(t, m_fields.at(k));
 | 
								OX_REQUIRE(t, m_fields.at(k));
 | 
				
			||||||
			return &(*t)->value;
 | 
								return &(*t)->value;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -788,7 +790,7 @@ class ModelUnion {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		constexpr Error setType(const DescriptorType *type) noexcept {
 | 
							constexpr Error setType(const DescriptorType *type) noexcept {
 | 
				
			||||||
			if (type->primitiveType != PrimitiveType::Struct && type->primitiveType != PrimitiveType::Union) {
 | 
								if (type->primitiveType != PrimitiveType::Struct && type->primitiveType != PrimitiveType::Union) {
 | 
				
			||||||
				return OxError(1, "Cannot load a non-struct type to ModelUnion");
 | 
									return ox::Error(1, "Cannot load a non-struct type to ModelUnion");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			m_fields.clear();
 | 
								m_fields.clear();
 | 
				
			||||||
			m_fieldsOrder.clear();
 | 
								m_fieldsOrder.clear();
 | 
				
			||||||
@@ -797,12 +799,12 @@ class ModelUnion {
 | 
				
			|||||||
				auto field = make_unique<Field>();
 | 
									auto field = make_unique<Field>();
 | 
				
			||||||
				field->name = f.fieldName;
 | 
									field->name = f.fieldName;
 | 
				
			||||||
				field->idx = i;
 | 
									field->idx = i;
 | 
				
			||||||
				oxReturnError(field->value.setType(f.type, f.subscriptLevels));
 | 
									OX_RETURN_ERROR(field->value.setType(f.type, SubscriptStack{static_cast<size_t>(f.subscriptLevels)}, f.subscriptLevels));
 | 
				
			||||||
				m_fields[field->name] = field.get();
 | 
									m_fields[field->name] = field.get();
 | 
				
			||||||
				m_fieldsOrder.emplace_back(std::move(field));
 | 
									m_fieldsOrder.emplace_back(std::move(field));
 | 
				
			||||||
				++i;
 | 
									++i;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
@@ -965,21 +967,21 @@ constexpr std::size_t alignOf(const ModelValue &t) noexcept {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept {
 | 
					constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept {
 | 
				
			||||||
	oxReturnError(h->template setTypeInfo<ModelObject>(
 | 
						OX_RETURN_ERROR(h->template setTypeInfo<ModelObject>(
 | 
				
			||||||
			obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
 | 
								obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
 | 
				
			||||||
	for (auto &f : obj->m_fieldsOrder) {
 | 
						for (auto &f : obj->m_fieldsOrder) {
 | 
				
			||||||
		oxReturnError(h->field(f->name.c_str(), &f->value));
 | 
							OX_RETURN_ERROR(h->field(f->name.c_str(), &f->value));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept {
 | 
					constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept {
 | 
				
			||||||
	oxReturnError(h->template setTypeInfo<ModelUnion>(
 | 
						OX_RETURN_ERROR(h->template setTypeInfo<ModelUnion>(
 | 
				
			||||||
			obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
 | 
								obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
 | 
				
			||||||
	for (auto &f : obj->m_fieldsOrder) {
 | 
						for (auto &f : obj->m_fieldsOrder) {
 | 
				
			||||||
		oxReturnError(h->field(f->name.c_str(), &f->value));
 | 
							OX_RETURN_ERROR(h->field(f->name.c_str(), &f->value));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr ModelValue::ModelValue(const ModelValue &other) noexcept {
 | 
					constexpr ModelValue::ModelValue(const ModelValue &other) noexcept {
 | 
				
			||||||
@@ -995,7 +997,7 @@ constexpr ModelValue::ModelValue(const ModelValue &other) noexcept {
 | 
				
			|||||||
		case Type::SignedInteger16:
 | 
							case Type::SignedInteger16:
 | 
				
			||||||
		case Type::SignedInteger32:
 | 
							case Type::SignedInteger32:
 | 
				
			||||||
		case Type::SignedInteger64:
 | 
							case Type::SignedInteger64:
 | 
				
			||||||
			ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
 | 
								m_data = other.m_data;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case Type::String:
 | 
							case Type::String:
 | 
				
			||||||
			m_data.str = new String(other.get<String>());
 | 
								m_data.str = new String(other.get<String>());
 | 
				
			||||||
@@ -1028,8 +1030,8 @@ constexpr ModelValue::ModelValue(ModelValue &&other) noexcept {
 | 
				
			|||||||
		case Type::SignedInteger16:
 | 
							case Type::SignedInteger16:
 | 
				
			||||||
		case Type::SignedInteger32:
 | 
							case Type::SignedInteger32:
 | 
				
			||||||
		case Type::SignedInteger64:
 | 
							case Type::SignedInteger64:
 | 
				
			||||||
			ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
 | 
								m_data = other.m_data;
 | 
				
			||||||
			ox::memset(&other.m_data, 0, sizeof(m_data));
 | 
								other.m_data.ui64 = 0;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case Type::String:
 | 
							case Type::String:
 | 
				
			||||||
			m_data.str = other.m_data.str;
 | 
								m_data.str = other.m_data.str;
 | 
				
			||||||
@@ -1076,20 +1078,21 @@ constexpr ModelValue::Type ModelValue::type() const noexcept {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
constexpr Error ModelValue::setType(
 | 
					constexpr Error ModelValue::setType(
 | 
				
			||||||
		const DescriptorType *type,
 | 
							const DescriptorType *type,
 | 
				
			||||||
		int subscriptLevels,
 | 
							SubscriptStack const&subscriptStack,
 | 
				
			||||||
		SubscriptStack const&subscriptStack) noexcept {
 | 
							int subscriptLevels) noexcept {
 | 
				
			||||||
	freeResources();
 | 
						freeResources();
 | 
				
			||||||
 | 
						oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
 | 
				
			||||||
	if (subscriptLevels) {
 | 
						if (subscriptLevels) {
 | 
				
			||||||
		auto const&subscript = subscriptStack[subscriptStack.size() - static_cast<size_t>(subscriptLevels)];
 | 
							auto const&subscript = subscriptStack[subscriptStack.size() - static_cast<size_t>(subscriptLevels)];
 | 
				
			||||||
		if (subscript.subscriptType == Subscript::SubscriptType::InlineArray) {
 | 
							if (subscript.subscriptType == Subscript::SubscriptType::InlineArray) {
 | 
				
			||||||
			m_type = Type::InlineArray;
 | 
								m_type = Type::InlineArray;
 | 
				
			||||||
			m_data.array = new ModelValueArray;
 | 
								m_data.array = new ModelValueArray;
 | 
				
			||||||
			oxReturnError(m_data.array->setType(type, subscriptLevels - 1, subscriptStack));
 | 
								OX_RETURN_ERROR(m_data.array->setType(type, subscriptStack, subscriptLevels - 1));
 | 
				
			||||||
			oxReturnError(m_data.array->setSize(static_cast<size_t>(subscript.length)));
 | 
								OX_RETURN_ERROR(m_data.array->setSize(static_cast<size_t>(subscript.length)));
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			m_type = Type::Vector;
 | 
								m_type = Type::Vector;
 | 
				
			||||||
			m_data.vec = new ModelValueVector;
 | 
								m_data.vec = new ModelValueVector;
 | 
				
			||||||
			oxReturnError(m_data.vec->setType(type, subscriptLevels - 1, subscriptStack));
 | 
								OX_RETURN_ERROR(m_data.vec->setType(type, subscriptStack, subscriptLevels - 1));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
	} else if (type->typeName == types::Bool) {
 | 
						} else if (type->typeName == types::Bool) {
 | 
				
			||||||
@@ -1118,15 +1121,15 @@ constexpr Error ModelValue::setType(
 | 
				
			|||||||
	} else if (type->primitiveType == PrimitiveType::Struct) {
 | 
						} else if (type->primitiveType == PrimitiveType::Struct) {
 | 
				
			||||||
		m_type = Type::Object;
 | 
							m_type = Type::Object;
 | 
				
			||||||
		m_data.obj = new ModelObject;
 | 
							m_data.obj = new ModelObject;
 | 
				
			||||||
		oxReturnError(m_data.obj->setType(type));
 | 
							OX_RETURN_ERROR(m_data.obj->setType(type));
 | 
				
			||||||
	} else if (type->primitiveType == PrimitiveType::Union) {
 | 
						} else if (type->primitiveType == PrimitiveType::Union) {
 | 
				
			||||||
		m_type = Type::Union;
 | 
							m_type = Type::Union;
 | 
				
			||||||
		oxRequireM(u, ModelUnion::make(type));
 | 
							OX_REQUIRE_M(u, ModelUnion::make(type));
 | 
				
			||||||
		m_data.uni = u.release();
 | 
							m_data.uni = u.release();
 | 
				
			||||||
		oxReturnError(m_data.uni->setType(type));
 | 
							OX_RETURN_ERROR(m_data.uni->setType(type));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxAssert(m_type != Type::Undefined, "No type set");
 | 
						oxAssert(m_type != Type::Undefined, "No type set");
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
@@ -1138,11 +1141,11 @@ constexpr Error ModelValue::setType() noexcept {
 | 
				
			|||||||
	//             rather than using getValue<type>()
 | 
						//             rather than using getValue<type>()
 | 
				
			||||||
	if constexpr(type == Type::Object) {
 | 
						if constexpr(type == Type::Object) {
 | 
				
			||||||
		m_data.obj = new ModelObject;
 | 
							m_data.obj = new ModelObject;
 | 
				
			||||||
		oxReturnError(m_data.obj->setType(type));
 | 
							OX_RETURN_ERROR(m_data.obj->setType(type));
 | 
				
			||||||
	} else if constexpr(type == Type::Union) {
 | 
						} else if constexpr(type == Type::Union) {
 | 
				
			||||||
		oxRequireM(u, ModelUnion::make(type));
 | 
							OX_REQUIRE_M(u, ModelUnion::make(type));
 | 
				
			||||||
		m_data.uni = u.release();
 | 
							m_data.uni = u.release();
 | 
				
			||||||
		oxReturnError(m_data.uni->setType(type));
 | 
							OX_RETURN_ERROR(m_data.uni->setType(type));
 | 
				
			||||||
	} else if constexpr(type == Type::String) {
 | 
						} else if constexpr(type == Type::String) {
 | 
				
			||||||
		m_data.str = new String;
 | 
							m_data.str = new String;
 | 
				
			||||||
	} else if constexpr(type == Type::Vector) {
 | 
						} else if constexpr(type == Type::Vector) {
 | 
				
			||||||
@@ -1173,7 +1176,7 @@ template<typename T>
 | 
				
			|||||||
constexpr Error ModelValue::set(const T &v) noexcept {
 | 
					constexpr Error ModelValue::set(const T &v) noexcept {
 | 
				
			||||||
	constexpr auto type = getType<T>();
 | 
						constexpr auto type = getType<T>();
 | 
				
			||||||
	if (m_type != type) [[unlikely]] {
 | 
						if (m_type != type) [[unlikely]] {
 | 
				
			||||||
		return OxError(1, "type mismatch");
 | 
							return ox::Error(1, "type mismatch");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto &value = getValue<type>(*this);
 | 
						auto &value = getValue<type>(*this);
 | 
				
			||||||
	if constexpr(type == Type::Vector || type == Type::Object ||
 | 
						if constexpr(type == Type::Vector || type == Type::Object ||
 | 
				
			||||||
@@ -1181,14 +1184,14 @@ constexpr Error ModelValue::set(const T &v) noexcept {
 | 
				
			|||||||
		safeDelete(&value);
 | 
							safeDelete(&value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	value = v;
 | 
						value = v;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr Error ModelValue::set(T &&v) noexcept {
 | 
					constexpr Error ModelValue::set(T &&v) noexcept {
 | 
				
			||||||
	constexpr auto type = getType<T>();
 | 
						constexpr auto type = getType<T>();
 | 
				
			||||||
	if (m_type != type) [[unlikely]] {
 | 
						if (m_type != type) [[unlikely]] {
 | 
				
			||||||
		return OxError(1, "type mismatch");
 | 
							return ox::Error(1, "type mismatch");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto &value = getValue<type>(*this);
 | 
						auto &value = getValue<type>(*this);
 | 
				
			||||||
	if constexpr(type == Type::Vector || type == Type::Object ||
 | 
						if constexpr(type == Type::Vector || type == Type::Object ||
 | 
				
			||||||
@@ -1196,7 +1199,7 @@ constexpr Error ModelValue::set(T &&v) noexcept {
 | 
				
			|||||||
		safeDelete(&value);
 | 
							safeDelete(&value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	value = std::move(v);
 | 
						value = std::move(v);
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr ModelValue &ModelValue::operator=(ModelValue &other) noexcept {
 | 
					constexpr ModelValue &ModelValue::operator=(ModelValue &other) noexcept {
 | 
				
			||||||
@@ -1220,7 +1223,7 @@ constexpr ModelValue &ModelValue::operator=(const ModelValue &other) noexcept {
 | 
				
			|||||||
		case Type::SignedInteger16:
 | 
							case Type::SignedInteger16:
 | 
				
			||||||
		case Type::SignedInteger32:
 | 
							case Type::SignedInteger32:
 | 
				
			||||||
		case Type::SignedInteger64:
 | 
							case Type::SignedInteger64:
 | 
				
			||||||
			ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
 | 
								m_data = other.m_data;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case Type::String:
 | 
							case Type::String:
 | 
				
			||||||
			m_data.str = new String(other.get<String>());
 | 
								m_data.str = new String(other.get<String>());
 | 
				
			||||||
@@ -1258,8 +1261,8 @@ constexpr ModelValue &ModelValue::operator=(ModelValue &&other) noexcept {
 | 
				
			|||||||
		case Type::SignedInteger16:
 | 
							case Type::SignedInteger16:
 | 
				
			||||||
		case Type::SignedInteger32:
 | 
							case Type::SignedInteger32:
 | 
				
			||||||
		case Type::SignedInteger64:
 | 
							case Type::SignedInteger64:
 | 
				
			||||||
			ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
 | 
								m_data = other.m_data;
 | 
				
			||||||
			ox::memset(&other.m_data, 0, sizeof(m_data));
 | 
								other.m_data = {};
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case Type::String:
 | 
							case Type::String:
 | 
				
			||||||
			m_data.str = other.m_data.str;
 | 
								m_data.str = other.m_data.str;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/model/optype.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/model/optype.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								deps/ox/src/ox/model/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								deps/ox/src/ox/model/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -17,8 +17,8 @@ struct TestType {
 | 
				
			|||||||
	static constexpr auto TypeVersion = 1;
 | 
						static constexpr auto TypeVersion = 1;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oxModelBegin(TestType)
 | 
					OX_MODEL_BEGIN(TestType)
 | 
				
			||||||
oxModelEnd()
 | 
					OX_MODEL_END()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct TestType2 {
 | 
					struct TestType2 {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -38,12 +38,12 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
			"ModelValue",
 | 
								"ModelValue",
 | 
				
			||||||
			[] {
 | 
								[] {
 | 
				
			||||||
				ox::ModelValue v;
 | 
									ox::ModelValue v;
 | 
				
			||||||
				oxReturnError(v.setType<int32_t>());
 | 
									OX_RETURN_ERROR(v.setType<int32_t>());
 | 
				
			||||||
				//v.m_type = ox::ModelValue::getType<int32_t>();
 | 
									//v.m_type = ox::ModelValue::getType<int32_t>();
 | 
				
			||||||
				if (v.type() != ox::ModelValue::Type::SignedInteger32) {
 | 
									if (v.type() != ox::ModelValue::Type::SignedInteger32) {
 | 
				
			||||||
					return OxError(1, "type is wrong");
 | 
										return ox::Error(1, "type is wrong");
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				oxReturnError(v.set<int32_t>(5));
 | 
									OX_RETURN_ERROR(v.set<int32_t>(5));
 | 
				
			||||||
				return ox::Error{};
 | 
									return ox::Error{};
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								deps/ox/src/ox/model/typenamecatcher.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								deps/ox/src/ox/model/typenamecatcher.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -38,17 +38,17 @@ struct TypeNameCatcher {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	template<typename T>
 | 
						template<typename T>
 | 
				
			||||||
	constexpr Error field(const char*, T*, std::size_t) noexcept {
 | 
						constexpr Error field(const char*, T*, std::size_t) noexcept {
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<typename T>
 | 
						template<typename T>
 | 
				
			||||||
	constexpr Error field(const char*, T) noexcept {
 | 
						constexpr Error field(const char*, T) noexcept {
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<typename ...Args>
 | 
						template<typename ...Args>
 | 
				
			||||||
	constexpr Error fieldCString(Args&&...) noexcept {
 | 
						constexpr Error fieldCString(Args&&...) noexcept {
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static constexpr auto opType() noexcept {
 | 
						static constexpr auto opType() noexcept {
 | 
				
			||||||
@@ -77,17 +77,17 @@ struct TypeInfoCatcher {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	template<typename T>
 | 
						template<typename T>
 | 
				
			||||||
	constexpr Error field(const char*, T*, std::size_t) noexcept {
 | 
						constexpr Error field(const char*, T*, std::size_t) noexcept {
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<typename T>
 | 
						template<typename T>
 | 
				
			||||||
	constexpr Error field(const char*, T) noexcept {
 | 
						constexpr Error field(const char*, T) noexcept {
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<typename T>
 | 
						template<typename T>
 | 
				
			||||||
	constexpr Error fieldCString(const char*, T) noexcept {
 | 
						constexpr Error fieldCString(const char*, T) noexcept {
 | 
				
			||||||
		return OxError(0);
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static constexpr auto opType() noexcept {
 | 
						static constexpr auto opType() noexcept {
 | 
				
			||||||
@@ -140,16 +140,16 @@ constexpr Str getModelTypeName() noexcept {
 | 
				
			|||||||
	return out;
 | 
						return out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T, typename Str = const char*>
 | 
				
			||||||
[[nodiscard]]
 | 
					[[nodiscard]]
 | 
				
			||||||
consteval auto requireModelTypeName() noexcept {
 | 
					consteval auto requireModelTypeName() noexcept {
 | 
				
			||||||
	constexpr auto name = getModelTypeName<T>();
 | 
						constexpr auto name = getModelTypeName<T, Str>();
 | 
				
			||||||
	static_assert(ox::StringView{name}.len(), "Type lacks required TypeName");
 | 
						static_assert(ox::StringView{name}.size(), "Type lacks required TypeName");
 | 
				
			||||||
	return name;
 | 
						return name;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T, typename Str = const char*>
 | 
					template<typename T, typename Str = const char*>
 | 
				
			||||||
constexpr auto ModelTypeName_v = getModelTypeName<T, Str>();
 | 
					constexpr auto ModelTypeName_v = requireModelTypeName<T, Str>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T, typename Str = const char*>
 | 
					template<typename T, typename Str = const char*>
 | 
				
			||||||
constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>();
 | 
					constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>();
 | 
				
			||||||
@@ -159,7 +159,7 @@ constexpr auto ModelTypeId_v = [] {
 | 
				
			|||||||
	constexpr auto name = ModelTypeName_v<T, ox::StringView>;
 | 
						constexpr auto name = ModelTypeName_v<T, ox::StringView>;
 | 
				
			||||||
	constexpr auto version = ModelTypeVersion_v<T>;
 | 
						constexpr auto version = ModelTypeVersion_v<T>;
 | 
				
			||||||
	constexpr auto versionStr = ox::sfmt<ox::IString<19>>("{}", version);
 | 
						constexpr auto versionStr = ox::sfmt<ox::IString<19>>("{}", version);
 | 
				
			||||||
	return ox::sfmt<ox::IString<name.len() + versionStr.len() + 1>>("{};{}", name, versionStr);
 | 
						return ox::sfmt<ox::IString<name.size() + versionStr.size() + 1>>("{};{}", name, versionStr);
 | 
				
			||||||
}();
 | 
					}();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/model/types.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/model/types.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								deps/ox/src/ox/model/typestore.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								deps/ox/src/ox/model/typestore.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -31,7 +31,7 @@ class TypeStore {
 | 
				
			|||||||
		constexpr Result<const DescriptorType*> get(const auto &name, int typeVersion,
 | 
							constexpr Result<const DescriptorType*> get(const auto &name, int typeVersion,
 | 
				
			||||||
		                                            const TypeParamPack &typeParams) const noexcept {
 | 
							                                            const TypeParamPack &typeParams) const noexcept {
 | 
				
			||||||
			const auto typeId = buildTypeId(name, typeVersion, typeParams);
 | 
								const auto typeId = buildTypeId(name, typeVersion, typeParams);
 | 
				
			||||||
			oxRequire(out, m_cache.at(typeId));
 | 
								OX_REQUIRE(out, m_cache.at(typeId));
 | 
				
			||||||
			return out->get();
 | 
								return out->get();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -40,11 +40,11 @@ class TypeStore {
 | 
				
			|||||||
			constexpr auto typeName = ModelTypeName_v<T>;
 | 
								constexpr auto typeName = ModelTypeName_v<T>;
 | 
				
			||||||
			constexpr auto typeVersion = ModelTypeVersion_v<T>;
 | 
								constexpr auto typeVersion = ModelTypeVersion_v<T>;
 | 
				
			||||||
			const auto typeId = buildTypeId(typeName, typeVersion, {});
 | 
								const auto typeId = buildTypeId(typeName, typeVersion, {});
 | 
				
			||||||
			oxRequire(out, m_cache.at(typeId));
 | 
								OX_REQUIRE(out, m_cache.at(typeId));
 | 
				
			||||||
			return out->get();
 | 
								return out->get();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		constexpr DescriptorType *getInit(CRStringView typeName, int typeVersion, PrimitiveType pt,
 | 
							constexpr DescriptorType *getInit(StringViewCR typeName, int typeVersion, PrimitiveType pt,
 | 
				
			||||||
		                                  const TypeParamPack &typeParams) noexcept {
 | 
							                                  const TypeParamPack &typeParams) noexcept {
 | 
				
			||||||
			const auto typeId = buildTypeId(typeName, typeVersion, typeParams);
 | 
								const auto typeId = buildTypeId(typeName, typeVersion, typeParams);
 | 
				
			||||||
			auto &out = m_cache[typeId];
 | 
								auto &out = m_cache[typeId];
 | 
				
			||||||
@@ -56,15 +56,19 @@ class TypeStore {
 | 
				
			|||||||
			auto [val, err] = m_cache.at(typeId);
 | 
								auto [val, err] = m_cache.at(typeId);
 | 
				
			||||||
			if (err) {
 | 
								if (err) {
 | 
				
			||||||
				if (!std::is_constant_evaluated()) {
 | 
									if (!std::is_constant_evaluated()) {
 | 
				
			||||||
					oxRequireM(dt, loadDescriptor(typeId));
 | 
										OX_REQUIRE_M(dt, loadDescriptor(typeId));
 | 
				
			||||||
					for (auto &f : dt->fieldList) {
 | 
										for (auto &f : dt->fieldList) {
 | 
				
			||||||
						oxReturnError(this->getLoad(f.typeId).moveTo(f.type));
 | 
											if (typeId == f.typeId) {
 | 
				
			||||||
 | 
												f.type = dt.get();
 | 
				
			||||||
 | 
											} else {
 | 
				
			||||||
 | 
												OX_RETURN_ERROR(this->getLoad(f.typeId).moveTo(f.type));
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					auto &out = m_cache[typeId];
 | 
										auto &out = m_cache[typeId];
 | 
				
			||||||
					out = std::move(dt);
 | 
										out = std::move(dt);
 | 
				
			||||||
					return out.get();
 | 
										return out.get();
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					return OxError(1, "Type not available");
 | 
										return ox::Error(1, "Type not available");
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return val->get();
 | 
								return val->get();
 | 
				
			||||||
@@ -102,10 +106,10 @@ class TypeStore {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	protected:
 | 
						protected:
 | 
				
			||||||
		virtual Result<UniquePtr<DescriptorType>> loadDescriptor(ox::StringView) noexcept {
 | 
							virtual Result<UniquePtr<DescriptorType>> loadDescriptor(ox::StringView) noexcept {
 | 
				
			||||||
			return OxError(1);
 | 
								return ox::Error(1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Result<UniquePtr<DescriptorType>> loadDescriptor(ox::CRStringView name, int version,
 | 
							Result<UniquePtr<DescriptorType>> loadDescriptor(ox::StringViewCR name, int version,
 | 
				
			||||||
		                                                 const ox::TypeParamPack &typeParams) noexcept {
 | 
							                                                 const ox::TypeParamPack &typeParams) noexcept {
 | 
				
			||||||
			const auto typeId = buildTypeId(name, version, typeParams);
 | 
								const auto typeId = buildTypeId(name, version, typeParams);
 | 
				
			||||||
			return loadDescriptor(typeId);
 | 
								return loadDescriptor(typeId);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										26
									
								
								deps/ox/src/ox/model/walk.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								deps/ox/src/ox/model/walk.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -50,7 +50,7 @@ constexpr DataWalker<Reader, T>::DataWalker(DescriptorType *type, T fieldHandler
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename Reader, typename T>
 | 
					template<typename Reader, typename T>
 | 
				
			||||||
constexpr Result<const DescriptorType*> DataWalker<Reader, T>::type() const noexcept {
 | 
					constexpr Result<const DescriptorType*> DataWalker<Reader, T>::type() const noexcept {
 | 
				
			||||||
	oxRequire(out, m_typeStack.back());
 | 
						OX_REQUIRE(out, m_typeStack.back());
 | 
				
			||||||
	return *out;
 | 
						return *out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -87,9 +87,9 @@ static constexpr Error parseField(const DescriptorField &field, Reader *rdr, Dat
 | 
				
			|||||||
	walker->pushNamePath(field.fieldName);
 | 
						walker->pushNamePath(field.fieldName);
 | 
				
			||||||
	if (field.subscriptLevels) {
 | 
						if (field.subscriptLevels) {
 | 
				
			||||||
		// add array handling
 | 
							// add array handling
 | 
				
			||||||
		oxRequire(arrayLen, rdr->arrayLength(field.fieldName.c_str(), true));
 | 
							OX_REQUIRE(arrayLen, rdr->arrayLength(field.fieldName.c_str(), true));
 | 
				
			||||||
		auto child = rdr->child(field.fieldName.c_str());
 | 
							auto child = rdr->child(field.fieldName.c_str());
 | 
				
			||||||
		oxReturnError(child.setTypeInfo(field.type->typeName.c_str(), field.type->typeVersion, field.type->typeParams, arrayLen));
 | 
							OX_RETURN_ERROR(child.setTypeInfo(field.type->typeName.c_str(), field.type->typeVersion, field.type->typeParams, arrayLen));
 | 
				
			||||||
		DescriptorField f(field); // create mutable copy
 | 
							DescriptorField f(field); // create mutable copy
 | 
				
			||||||
		--f.subscriptLevels;
 | 
							--f.subscriptLevels;
 | 
				
			||||||
		String subscript;
 | 
							String subscript;
 | 
				
			||||||
@@ -98,7 +98,7 @@ static constexpr Error parseField(const DescriptorField &field, Reader *rdr, Dat
 | 
				
			|||||||
			subscript += static_cast<uint64_t>(i);
 | 
								subscript += static_cast<uint64_t>(i);
 | 
				
			||||||
			subscript += "]";
 | 
								subscript += "]";
 | 
				
			||||||
			walker->pushNamePath(subscript);
 | 
								walker->pushNamePath(subscript);
 | 
				
			||||||
			oxReturnError(parseField(f, &child, walker));
 | 
								OX_RETURN_ERROR(parseField(f, &child, walker));
 | 
				
			||||||
			walker->popNamePath();
 | 
								walker->popNamePath();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		rdr->nextField();
 | 
							rdr->nextField();
 | 
				
			||||||
@@ -108,40 +108,40 @@ static constexpr Error parseField(const DescriptorField &field, Reader *rdr, Dat
 | 
				
			|||||||
			case PrimitiveType::SignedInteger:
 | 
								case PrimitiveType::SignedInteger:
 | 
				
			||||||
			case PrimitiveType::Bool:
 | 
								case PrimitiveType::Bool:
 | 
				
			||||||
			case PrimitiveType::String:
 | 
								case PrimitiveType::String:
 | 
				
			||||||
				oxReturnError(walker->read(field, rdr));
 | 
									OX_RETURN_ERROR(walker->read(field, rdr));
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			case PrimitiveType::Struct:
 | 
								case PrimitiveType::Struct:
 | 
				
			||||||
			case PrimitiveType::Union:
 | 
								case PrimitiveType::Union:
 | 
				
			||||||
				if (rdr->fieldPresent(field.fieldName.c_str())) {
 | 
									if (rdr->fieldPresent(field.fieldName.c_str())) {
 | 
				
			||||||
					auto child = rdr->child(field.fieldName.c_str());
 | 
										auto child = rdr->child(field.fieldName.c_str());
 | 
				
			||||||
					walker->pushType(field.type);
 | 
										walker->pushType(field.type);
 | 
				
			||||||
					oxReturnError(model(&child, walker));
 | 
										OX_RETURN_ERROR(model(&child, walker));
 | 
				
			||||||
					walker->popType();
 | 
										walker->popType();
 | 
				
			||||||
					rdr->nextField();
 | 
										rdr->nextField();
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					// skip and discard absent field
 | 
										// skip and discard absent field
 | 
				
			||||||
					int discard;
 | 
										int discard;
 | 
				
			||||||
					oxReturnError(rdr->field(field.fieldName.c_str(), &discard));
 | 
										OX_RETURN_ERROR(rdr->field(field.fieldName.c_str(), &discard));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	walker->popNamePath();
 | 
						walker->popNamePath();
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename Reader, typename FH>
 | 
					template<typename Reader, typename FH>
 | 
				
			||||||
constexpr Error model(Reader *rdr, DataWalker<Reader, FH> *walker) noexcept {
 | 
					constexpr Error model(Reader *rdr, DataWalker<Reader, FH> *walker) noexcept {
 | 
				
			||||||
	oxRequire(type, walker->type());
 | 
						OX_REQUIRE(type, walker->type());
 | 
				
			||||||
	auto typeName = type->typeName.c_str();
 | 
						auto typeName = type->typeName.c_str();
 | 
				
			||||||
	auto typeVersion = type->typeVersion;
 | 
						auto typeVersion = type->typeVersion;
 | 
				
			||||||
	auto typeParams = type->typeParams;
 | 
						auto typeParams = type->typeParams;
 | 
				
			||||||
	auto &fields = type->fieldList;
 | 
						auto &fields = type->fieldList;
 | 
				
			||||||
	oxReturnError(rdr->setTypeInfo(typeName, typeVersion, typeParams, fields.size()));
 | 
						OX_RETURN_ERROR(rdr->setTypeInfo(typeName, typeVersion, typeParams, fields.size()));
 | 
				
			||||||
	for (const auto &field : fields) {
 | 
						for (const auto &field : fields) {
 | 
				
			||||||
		oxReturnError(parseField(field, rdr, walker));
 | 
							OX_RETURN_ERROR(parseField(field, rdr, walker));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename Reader, typename Handler>
 | 
					template<typename Reader, typename Handler>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/oc/oc.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/oc/oc.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										32
									
								
								deps/ox/src/ox/oc/read.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								deps/ox/src/ox/oc/read.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -15,11 +15,11 @@ namespace ox {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
OrganicClawReader::OrganicClawReader(const uint8_t *buff, std::size_t buffSize) {
 | 
					OrganicClawReader::OrganicClawReader(const uint8_t *buff, std::size_t buffSize) {
 | 
				
			||||||
	auto json = reinterpret_cast<const char*>(buff);
 | 
						auto json = reinterpret_cast<const char*>(buff);
 | 
				
			||||||
	auto jsonLen = ox::strnlen(json, buffSize);
 | 
						auto jsonLen = ox::strnlen_s(json, buffSize);
 | 
				
			||||||
	Json::CharReaderBuilder parserBuilder;
 | 
						Json::CharReaderBuilder parserBuilder;
 | 
				
			||||||
	auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader());
 | 
						auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader());
 | 
				
			||||||
	if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) {
 | 
						if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) {
 | 
				
			||||||
		throw OxException(1, "Could not parse JSON");
 | 
							throw ox::Exception(1, "Could not parse JSON");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,7 +27,7 @@ OrganicClawReader::OrganicClawReader(const char *json, std::size_t jsonLen) {
 | 
				
			|||||||
	Json::CharReaderBuilder parserBuilder;
 | 
						Json::CharReaderBuilder parserBuilder;
 | 
				
			||||||
	auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader());
 | 
						auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader());
 | 
				
			||||||
	if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) {
 | 
						if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) {
 | 
				
			||||||
		throw OxException(1, "Could not parse JSON");
 | 
							throw ox::Exception(1, "Could not parse JSON");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -37,7 +37,7 @@ OrganicClawReader::OrganicClawReader(Json::Value json, int unionIdx) noexcept:
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error OrganicClawReader::field(const char *key, bool *val) noexcept {
 | 
					Error OrganicClawReader::field(const char *key, bool *val) noexcept {
 | 
				
			||||||
	auto err = OxError(0);
 | 
						ox::Error err{};
 | 
				
			||||||
	if (targetValid()) {
 | 
						if (targetValid()) {
 | 
				
			||||||
		const auto &jv = value(key);
 | 
							const auto &jv = value(key);
 | 
				
			||||||
		if (jv.empty()) {
 | 
							if (jv.empty()) {
 | 
				
			||||||
@@ -45,7 +45,7 @@ Error OrganicClawReader::field(const char *key, bool *val) noexcept {
 | 
				
			|||||||
		} else if (jv.isBool()) {
 | 
							} else if (jv.isBool()) {
 | 
				
			||||||
			*val = jv.asBool();
 | 
								*val = jv.asBool();
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			err = OxError(1, "Type mismatch");
 | 
								err = ox::Error(1, "Type mismatch");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_fieldIt;
 | 
						++m_fieldIt;
 | 
				
			||||||
@@ -53,7 +53,7 @@ Error OrganicClawReader::field(const char *key, bool *val) noexcept {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t buffLen) noexcept {
 | 
					Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t buffLen) noexcept {
 | 
				
			||||||
	auto err = OxError(0);
 | 
						ox::Error err{};
 | 
				
			||||||
	const char *begin = nullptr, *end = nullptr;
 | 
						const char *begin = nullptr, *end = nullptr;
 | 
				
			||||||
	const auto &jv = value(key);
 | 
						const auto &jv = value(key);
 | 
				
			||||||
	if (targetValid()) {
 | 
						if (targetValid()) {
 | 
				
			||||||
@@ -67,13 +67,13 @@ Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t bu
 | 
				
			|||||||
			const auto strSize = static_cast<std::size_t>(end - begin);
 | 
								const auto strSize = static_cast<std::size_t>(end - begin);
 | 
				
			||||||
			auto data = val;
 | 
								auto data = val;
 | 
				
			||||||
			if (strSize >= buffLen) {
 | 
								if (strSize >= buffLen) {
 | 
				
			||||||
				err = OxError(2, "String size exceeds capacity of destination");
 | 
									err = ox::Error(2, "String size exceeds capacity of destination");
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
 | 
									ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
 | 
				
			||||||
				data[strSize] = 0;
 | 
									data[strSize] = 0;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			err = OxError(1, "Type mismatch");
 | 
								err = ox::Error(1, "Type mismatch");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_fieldIt;
 | 
						++m_fieldIt;
 | 
				
			||||||
@@ -81,7 +81,7 @@ Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t bu
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error OrganicClawReader::fieldCString(const char *key, char **val) noexcept {
 | 
					Error OrganicClawReader::fieldCString(const char *key, char **val) noexcept {
 | 
				
			||||||
	auto err = OxError(0);
 | 
						ox::Error err{};
 | 
				
			||||||
	const char *begin = nullptr, *end = nullptr;
 | 
						const char *begin = nullptr, *end = nullptr;
 | 
				
			||||||
	const auto &jv = value(key);
 | 
						const auto &jv = value(key);
 | 
				
			||||||
	auto &data = *val;
 | 
						auto &data = *val;
 | 
				
			||||||
@@ -98,7 +98,7 @@ Error OrganicClawReader::fieldCString(const char *key, char **val) noexcept {
 | 
				
			|||||||
			ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
 | 
								ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
 | 
				
			||||||
			data[strSize] = 0;
 | 
								data[strSize] = 0;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			err = OxError(1, "Type mismatch");
 | 
								err = ox::Error(1, "Type mismatch");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_fieldIt;
 | 
						++m_fieldIt;
 | 
				
			||||||
@@ -106,7 +106,7 @@ Error OrganicClawReader::fieldCString(const char *key, char **val) noexcept {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t buffLen) noexcept {
 | 
					Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t buffLen) noexcept {
 | 
				
			||||||
	auto err = OxError(0);
 | 
						ox::Error err{};
 | 
				
			||||||
	const char *begin = nullptr, *end = nullptr;
 | 
						const char *begin = nullptr, *end = nullptr;
 | 
				
			||||||
	const auto &jv = value(key);
 | 
						const auto &jv = value(key);
 | 
				
			||||||
	if (targetValid()) {
 | 
						if (targetValid()) {
 | 
				
			||||||
@@ -126,7 +126,7 @@ Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t b
 | 
				
			|||||||
			ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
 | 
								ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
 | 
				
			||||||
			data[strSize] = nullptr;
 | 
								data[strSize] = nullptr;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			err = OxError(1, "Type mismatch");
 | 
								err = ox::Error(1, "Type mismatch");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_fieldIt;
 | 
						++m_fieldIt;
 | 
				
			||||||
@@ -135,7 +135,7 @@ Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t b
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Error OrganicClawReader::field(const char *key, UUID *val) noexcept {
 | 
					Error OrganicClawReader::field(const char *key, UUID *val) noexcept {
 | 
				
			||||||
	UUIDStr str;
 | 
						UUIDStr str;
 | 
				
			||||||
	oxReturnError(field(key, &str));
 | 
						OX_RETURN_ERROR(field(key, &str));
 | 
				
			||||||
	return UUID::fromString(str).moveTo(*val);
 | 
						return UUID::fromString(str).moveTo(*val);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -147,7 +147,7 @@ Result<std::size_t> OrganicClawReader::arrayLength(const char *key, bool) noexce
 | 
				
			|||||||
	if (jv.isArray()) {
 | 
						if (jv.isArray()) {
 | 
				
			||||||
		return jv.size();
 | 
							return jv.size();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1, "Type mismatch");
 | 
						return ox::Error(1, "Type mismatch");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[nodiscard]]
 | 
					[[nodiscard]]
 | 
				
			||||||
@@ -161,7 +161,7 @@ std::size_t OrganicClawReader::stringLength(const char *key) noexcept {
 | 
				
			|||||||
		jv.getString(&begin, &end);
 | 
							jv.getString(&begin, &end);
 | 
				
			||||||
		return static_cast<std::size_t>(end - begin);
 | 
							return static_cast<std::size_t>(end - begin);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(1, "Type mismatch");
 | 
						return ox::Error(1, "Type mismatch");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OrganicClawReader OrganicClawReader::child(const char *key, int unionIdx) noexcept {
 | 
					OrganicClawReader OrganicClawReader::child(const char *key, int unionIdx) noexcept {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										64
									
								
								deps/ox/src/ox/oc/read.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								deps/ox/src/ox/oc/read.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -8,7 +8,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ox/std/def.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
#include <json/json.h>
 | 
					#include <json/json.h>
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <ox/model/fieldcounter.hpp>
 | 
					#include <ox/model/fieldcounter.hpp>
 | 
				
			||||||
#include <ox/model/modelhandleradaptor.hpp>
 | 
					#include <ox/model/modelhandleradaptor.hpp>
 | 
				
			||||||
@@ -133,7 +137,7 @@ class OrganicClawReader {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
Error OrganicClawReader::field(const char *key, T *val) noexcept {
 | 
					Error OrganicClawReader::field(const char *key, T *val) noexcept {
 | 
				
			||||||
	auto err = OxError(0);
 | 
						ox::Error err{};
 | 
				
			||||||
	try {
 | 
						try {
 | 
				
			||||||
		if constexpr (is_integer_v<T>) {
 | 
							if constexpr (is_integer_v<T>) {
 | 
				
			||||||
			if (targetValid()) {
 | 
								if (targetValid()) {
 | 
				
			||||||
@@ -144,21 +148,25 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
 | 
				
			|||||||
				if (jv.empty()) {
 | 
									if (jv.empty()) {
 | 
				
			||||||
					*val = 0;
 | 
										*val = 0;
 | 
				
			||||||
				} else if (rightType) {
 | 
									} else if (rightType) {
 | 
				
			||||||
					*val = static_cast<T>(jv.asUInt());
 | 
										if constexpr(ox::is_signed_v<T>) {
 | 
				
			||||||
 | 
											*val = static_cast<T>(jv.asInt64());
 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
					err = OxError(1, "Type mismatch");
 | 
											*val = static_cast<T>(jv.asUInt64());
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										err = ox::Error(1, "Type mismatch");
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else if constexpr (isVector_v<T>) {
 | 
							} else if constexpr (isVector_v<T>) {
 | 
				
			||||||
			const auto&srcVal = value(key);
 | 
								const auto&srcVal = value(key);
 | 
				
			||||||
			const auto srcSize = srcVal.size();
 | 
								const auto srcSize = srcVal.size();
 | 
				
			||||||
			oxReturnError(ox::resizeVector(*val, srcSize));
 | 
								OX_RETURN_ERROR(ox::resizeVector(*val, srcSize));
 | 
				
			||||||
			err = field(key, val->data(), val->size());
 | 
								err = field(key, val->data(), val->size());
 | 
				
			||||||
		} else if constexpr (isArray_v<T>) {
 | 
							} else if constexpr (isArray_v<T>) {
 | 
				
			||||||
			const auto&srcVal = value(key);
 | 
								const auto&srcVal = value(key);
 | 
				
			||||||
			const auto srcSize = srcVal.size();
 | 
								const auto srcSize = srcVal.size();
 | 
				
			||||||
			if (srcSize > val->size()) {
 | 
								if (srcSize > val->size()) {
 | 
				
			||||||
				err = OxError(1, "Input array is too long");
 | 
									err = ox::Error(1, "Input array is too long");
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				err = field(key, val->data(), val->size());
 | 
									err = field(key, val->data(), val->size());
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -169,11 +177,11 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
 | 
				
			|||||||
				ModelHandlerInterface handler(&reader);
 | 
									ModelHandlerInterface handler(&reader);
 | 
				
			||||||
				err = model(&handler, val);
 | 
									err = model(&handler, val);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				err = OxError(1, "Type mismatch");
 | 
									err = ox::Error(1, "Type mismatch");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} catch (Json::LogicError const&) {
 | 
						} catch (Json::LogicError const&e) {
 | 
				
			||||||
		err = OxError(1, "error reading JSON data");
 | 
							err = ox::Error(1, "error reading JSON data");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_fieldIt;
 | 
						++m_fieldIt;
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
@@ -181,7 +189,7 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename U, bool force>
 | 
					template<typename U, bool force>
 | 
				
			||||||
Error OrganicClawReader::field(const char *key, UnionView<U, force> val) noexcept {
 | 
					Error OrganicClawReader::field(const char *key, UnionView<U, force> val) noexcept {
 | 
				
			||||||
	auto err = OxError(0);
 | 
						ox::Error err{};
 | 
				
			||||||
	if (targetValid()) {
 | 
						if (targetValid()) {
 | 
				
			||||||
		const auto &jv = value(key);
 | 
							const auto &jv = value(key);
 | 
				
			||||||
		if (jv.empty() || jv.isObject()) {
 | 
							if (jv.empty() || jv.isObject()) {
 | 
				
			||||||
@@ -189,7 +197,7 @@ Error OrganicClawReader::field(const char *key, UnionView<U, force> val) noexcep
 | 
				
			|||||||
			ModelHandlerInterface handler(&reader);
 | 
								ModelHandlerInterface handler(&reader);
 | 
				
			||||||
			err = model(&handler, val.get());
 | 
								err = model(&handler, val.get());
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			err = OxError(1, "Type mismatch");
 | 
								err = ox::Error(1, "Type mismatch");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_fieldIt;
 | 
						++m_fieldIt;
 | 
				
			||||||
@@ -198,7 +206,7 @@ Error OrganicClawReader::field(const char *key, UnionView<U, force> val) noexcep
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<std::size_t L>
 | 
					template<std::size_t L>
 | 
				
			||||||
Error OrganicClawReader::field(const char *key, BasicString<L> *val) noexcept {
 | 
					Error OrganicClawReader::field(const char *key, BasicString<L> *val) noexcept {
 | 
				
			||||||
	auto err = OxError(0);
 | 
						ox::Error err{};
 | 
				
			||||||
	if (targetValid()) {
 | 
						if (targetValid()) {
 | 
				
			||||||
		const auto &jv = value(key);
 | 
							const auto &jv = value(key);
 | 
				
			||||||
		if (jv.empty()) {
 | 
							if (jv.empty()) {
 | 
				
			||||||
@@ -206,7 +214,7 @@ Error OrganicClawReader::field(const char *key, BasicString<L> *val) noexcept {
 | 
				
			|||||||
		} else if (jv.isString()) {
 | 
							} else if (jv.isString()) {
 | 
				
			||||||
			*val = jv.asString().c_str();
 | 
								*val = jv.asString().c_str();
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			err = OxError(1, "Type mismatch");
 | 
								err = ox::Error(1, "Type mismatch");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_fieldIt;
 | 
						++m_fieldIt;
 | 
				
			||||||
@@ -215,7 +223,7 @@ Error OrganicClawReader::field(const char *key, BasicString<L> *val) noexcept {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<std::size_t L>
 | 
					template<std::size_t L>
 | 
				
			||||||
Error OrganicClawReader::field(const char *key, IString<L> *val) noexcept {
 | 
					Error OrganicClawReader::field(const char *key, IString<L> *val) noexcept {
 | 
				
			||||||
	auto err = OxError(0);
 | 
						ox::Error err{};
 | 
				
			||||||
	if (targetValid()) {
 | 
						if (targetValid()) {
 | 
				
			||||||
		const auto &jv = value(key);
 | 
							const auto &jv = value(key);
 | 
				
			||||||
		if (jv.empty()) {
 | 
							if (jv.empty()) {
 | 
				
			||||||
@@ -223,7 +231,7 @@ Error OrganicClawReader::field(const char *key, IString<L> *val) noexcept {
 | 
				
			|||||||
		} else if (jv.isString()) {
 | 
							} else if (jv.isString()) {
 | 
				
			||||||
			*val = jv.asString().c_str();
 | 
								*val = jv.asString().c_str();
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			err = OxError(1, "Type mismatch");
 | 
								err = ox::Error(1, "Type mismatch");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_fieldIt;
 | 
						++m_fieldIt;
 | 
				
			||||||
@@ -235,25 +243,27 @@ template<typename T>
 | 
				
			|||||||
Error OrganicClawReader::field(const char *key, T *val, std::size_t valLen) noexcept {
 | 
					Error OrganicClawReader::field(const char *key, T *val, std::size_t valLen) noexcept {
 | 
				
			||||||
	const auto &srcVal = value(key);
 | 
						const auto &srcVal = value(key);
 | 
				
			||||||
	if (!srcVal.isNull() && !srcVal.isArray()) {
 | 
						if (!srcVal.isNull() && !srcVal.isArray()) {
 | 
				
			||||||
		return OxError(1, "Type mismatch");
 | 
							return ox::Error(1, "Type mismatch");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto srcSize = srcVal.size();
 | 
						auto srcSize = srcVal.size();
 | 
				
			||||||
	if (srcSize > valLen) {
 | 
						if (srcSize > valLen) {
 | 
				
			||||||
		return OxError(1);
 | 
							return ox::Error(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	OrganicClawReader r(srcVal);
 | 
						OrganicClawReader r(srcVal);
 | 
				
			||||||
	ModelHandlerInterface handler{&r};
 | 
						ModelHandlerInterface handler{&r};
 | 
				
			||||||
	for (decltype(srcSize) i = 0; i < srcSize; ++i) {
 | 
						for (decltype(srcSize) i = 0; i < srcSize; ++i) {
 | 
				
			||||||
		oxReturnError(handler.field("", &val[i]));
 | 
					OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
 | 
							OX_RETURN_ERROR(handler.field("", &val[i]));
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
Error OrganicClawReader::field(const char *key, HashMap<String, T> *val) noexcept {
 | 
					Error OrganicClawReader::field(const char *key, HashMap<String, T> *val) noexcept {
 | 
				
			||||||
	const auto &srcVal = value(key);
 | 
						const auto &srcVal = value(key);
 | 
				
			||||||
	if (!srcVal.isObject()) {
 | 
						if (!srcVal.isObject()) {
 | 
				
			||||||
		return OxError(1, "Type mismatch");
 | 
							return ox::Error(1, "Type mismatch");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto keys = srcVal.getMemberNames();
 | 
						auto keys = srcVal.getMemberNames();
 | 
				
			||||||
	auto srcSize = srcVal.size();
 | 
						auto srcSize = srcVal.size();
 | 
				
			||||||
@@ -261,9 +271,9 @@ Error OrganicClawReader::field(const char *key, HashMap<String, T> *val) noexcep
 | 
				
			|||||||
	ModelHandlerInterface handler{&r};
 | 
						ModelHandlerInterface handler{&r};
 | 
				
			||||||
	for (decltype(srcSize) i = 0; i < srcSize; ++i) {
 | 
						for (decltype(srcSize) i = 0; i < srcSize; ++i) {
 | 
				
			||||||
		const auto k = keys[i].c_str();
 | 
							const auto k = keys[i].c_str();
 | 
				
			||||||
		oxReturnError(handler.field(k, &val->operator[](k)));
 | 
							OX_RETURN_ERROR(handler.field(k, &val->operator[](k)));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error readOC(BufferView buff, auto &val) noexcept {
 | 
					Error readOC(BufferView buff, auto &val) noexcept {
 | 
				
			||||||
@@ -272,8 +282,10 @@ Error readOC(BufferView buff, auto &val) noexcept {
 | 
				
			|||||||
		Json::Value doc;
 | 
							Json::Value doc;
 | 
				
			||||||
		Json::CharReaderBuilder parserBuilder;
 | 
							Json::CharReaderBuilder parserBuilder;
 | 
				
			||||||
		auto parser = UniquePtr<Json::CharReader>(parserBuilder.newCharReader());
 | 
							auto parser = UniquePtr<Json::CharReader>(parserBuilder.newCharReader());
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
		if (!parser->parse(buff.data(), buff.data() + buff.size(), &doc, nullptr)) {
 | 
							if (!parser->parse(buff.data(), buff.data() + buff.size(), &doc, nullptr)) {
 | 
				
			||||||
			return OxError(1, "Could not parse JSON");
 | 
					OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
 | 
								return ox::Error(1, "Could not parse JSON");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		OrganicClawReader reader(buff.data(), buff.size());
 | 
							OrganicClawReader reader(buff.data(), buff.size());
 | 
				
			||||||
		ModelHandlerInterface handler(&reader);
 | 
							ModelHandlerInterface handler(&reader);
 | 
				
			||||||
@@ -281,20 +293,20 @@ Error readOC(BufferView buff, auto &val) noexcept {
 | 
				
			|||||||
	} catch (const Error &err) {
 | 
						} catch (const Error &err) {
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	} catch (...) {
 | 
						} catch (...) {
 | 
				
			||||||
		return OxError(1, "Unknown Error");
 | 
							return ox::Error(1, "Unknown Error");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
Result<T> readOC(BufferView buff) noexcept {
 | 
					Result<T> readOC(BufferView buff) noexcept {
 | 
				
			||||||
	Result<T> val;
 | 
						Result<T> val;
 | 
				
			||||||
	oxReturnError(readOC(buff, val.value));
 | 
						OX_RETURN_ERROR(readOC(buff, val.value));
 | 
				
			||||||
	return val;
 | 
						return val;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
Result<T> readOC(ox::StringView json) noexcept {
 | 
					Result<T> readOC(ox::StringView json) noexcept {
 | 
				
			||||||
	return readOC<T>(ox::BufferView{json.data(), json.len()});
 | 
						return readOC<T>(ox::BufferView{json.data(), json.size()});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										78
									
								
								deps/ox/src/ox/oc/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										78
									
								
								deps/ox/src/ox/oc/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -74,45 +74,45 @@ struct TestStruct {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcept {
 | 
					constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcept {
 | 
				
			||||||
	oxReturnError(io->template setTypeInfo<TestUnion>());
 | 
						OX_RETURN_ERROR(io->template setTypeInfo<TestUnion>());
 | 
				
			||||||
	oxReturnError(io->field("Bool", &obj->Bool));
 | 
						OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
 | 
				
			||||||
	oxReturnError(io->field("Int", &obj->Int));
 | 
						OX_RETURN_ERROR(io->field("Int", &obj->Int));
 | 
				
			||||||
	oxReturnError(io->fieldCString("String", &obj->String));
 | 
						OX_RETURN_ERROR(io->fieldCString("String", &obj->String));
 | 
				
			||||||
	return OxError(0);
 | 
						return ox::Error(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestStructNest> auto *obj) noexcept {
 | 
					constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestStructNest> auto *obj) noexcept {
 | 
				
			||||||
	oxReturnError(io->template setTypeInfo<TestStructNest>());
 | 
						OX_RETURN_ERROR(io->template setTypeInfo<TestStructNest>());
 | 
				
			||||||
	oxReturnError(io->field("Bool", &obj->Bool));
 | 
						OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
 | 
				
			||||||
	oxReturnError(io->field("Int", &obj->Int));
 | 
						OX_RETURN_ERROR(io->field("Int", &obj->Int));
 | 
				
			||||||
	oxReturnError(io->field("String", &obj->String));
 | 
						OX_RETURN_ERROR(io->field("String", &obj->String));
 | 
				
			||||||
	return OxError(0);
 | 
						return ox::Error(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestStruct> auto *obj) noexcept {
 | 
					constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestStruct> auto *obj) noexcept {
 | 
				
			||||||
	oxReturnError(io->template setTypeInfo<TestStruct>());
 | 
						OX_RETURN_ERROR(io->template setTypeInfo<TestStruct>());
 | 
				
			||||||
	oxReturnError(io->field("Bool", &obj->Bool));
 | 
						OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
 | 
				
			||||||
	oxReturnError(io->field("Int", &obj->Int));
 | 
						OX_RETURN_ERROR(io->field("Int", &obj->Int));
 | 
				
			||||||
	oxReturnError(io->field("Int1", &obj->Int1));
 | 
						OX_RETURN_ERROR(io->field("Int1", &obj->Int1));
 | 
				
			||||||
	oxReturnError(io->field("Int2", &obj->Int2));
 | 
						OX_RETURN_ERROR(io->field("Int2", &obj->Int2));
 | 
				
			||||||
	oxReturnError(io->field("Int3", &obj->Int3));
 | 
						OX_RETURN_ERROR(io->field("Int3", &obj->Int3));
 | 
				
			||||||
	oxReturnError(io->field("Int4", &obj->Int4));
 | 
						OX_RETURN_ERROR(io->field("Int4", &obj->Int4));
 | 
				
			||||||
	oxReturnError(io->field("Int5", &obj->Int5));
 | 
						OX_RETURN_ERROR(io->field("Int5", &obj->Int5));
 | 
				
			||||||
	oxReturnError(io->field("Int6", &obj->Int6));
 | 
						OX_RETURN_ERROR(io->field("Int6", &obj->Int6));
 | 
				
			||||||
	oxReturnError(io->field("Int7", &obj->Int7));
 | 
						OX_RETURN_ERROR(io->field("Int7", &obj->Int7));
 | 
				
			||||||
	oxReturnError(io->field("Int8", &obj->Int8));
 | 
						OX_RETURN_ERROR(io->field("Int8", &obj->Int8));
 | 
				
			||||||
	oxReturnError(io->field("unionIdx", &obj->unionIdx));
 | 
						OX_RETURN_ERROR(io->field("unionIdx", &obj->unionIdx));
 | 
				
			||||||
	if (io->opType() == ox::OpType::Reflect) {
 | 
						if (io->opType() == ox::OpType::Reflect) {
 | 
				
			||||||
		oxReturnError(io->field("Union", ox::UnionView{&obj->Union, 0}));
 | 
							OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, 0}));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		oxReturnError(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
 | 
							OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(io->field("String", &obj->String));
 | 
						OX_RETURN_ERROR(io->field("String", &obj->String));
 | 
				
			||||||
	oxReturnError(io->field("List", obj->List, 4));
 | 
						OX_RETURN_ERROR(io->field("List", obj->List, 4));
 | 
				
			||||||
	oxReturnError(io->field("Map", &obj->Map));
 | 
						OX_RETURN_ERROR(io->field("Map", &obj->Map));
 | 
				
			||||||
	oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
 | 
						OX_RETURN_ERROR(io->field("EmptyStruct", &obj->EmptyStruct));
 | 
				
			||||||
	oxReturnError(io->field("Struct", &obj->Struct));
 | 
						OX_RETURN_ERROR(io->field("Struct", &obj->Struct));
 | 
				
			||||||
	return OxError(0);
 | 
						return ox::Error(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TestStruct::TestStruct(TestStruct &&other) noexcept {
 | 
					TestStruct::TestStruct(TestStruct &&other) noexcept {
 | 
				
			||||||
@@ -184,7 +184,7 @@ const std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				oxAssert(testIn.Struct.String      == testOut.Struct.String, "Struct.String value mismatch");
 | 
									oxAssert(testIn.Struct.String      == testOut.Struct.String, "Struct.String value mismatch");
 | 
				
			||||||
				oxAssert(testIn.Struct.Bool        == testOut.Struct.Bool, "Struct.Bool value mismatch");
 | 
									oxAssert(testIn.Struct.Bool        == testOut.Struct.Bool, "Struct.Bool value mismatch");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -207,10 +207,10 @@ const std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
		   testIn.Union.Int = 93;
 | 
							   testIn.Union.Int = 93;
 | 
				
			||||||
		   oxAssert(ox::writeOC(testIn).moveTo(dataBuff), "Data generation failed");
 | 
							   oxAssert(ox::writeOC(testIn).moveTo(dataBuff), "Data generation failed");
 | 
				
			||||||
		   ox::TypeStore typeStore;
 | 
							   ox::TypeStore typeStore;
 | 
				
			||||||
		   auto type = ox::buildTypeDef(&typeStore, &testIn);
 | 
							   auto type = ox::buildTypeDef(typeStore, testIn);
 | 
				
			||||||
		   oxAssert(type.error, "Descriptor write failed");
 | 
							   oxAssert(type.error, "Descriptor write failed");
 | 
				
			||||||
		   ox::ModelObject testOut;
 | 
							   ox::ModelObject testOut;
 | 
				
			||||||
		   oxReturnError(testOut.setType(type.value));
 | 
							   OX_RETURN_ERROR(testOut.setType(type.value));
 | 
				
			||||||
		   oxAssert(ox::readOC(dataBuff, testOut), "Data read failed");
 | 
							   oxAssert(ox::readOC(dataBuff, testOut), "Data read failed");
 | 
				
			||||||
		   oxAssert(testOut.get("Int").unwrap()->get<int>() == testIn.Int, "testOut.Int failed");
 | 
							   oxAssert(testOut.get("Int").unwrap()->get<int>() == testIn.Int, "testOut.Int failed");
 | 
				
			||||||
		   oxAssert(testOut.get("Bool").unwrap()->get<bool>() == testIn.Bool, "testOut.Bool failed");
 | 
							   oxAssert(testOut.get("Bool").unwrap()->get<bool>() == testIn.Bool, "testOut.Bool failed");
 | 
				
			||||||
@@ -234,7 +234,7 @@ const std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
		   oxAssert(testOutStructCopy.get("String").unwrap()->get<ox::String>() == testIn.Struct.String.c_str(), "testOut.Struct.String (copy) failed");
 | 
							   oxAssert(testOutStructCopy.get("String").unwrap()->get<ox::String>() == testIn.Struct.String.c_str(), "testOut.Struct.String (copy) failed");
 | 
				
			||||||
		   oxAssert(testOutListCopy[0].get<uint32_t>() == testIn.List[0], "testOut.Struct.List[0] (copy) failed");
 | 
							   oxAssert(testOutListCopy[0].get<uint32_t>() == testIn.List[0], "testOut.Struct.List[0] (copy) failed");
 | 
				
			||||||
		   oxAssert(testOutListCopy[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] (copy) failed");
 | 
							   oxAssert(testOutListCopy[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] (copy) failed");
 | 
				
			||||||
		   return OxError(0);
 | 
							   return ox::Error(0);
 | 
				
			||||||
		   }
 | 
							   }
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -257,9 +257,9 @@ const std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
				auto [oc, ocErr] = ox::writeOC(testIn);
 | 
									auto [oc, ocErr] = ox::writeOC(testIn);
 | 
				
			||||||
				oxAssert(ocErr, "Data generation failed");
 | 
									oxAssert(ocErr, "Data generation failed");
 | 
				
			||||||
				ox::TypeStore typeStore;
 | 
									ox::TypeStore typeStore;
 | 
				
			||||||
				auto type = ox::buildTypeDef(&typeStore, &testIn);
 | 
									auto type = ox::buildTypeDef(typeStore, testIn);
 | 
				
			||||||
				oxAssert(type.error, "Descriptor write failed");
 | 
									oxAssert(type.error, "Descriptor write failed");
 | 
				
			||||||
				oxReturnError(ox::walkModel<ox::OrganicClawReader>(type.value, oc.data(), oc.size(),
 | 
									OX_RETURN_ERROR(ox::walkModel<ox::OrganicClawReader>(type.value, oc.data(), oc.size(),
 | 
				
			||||||
					[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::String>&, const ox::DescriptorField &f,
 | 
										[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::String>&, const ox::DescriptorField &f,
 | 
				
			||||||
					   ox::OrganicClawReader *rdr) -> ox::Error {
 | 
										   ox::OrganicClawReader *rdr) -> ox::Error {
 | 
				
			||||||
						auto fieldName = f.fieldName.c_str();
 | 
											auto fieldName = f.fieldName.c_str();
 | 
				
			||||||
@@ -341,10 +341,10 @@ const std::map<ox::StringView, ox::Error(*)()> tests = {
 | 
				
			|||||||
							case ox::PrimitiveType::Union:
 | 
												case ox::PrimitiveType::Union:
 | 
				
			||||||
								break;
 | 
													break;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						return OxError(0);
 | 
											return ox::Error(0);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				));
 | 
									));
 | 
				
			||||||
				return OxError(0);
 | 
									return ox::Error(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								deps/ox/src/ox/oc/write.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								deps/ox/src/ox/oc/write.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -23,7 +23,7 @@ Error OrganicClawWriter::fieldCString(const char *key, const char *const*val, in
 | 
				
			|||||||
		value(key) = *val;
 | 
							value(key) = *val;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_fieldIt;
 | 
						++m_fieldIt;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Error OrganicClawWriter::fieldCString(const char *key, const char *const*val) noexcept {
 | 
					Error OrganicClawWriter::fieldCString(const char *key, const char *const*val) noexcept {
 | 
				
			||||||
@@ -32,7 +32,7 @@ Error OrganicClawWriter::fieldCString(const char *key, const char *const*val) no
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Error OrganicClawWriter::field(const char *key, const UUID *uuid) noexcept {
 | 
					Error OrganicClawWriter::field(const char *key, const UUID *uuid) noexcept {
 | 
				
			||||||
	const auto uuidStr = uuid->toString();
 | 
						const auto uuidStr = uuid->toString();
 | 
				
			||||||
	if (targetValid() && uuidStr.len()) {
 | 
						if (targetValid() && uuidStr.size()) {
 | 
				
			||||||
		value(key) = uuidStr.c_str();
 | 
							value(key) = uuidStr.c_str();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_fieldIt;
 | 
						++m_fieldIt;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										76
									
								
								deps/ox/src/ox/oc/write.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								deps/ox/src/ox/oc/write.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -8,7 +8,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ox/std/def.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
#include <json/json.h>
 | 
					#include <json/json.h>
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <ox/model/fieldcounter.hpp>
 | 
					#include <ox/model/fieldcounter.hpp>
 | 
				
			||||||
#include <ox/model/modelhandleradaptor.hpp>
 | 
					#include <ox/model/modelhandleradaptor.hpp>
 | 
				
			||||||
@@ -24,7 +28,8 @@ namespace ox {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class OrganicClawWriter {
 | 
					class OrganicClawWriter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	friend Result<Buffer> writeOC(const auto &val) noexcept;
 | 
						friend Result<ox::Buffer> writeOC(const auto &val) noexcept;
 | 
				
			||||||
 | 
						friend Result<ox::String> writeOCString(const auto &val) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected:
 | 
						protected:
 | 
				
			||||||
		Json::Value m_json{Json::Value(Json::objectValue)};
 | 
							Json::Value m_json{Json::Value(Json::objectValue)};
 | 
				
			||||||
@@ -41,7 +46,7 @@ class OrganicClawWriter {
 | 
				
			|||||||
				value(key) = *val;
 | 
									value(key) = *val;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			++m_fieldIt;
 | 
								++m_fieldIt;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error field(const char *key, const int16_t *val) noexcept {
 | 
							Error field(const char *key, const int16_t *val) noexcept {
 | 
				
			||||||
@@ -49,7 +54,7 @@ class OrganicClawWriter {
 | 
				
			|||||||
				value(key) = *val;
 | 
									value(key) = *val;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			++m_fieldIt;
 | 
								++m_fieldIt;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error field(const char *key, const int32_t *val) noexcept {
 | 
							Error field(const char *key, const int32_t *val) noexcept {
 | 
				
			||||||
@@ -57,7 +62,7 @@ class OrganicClawWriter {
 | 
				
			|||||||
				value(key) = *val;
 | 
									value(key) = *val;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			++m_fieldIt;
 | 
								++m_fieldIt;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error field(const char *key, const int64_t *val) noexcept {
 | 
							Error field(const char *key, const int64_t *val) noexcept {
 | 
				
			||||||
@@ -65,7 +70,7 @@ class OrganicClawWriter {
 | 
				
			|||||||
				value(key) = *val;
 | 
									value(key) = *val;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			++m_fieldIt;
 | 
								++m_fieldIt;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -74,7 +79,7 @@ class OrganicClawWriter {
 | 
				
			|||||||
				value(key) = *val;
 | 
									value(key) = *val;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			++m_fieldIt;
 | 
								++m_fieldIt;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error field(const char *key, const uint16_t *val) noexcept {
 | 
							Error field(const char *key, const uint16_t *val) noexcept {
 | 
				
			||||||
@@ -82,7 +87,7 @@ class OrganicClawWriter {
 | 
				
			|||||||
				value(key) = *val;
 | 
									value(key) = *val;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			++m_fieldIt;
 | 
								++m_fieldIt;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error field(const char *key, const uint32_t *val) noexcept {
 | 
							Error field(const char *key, const uint32_t *val) noexcept {
 | 
				
			||||||
@@ -90,7 +95,7 @@ class OrganicClawWriter {
 | 
				
			|||||||
				value(key) = *val;
 | 
									value(key) = *val;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			++m_fieldIt;
 | 
								++m_fieldIt;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error field(const char *key, const uint64_t *val) noexcept {
 | 
							Error field(const char *key, const uint64_t *val) noexcept {
 | 
				
			||||||
@@ -98,7 +103,7 @@ class OrganicClawWriter {
 | 
				
			|||||||
				value(key) = *val;
 | 
									value(key) = *val;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			++m_fieldIt;
 | 
								++m_fieldIt;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error field(char const*key, bool const*val) noexcept {
 | 
							Error field(char const*key, bool const*val) noexcept {
 | 
				
			||||||
@@ -121,8 +126,8 @@ class OrganicClawWriter {
 | 
				
			|||||||
				for (std::size_t i = 0; i < keys.size(); ++i) {
 | 
									for (std::size_t i = 0; i < keys.size(); ++i) {
 | 
				
			||||||
					const auto k = keys[i].c_str();
 | 
										const auto k = keys[i].c_str();
 | 
				
			||||||
					if (k) [[likely]] {
 | 
										if (k) [[likely]] {
 | 
				
			||||||
						oxRequireM(value, val->at(k));
 | 
											OX_REQUIRE_M(value, val->at(k));
 | 
				
			||||||
						oxReturnError(handler.field(k, value));
 | 
											OX_RETURN_ERROR(handler.field(k, value));
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				value(key) = w.m_json;
 | 
									value(key) = w.m_json;
 | 
				
			||||||
@@ -133,7 +138,7 @@ class OrganicClawWriter {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		template<std::size_t L>
 | 
							template<std::size_t L>
 | 
				
			||||||
		Error field(char const*key, IString<L> const*val) noexcept {
 | 
							Error field(char const*key, IString<L> const*val) noexcept {
 | 
				
			||||||
			if (targetValid() && val->len()) {
 | 
								if (targetValid() && val->size()) {
 | 
				
			||||||
				value(key) = val->c_str();
 | 
									value(key) = val->c_str();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			++m_fieldIt;
 | 
								++m_fieldIt;
 | 
				
			||||||
@@ -142,11 +147,11 @@ class OrganicClawWriter {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		template<std::size_t L>
 | 
							template<std::size_t L>
 | 
				
			||||||
		Error field(char const*key, BasicString<L> const*val) noexcept {
 | 
							Error field(char const*key, BasicString<L> const*val) noexcept {
 | 
				
			||||||
			if (targetValid() && val->len()) {
 | 
								if (targetValid() && val->size()) {
 | 
				
			||||||
				value(key) = val->c_str();
 | 
									value(key) = val->c_str();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			++m_fieldIt;
 | 
								++m_fieldIt;
 | 
				
			||||||
			return OxError(0);
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Error fieldCString(const char*, const char *const*val, int len) noexcept;
 | 
							Error fieldCString(const char*, const char *const*val, int len) noexcept;
 | 
				
			||||||
@@ -199,12 +204,14 @@ Error OrganicClawWriter::field(const char *key, const T *val, std::size_t len) n
 | 
				
			|||||||
		OrganicClawWriter w((Json::Value(Json::arrayValue)));
 | 
							OrganicClawWriter w((Json::Value(Json::arrayValue)));
 | 
				
			||||||
		ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
 | 
							ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
 | 
				
			||||||
		for (std::size_t i = 0; i < len; ++i) {
 | 
							for (std::size_t i = 0; i < len; ++i) {
 | 
				
			||||||
			oxReturnError(handler.field({}, &val[i]));
 | 
					OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
 | 
								OX_RETURN_ERROR(handler.field({}, &val[i]));
 | 
				
			||||||
 | 
					OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		value(key) = w.m_json;
 | 
							value(key) = w.m_json;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_fieldIt;
 | 
						++m_fieldIt;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
@@ -224,13 +231,13 @@ Error OrganicClawWriter::field(const char *key, const T *val) noexcept {
 | 
				
			|||||||
	} else if (val && targetValid()) {
 | 
						} else if (val && targetValid()) {
 | 
				
			||||||
		OrganicClawWriter w;
 | 
							OrganicClawWriter w;
 | 
				
			||||||
		ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
 | 
							ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
 | 
				
			||||||
		oxReturnError(model(&handler, val));
 | 
							OX_RETURN_ERROR(model(&handler, val));
 | 
				
			||||||
		if (!w.m_json.empty() || m_json.isArray()) {
 | 
							if (!w.m_json.empty() || m_json.isArray()) {
 | 
				
			||||||
			value(key) = w.m_json;
 | 
								value(key) = w.m_json;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_fieldIt;
 | 
						++m_fieldIt;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename U, bool force>
 | 
					template<typename U, bool force>
 | 
				
			||||||
@@ -238,23 +245,40 @@ Error OrganicClawWriter::field(const char *key, UnionView<U, force> val) noexcep
 | 
				
			|||||||
	if (targetValid()) {
 | 
						if (targetValid()) {
 | 
				
			||||||
		OrganicClawWriter w(val.idx());
 | 
							OrganicClawWriter w(val.idx());
 | 
				
			||||||
		ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
 | 
							ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
 | 
				
			||||||
		oxReturnError(model(&handler, val.get()));
 | 
							OX_RETURN_ERROR(model(&handler, val.get()));
 | 
				
			||||||
		if (!w.m_json.isNull()) {
 | 
							if (!w.m_json.isNull()) {
 | 
				
			||||||
			value(key) = w.m_json;
 | 
								value(key) = w.m_json;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	++m_fieldIt;
 | 
						++m_fieldIt;
 | 
				
			||||||
	return OxError(0);
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result<Buffer> writeOC(const auto &val) noexcept {
 | 
					Result<ox::Buffer> writeOC(const auto &val) noexcept {
 | 
				
			||||||
	OrganicClawWriter writer;
 | 
						OrganicClawWriter writer;
 | 
				
			||||||
	ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler(&writer);
 | 
						ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler(&writer);
 | 
				
			||||||
	oxReturnError(model(&handler, &val));
 | 
						OX_RETURN_ERROR(model(&handler, &val));
 | 
				
			||||||
	Json::StreamWriterBuilder jsonBuilder;
 | 
						Json::StreamWriterBuilder const jsonBuilder;
 | 
				
			||||||
	const auto str = Json::writeString(jsonBuilder, writer.m_json);
 | 
						const auto str = Json::writeString(jsonBuilder, writer.m_json);
 | 
				
			||||||
	Buffer buff(str.size() + 1);
 | 
						Result<Buffer> buff;
 | 
				
			||||||
	memcpy(buff.data(), str.c_str(), str.size() + 1);
 | 
						buff.value.resize(str.size() + 1);
 | 
				
			||||||
 | 
						OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
 | 
						memcpy(buff.value.data(), str.data(), str.size() + 1);
 | 
				
			||||||
 | 
						OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
 | 
						return buff;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Result<ox::String> writeOCString(const auto &val) noexcept {
 | 
				
			||||||
 | 
						OrganicClawWriter writer;
 | 
				
			||||||
 | 
						ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler(&writer);
 | 
				
			||||||
 | 
						OX_RETURN_ERROR(model(&handler, &val));
 | 
				
			||||||
 | 
						Json::StreamWriterBuilder const jsonBuilder;
 | 
				
			||||||
 | 
						const auto str = Json::writeString(jsonBuilder, writer.m_json);
 | 
				
			||||||
 | 
						Result<ox::String> buff;
 | 
				
			||||||
 | 
						buff.value.resize(str.size());
 | 
				
			||||||
 | 
						OX_ALLOW_UNSAFE_BUFFERS_BEGIN
 | 
				
			||||||
 | 
						memcpy(buff.value.data(), str.data(), str.size() + 1);
 | 
				
			||||||
 | 
						OX_ALLOW_UNSAFE_BUFFERS_END
 | 
				
			||||||
	return buff;
 | 
						return buff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								deps/ox/src/ox/preloader/alignmentcatcher.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								deps/ox/src/ox/preloader/alignmentcatcher.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -46,12 +46,12 @@ struct AlignmentCatcher: public ModelHandlerBase<AlignmentCatcher<PlatSpec>, OpT
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<typename T, bool force>
 | 
						template<typename T, bool force>
 | 
				
			||||||
	constexpr ox::Error field(CRStringView name, const UnionView<T, force> val) noexcept {
 | 
						constexpr ox::Error field(StringViewCR name, const UnionView<T, force> val) noexcept {
 | 
				
			||||||
		return field(name, val.get());
 | 
							return field(name, val.get());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<typename T>
 | 
						template<typename T>
 | 
				
			||||||
	constexpr ox::Error field(CRStringView, const T *val) noexcept {
 | 
						constexpr ox::Error field(StringViewCR, const T *val) noexcept {
 | 
				
			||||||
		if constexpr(ox::is_pointer_v<T> || ox::is_integer_v<T>) {
 | 
							if constexpr(ox::is_pointer_v<T> || ox::is_integer_v<T>) {
 | 
				
			||||||
			biggestAlignment = ox::max(biggestAlignment, PlatSpec::alignOf(*val));
 | 
								biggestAlignment = ox::max(biggestAlignment, PlatSpec::alignOf(*val));
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
@@ -61,9 +61,9 @@ struct AlignmentCatcher: public ModelHandlerBase<AlignmentCatcher<PlatSpec>, OpT
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<typename T>
 | 
						template<typename T>
 | 
				
			||||||
	constexpr ox::Error field(CRStringView, const T *val, std::size_t cnt) noexcept {
 | 
						constexpr ox::Error field(StringViewCR, const T *val, std::size_t cnt) noexcept {
 | 
				
			||||||
		for (std::size_t i = 0; i < cnt; ++i) {
 | 
							for (std::size_t i = 0; i < cnt; ++i) {
 | 
				
			||||||
			oxReturnError(field(nullptr, &val[i]));
 | 
								OX_RETURN_ERROR(field(nullptr, &val[i]));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/preloader/platspecs.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/preloader/platspecs.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/preloader/preloader.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/preloader/preloader.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										106
									
								
								deps/ox/src/ox/preloader/preloader.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										106
									
								
								deps/ox/src/ox/preloader/preloader.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -94,19 +94,19 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>, OpType::Reflect> {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename U, bool force>
 | 
							template<typename U, bool force>
 | 
				
			||||||
		constexpr ox::Error field(CRStringView, ox::UnionView<U, force> val) noexcept;
 | 
							constexpr ox::Error field(StringViewCR, ox::UnionView<U, force> val) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename T>
 | 
							template<typename T>
 | 
				
			||||||
		constexpr ox::Error field(CRStringView, const T *val) noexcept;
 | 
							constexpr ox::Error field(StringViewCR, const T *val) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<std::size_t SmallStringSize>
 | 
							template<std::size_t SmallStringSize>
 | 
				
			||||||
		constexpr ox::Error field(CRStringView, const ox::BasicString<SmallStringSize> *val) noexcept;
 | 
							constexpr ox::Error field(StringViewCR, const ox::BasicString<SmallStringSize> *val) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename T, std::size_t sz>
 | 
							template<typename T, std::size_t sz>
 | 
				
			||||||
		constexpr ox::Error field(CRStringView, const ox::Array<T, sz> *valArray) noexcept;
 | 
							constexpr ox::Error field(StringViewCR, const ox::Array<T, sz> *valArray) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename T>
 | 
							template<typename T>
 | 
				
			||||||
		constexpr ox::Error field(CRStringView, const T **val, std::size_t cnt) noexcept;
 | 
							constexpr ox::Error field(StringViewCR, const T **val, std::size_t cnt) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		constexpr ox::Result<std::size_t> startAlloc(size_t sz, size_t align) noexcept;
 | 
							constexpr ox::Result<std::size_t> startAlloc(size_t sz, size_t align) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -125,14 +125,14 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>, OpType::Reflect> {
 | 
				
			|||||||
		constexpr ox::Error pad(const T*) noexcept;
 | 
							constexpr ox::Error pad(const T*) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		constexpr ox::Error fieldVector(CRStringView name, const ox::ModelValueVector *val) noexcept;
 | 
							constexpr ox::Error fieldVector(StringViewCR name, const ox::ModelValueVector *val) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename T, std::size_t SmallVectorSize, typename Allocator>
 | 
							template<typename T, std::size_t SmallVectorSize, typename Allocator>
 | 
				
			||||||
		constexpr ox::Error fieldVector(CRStringView, const ox::Vector<T, SmallVectorSize, Allocator> *val) noexcept;
 | 
							constexpr ox::Error fieldVector(StringViewCR, const ox::Vector<T, SmallVectorSize, Allocator> *val) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		constexpr ox::Error fieldVector(CRStringView, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept;
 | 
							constexpr ox::Error fieldVector(StringViewCR, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		constexpr ox::Error fieldArray(CRStringView name, ox::ModelValueArray const*val) noexcept;
 | 
							constexpr ox::Error fieldArray(StringViewCR name, ox::ModelValueArray const*val) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		constexpr bool unionCheckAndIt() noexcept;
 | 
							constexpr bool unionCheckAndIt() noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -158,11 +158,11 @@ Preloader<PlatSpec>::make(ox::ios_base::seekdir anchor, std::size_t sz) noexcept
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename PlatSpec>
 | 
					template<typename PlatSpec>
 | 
				
			||||||
template<typename U, bool force>
 | 
					template<typename U, bool force>
 | 
				
			||||||
constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::UnionView<U, force> val) noexcept {
 | 
					constexpr ox::Error Preloader<PlatSpec>::field(StringViewCR, const ox::UnionView<U, force> val) noexcept {
 | 
				
			||||||
	if (!unionCheckAndIt()) {
 | 
						if (!unionCheckAndIt()) {
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(pad(val.get()));
 | 
						OX_RETURN_ERROR(pad(val.get()));
 | 
				
			||||||
	m_unionIdx.emplace_back(val.idx());
 | 
						m_unionIdx.emplace_back(val.idx());
 | 
				
			||||||
	const auto err = preload<PlatSpec, U>(this, val.get());
 | 
						const auto err = preload<PlatSpec, U>(this, val.get());
 | 
				
			||||||
	m_unionIdx.pop_back();
 | 
						m_unionIdx.pop_back();
 | 
				
			||||||
@@ -171,17 +171,17 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::UnionView
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename PlatSpec>
 | 
					template<typename PlatSpec>
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const T *val) noexcept {
 | 
					constexpr ox::Error Preloader<PlatSpec>::field(StringViewCR name, const T *val) noexcept {
 | 
				
			||||||
	if (!unionCheckAndIt()) {
 | 
						if (!unionCheckAndIt()) {
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(pad(val));
 | 
						OX_RETURN_ERROR(pad(val));
 | 
				
			||||||
	if constexpr(ox::is_integral_v<T>) {
 | 
						if constexpr(ox::is_integral_v<T>) {
 | 
				
			||||||
		return ox::serialize(m_writer, PlatSpec::correctEndianness(*val));
 | 
							return ox::serialize(m_writer, PlatSpec::correctEndianness(*val));
 | 
				
			||||||
	} else if constexpr(ox::is_pointer_v<T>) {
 | 
						} else if constexpr(ox::is_pointer_v<T>) {
 | 
				
			||||||
		const PtrType a = startAlloc(sizeOf<PlatSpec>(val), alignOf<PlatSpec>(*val), m_writer.tellp()) + PlatSpec::RomStart;
 | 
							const PtrType a = startAlloc(sizeOf<PlatSpec>(val), alignOf<PlatSpec>(*val), m_writer.tellp()) + PlatSpec::RomStart;
 | 
				
			||||||
		oxReturnError(field(name, *val));
 | 
							OX_RETURN_ERROR(field(name, *val));
 | 
				
			||||||
		oxReturnError(endAlloc());
 | 
							OX_RETURN_ERROR(endAlloc());
 | 
				
			||||||
		return ox::serialize(m_writer, PlatSpec::correctEndianness(a));
 | 
							return ox::serialize(m_writer, PlatSpec::correctEndianness(a));
 | 
				
			||||||
	} else if constexpr(ox::isVector_v<T>) {
 | 
						} else if constexpr(ox::isVector_v<T>) {
 | 
				
			||||||
		return fieldVector(name, val);
 | 
							return fieldVector(name, val);
 | 
				
			||||||
@@ -200,7 +200,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const T *val)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename PlatSpec>
 | 
					template<typename PlatSpec>
 | 
				
			||||||
template<std::size_t SmallStringSize>
 | 
					template<std::size_t SmallStringSize>
 | 
				
			||||||
constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::BasicString<SmallStringSize> *val) noexcept {
 | 
					constexpr ox::Error Preloader<PlatSpec>::field(StringViewCR, const ox::BasicString<SmallStringSize> *val) noexcept {
 | 
				
			||||||
	if (!unionCheckAndIt()) {
 | 
						if (!unionCheckAndIt()) {
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -211,35 +211,35 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::BasicStri
 | 
				
			|||||||
		.size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(sz)),
 | 
							.size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(sz)),
 | 
				
			||||||
		.cap = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(sz)),
 | 
							.cap = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(sz)),
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	oxReturnError(pad(&vecVal));
 | 
						OX_RETURN_ERROR(pad(&vecVal));
 | 
				
			||||||
	const auto restore = m_writer.tellp();
 | 
						const auto restore = m_writer.tellp();
 | 
				
			||||||
	std::size_t a = 0;
 | 
						std::size_t a = 0;
 | 
				
			||||||
	if (sz && sz >= SmallStringSize) {
 | 
						if (sz && sz >= SmallStringSize) {
 | 
				
			||||||
		oxReturnError(ox::allocate(m_writer, sz).moveTo(a));
 | 
							OX_RETURN_ERROR(ox::allocate(m_writer, sz).moveTo(a));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		a = restore;
 | 
							a = restore;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	vecVal.items = PlatSpec::correctEndianness(static_cast<PtrType>(a) + PlatSpec::RomStart);
 | 
						vecVal.items = PlatSpec::correctEndianness(static_cast<PtrType>(a) + PlatSpec::RomStart);
 | 
				
			||||||
	oxReturnError(m_writer.seekp(a));
 | 
						OX_RETURN_ERROR(m_writer.seekp(a));
 | 
				
			||||||
	oxReturnError(m_writer.write(val->data(), sz));
 | 
						OX_RETURN_ERROR(m_writer.write(val->data(), sz));
 | 
				
			||||||
	oxReturnError(m_writer.seekp(restore));
 | 
						OX_RETURN_ERROR(m_writer.seekp(restore));
 | 
				
			||||||
	oxReturnError(serialize(m_writer, vecVal));
 | 
						OX_RETURN_ERROR(serialize(m_writer, vecVal));
 | 
				
			||||||
	m_ptrs.emplace_back(restore + offsetof(VecMap, items), vecVal.items);
 | 
						m_ptrs.emplace_back(restore + offsetof(VecMap, items), vecVal.items);
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename PlatSpec>
 | 
					template<typename PlatSpec>
 | 
				
			||||||
template<typename T, std::size_t sz>
 | 
					template<typename T, std::size_t sz>
 | 
				
			||||||
constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const ox::Array<T, sz> *val) noexcept {
 | 
					constexpr ox::Error Preloader<PlatSpec>::field(StringViewCR name, const ox::Array<T, sz> *val) noexcept {
 | 
				
			||||||
	if (!unionCheckAndIt()) {
 | 
						if (!unionCheckAndIt()) {
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(pad(&(*val)[0]));
 | 
						OX_RETURN_ERROR(pad(&(*val)[0]));
 | 
				
			||||||
	// serialize the Array elements
 | 
						// serialize the Array elements
 | 
				
			||||||
	if constexpr(sz) {
 | 
						if constexpr(sz) {
 | 
				
			||||||
		m_unionIdx.emplace_back(-1);
 | 
							m_unionIdx.emplace_back(-1);
 | 
				
			||||||
		for (std::size_t i = 0; i < val->size(); ++i) {
 | 
							for (std::size_t i = 0; i < val->size(); ++i) {
 | 
				
			||||||
			oxReturnError(this->interface()->field(name, &(*val)[i]));
 | 
								OX_RETURN_ERROR(this->interface()->field(name, &(*val)[i]));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		m_unionIdx.pop_back();
 | 
							m_unionIdx.pop_back();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -248,16 +248,16 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const ox::Arra
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename PlatSpec>
 | 
					template<typename PlatSpec>
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const T **val, std::size_t cnt) noexcept {
 | 
					constexpr ox::Error Preloader<PlatSpec>::field(StringViewCR, const T **val, std::size_t cnt) noexcept {
 | 
				
			||||||
	if (!unionCheckAndIt()) {
 | 
						if (!unionCheckAndIt()) {
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (cnt) {
 | 
						if (cnt) {
 | 
				
			||||||
		oxReturnError(pad(*val));
 | 
							OX_RETURN_ERROR(pad(*val));
 | 
				
			||||||
		// serialize the array
 | 
							// serialize the array
 | 
				
			||||||
		m_unionIdx.emplace_back(-1);
 | 
							m_unionIdx.emplace_back(-1);
 | 
				
			||||||
		for (std::size_t i = 0; i < cnt; ++i) {
 | 
							for (std::size_t i = 0; i < cnt; ++i) {
 | 
				
			||||||
			oxReturnError(this->interface()->field(nullptr, &val[i]));
 | 
								OX_RETURN_ERROR(this->interface()->field(nullptr, &val[i]));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		m_unionIdx.pop_back();
 | 
							m_unionIdx.pop_back();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -267,11 +267,11 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const T **val, std:
 | 
				
			|||||||
template<typename PlatSpec>
 | 
					template<typename PlatSpec>
 | 
				
			||||||
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(size_t sz, size_t align) noexcept {
 | 
					constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(size_t sz, size_t align) noexcept {
 | 
				
			||||||
	m_allocStack.emplace_back(static_cast<typename PlatSpec::PtrType>(m_writer.tellp()));
 | 
						m_allocStack.emplace_back(static_cast<typename PlatSpec::PtrType>(m_writer.tellp()));
 | 
				
			||||||
	oxReturnError(m_writer.seekp(0, ox::ios_base::end));
 | 
						OX_RETURN_ERROR(m_writer.seekp(0, ox::ios_base::end));
 | 
				
			||||||
	auto const padding = calcPadding(align);
 | 
						auto const padding = calcPadding(align);
 | 
				
			||||||
	oxRequireM(a, ox::allocate(m_writer, sz + padding));
 | 
						OX_REQUIRE_M(a, ox::allocate(m_writer, sz + padding));
 | 
				
			||||||
	a += padding;
 | 
						a += padding;
 | 
				
			||||||
	oxReturnError(m_writer.seekp(a));
 | 
						OX_RETURN_ERROR(m_writer.seekp(a));
 | 
				
			||||||
	m_allocStart.push_back(a);
 | 
						m_allocStart.push_back(a);
 | 
				
			||||||
	return a;
 | 
						return a;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -280,11 +280,11 @@ template<typename PlatSpec>
 | 
				
			|||||||
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(
 | 
					constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(
 | 
				
			||||||
		std::size_t sz, size_t align, std::size_t restore) noexcept {
 | 
							std::size_t sz, size_t align, std::size_t restore) noexcept {
 | 
				
			||||||
	m_allocStack.emplace_back(restore, ox::ios_base::beg);
 | 
						m_allocStack.emplace_back(restore, ox::ios_base::beg);
 | 
				
			||||||
	oxReturnError(m_writer.seekp(0, ox::ios_base::end));
 | 
						OX_RETURN_ERROR(m_writer.seekp(0, ox::ios_base::end));
 | 
				
			||||||
	auto const padding = calcPadding(align);
 | 
						auto const padding = calcPadding(align);
 | 
				
			||||||
	oxRequireM(a, ox::allocate(m_writer, sz + padding));
 | 
						OX_REQUIRE_M(a, ox::allocate(m_writer, sz + padding));
 | 
				
			||||||
	a += padding;
 | 
						a += padding;
 | 
				
			||||||
	oxReturnError(m_writer.seekp(a));
 | 
						OX_RETURN_ERROR(m_writer.seekp(a));
 | 
				
			||||||
	m_allocStart.push_back(a);
 | 
						m_allocStart.push_back(a);
 | 
				
			||||||
	return a;
 | 
						return a;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -295,7 +295,7 @@ constexpr ox::Error Preloader<PlatSpec>::endAlloc() noexcept {
 | 
				
			|||||||
		return m_writer.seekp(0, ox::ios_base::end);
 | 
							return m_writer.seekp(0, ox::ios_base::end);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	const auto &si = *m_allocStack.back().unwrap();
 | 
						const auto &si = *m_allocStack.back().unwrap();
 | 
				
			||||||
	oxReturnError(m_writer.seekp(static_cast<ox::ssize_t>(si.restore), si.seekdir));
 | 
						OX_RETURN_ERROR(m_writer.seekp(static_cast<ox::ssize_t>(si.restore), si.seekdir));
 | 
				
			||||||
	m_allocStack.pop_back();
 | 
						m_allocStack.pop_back();
 | 
				
			||||||
	m_allocStart.pop_back();
 | 
						m_allocStart.pop_back();
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
@@ -304,12 +304,12 @@ constexpr ox::Error Preloader<PlatSpec>::endAlloc() noexcept {
 | 
				
			|||||||
template<typename PlatSpec>
 | 
					template<typename PlatSpec>
 | 
				
			||||||
constexpr ox::Error Preloader<PlatSpec>::offsetPtrs(std::size_t offset) noexcept {
 | 
					constexpr ox::Error Preloader<PlatSpec>::offsetPtrs(std::size_t offset) noexcept {
 | 
				
			||||||
	for (const auto &p : m_ptrs) {
 | 
						for (const auto &p : m_ptrs) {
 | 
				
			||||||
		oxReturnError(m_writer.seekp(p.loc));
 | 
							OX_RETURN_ERROR(m_writer.seekp(p.loc));
 | 
				
			||||||
		const auto val = PlatSpec::template correctEndianness<typename PlatSpec::PtrType>(
 | 
							const auto val = PlatSpec::template correctEndianness<typename PlatSpec::PtrType>(
 | 
				
			||||||
				static_cast<typename PlatSpec::PtrType>(p.value + offset));
 | 
									static_cast<typename PlatSpec::PtrType>(p.value + offset));
 | 
				
			||||||
		oxReturnError(ox::serialize(m_writer, val));
 | 
							OX_RETURN_ERROR(ox::serialize(m_writer, val));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oxReturnError(m_writer.seekp(0, ox::ios_base::end));
 | 
						OX_RETURN_ERROR(m_writer.seekp(0, ox::ios_base::end));
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -327,7 +327,7 @@ constexpr ox::Error Preloader<PlatSpec>::pad(const T *v) noexcept {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename PlatSpec>
 | 
					template<typename PlatSpec>
 | 
				
			||||||
constexpr ox::Error Preloader<PlatSpec>::fieldVector(
 | 
					constexpr ox::Error Preloader<PlatSpec>::fieldVector(
 | 
				
			||||||
		CRStringView name, const ox::ModelValueVector *val) noexcept {
 | 
							StringViewCR name, const ox::ModelValueVector *val) noexcept {
 | 
				
			||||||
	// serialize the Vector
 | 
						// serialize the Vector
 | 
				
			||||||
	ox::VectorMemMap<PlatSpec> vecVal{
 | 
						ox::VectorMemMap<PlatSpec> vecVal{
 | 
				
			||||||
			.size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
 | 
								.size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
 | 
				
			||||||
@@ -339,7 +339,7 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(
 | 
				
			|||||||
template<typename PlatSpec>
 | 
					template<typename PlatSpec>
 | 
				
			||||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
 | 
					template<typename T, std::size_t SmallVectorSize, typename Allocator>
 | 
				
			||||||
constexpr ox::Error Preloader<PlatSpec>::fieldVector(
 | 
					constexpr ox::Error Preloader<PlatSpec>::fieldVector(
 | 
				
			||||||
		CRStringView name, const ox::Vector<T, SmallVectorSize, Allocator> *val) noexcept {
 | 
							StringViewCR name, const ox::Vector<T, SmallVectorSize, Allocator> *val) noexcept {
 | 
				
			||||||
	// serialize the Vector
 | 
						// serialize the Vector
 | 
				
			||||||
	ox::VectorMemMap<PlatSpec> vecVal{
 | 
						ox::VectorMemMap<PlatSpec> vecVal{
 | 
				
			||||||
		.smallVecSize = SmallVectorSize * sizeOf<PlatSpec>(static_cast<T*>(nullptr)),
 | 
							.smallVecSize = SmallVectorSize * sizeOf<PlatSpec>(static_cast<T*>(nullptr)),
 | 
				
			||||||
@@ -353,40 +353,40 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename PlatSpec>
 | 
					template<typename PlatSpec>
 | 
				
			||||||
constexpr ox::Error Preloader<PlatSpec>::fieldVector(
 | 
					constexpr ox::Error Preloader<PlatSpec>::fieldVector(
 | 
				
			||||||
		CRStringView, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept {
 | 
							StringViewCR, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept {
 | 
				
			||||||
	oxReturnError(pad(&vecVal));
 | 
						OX_RETURN_ERROR(pad(&vecVal));
 | 
				
			||||||
	const auto vecValPt = m_writer.tellp();
 | 
						const auto vecValPt = m_writer.tellp();
 | 
				
			||||||
	// serialize the Vector elements
 | 
						// serialize the Vector elements
 | 
				
			||||||
	if (val->size()) {
 | 
						if (val->size()) {
 | 
				
			||||||
		const auto sz = sizeOf<PlatSpec>(&(*val)[0]) * val->size();
 | 
							const auto sz = sizeOf<PlatSpec>(&(*val)[0]) * val->size();
 | 
				
			||||||
		const auto align = alignOf<PlatSpec>((*val)[0]);
 | 
							const auto align = alignOf<PlatSpec>((*val)[0]);
 | 
				
			||||||
		oxReturnError(m_writer.seekp(0, ox::ios_base::end));
 | 
							OX_RETURN_ERROR(m_writer.seekp(0, ox::ios_base::end));
 | 
				
			||||||
		auto const padding = calcPadding(align);
 | 
							auto const padding = calcPadding(align);
 | 
				
			||||||
		oxRequireM(p, ox::allocate(m_writer, sz + padding));
 | 
							OX_REQUIRE_M(p, ox::allocate(m_writer, sz + padding));
 | 
				
			||||||
		p += padding;
 | 
							p += padding;
 | 
				
			||||||
		oxReturnError(m_writer.seekp(p));
 | 
							OX_RETURN_ERROR(m_writer.seekp(p));
 | 
				
			||||||
		m_unionIdx.emplace_back(-1);
 | 
							m_unionIdx.emplace_back(-1);
 | 
				
			||||||
		for (std::size_t i = 0; i < val->size(); ++i) {
 | 
							for (std::size_t i = 0; i < val->size(); ++i) {
 | 
				
			||||||
			oxReturnError(this->interface()->field(nullptr, &val->operator[](i)));
 | 
								OX_RETURN_ERROR(this->interface()->field(nullptr, &val->operator[](i)));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		m_unionIdx.pop_back();
 | 
							m_unionIdx.pop_back();
 | 
				
			||||||
		vecVal.items = PlatSpec::correctEndianness(
 | 
							vecVal.items = PlatSpec::correctEndianness(
 | 
				
			||||||
				static_cast<typename PlatSpec::size_t>(p + PlatSpec::RomStart));
 | 
									static_cast<typename PlatSpec::size_t>(p + PlatSpec::RomStart));
 | 
				
			||||||
		oxReturnError(m_writer.seekp(vecValPt));
 | 
							OX_RETURN_ERROR(m_writer.seekp(vecValPt));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		vecVal.items = 0;
 | 
							vecVal.items = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// serialize the Vector
 | 
						// serialize the Vector
 | 
				
			||||||
	oxReturnError(serialize(m_writer, vecVal));
 | 
						OX_RETURN_ERROR(serialize(m_writer, vecVal));
 | 
				
			||||||
	m_ptrs.emplace_back(m_writer.tellp() - PtrSize, vecVal.items);
 | 
						m_ptrs.emplace_back(m_writer.tellp() - PtrSize, vecVal.items);
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename PlatSpec>
 | 
					template<typename PlatSpec>
 | 
				
			||||||
constexpr ox::Error Preloader<PlatSpec>::fieldArray(CRStringView, ox::ModelValueArray const*val) noexcept {
 | 
					constexpr ox::Error Preloader<PlatSpec>::fieldArray(StringViewCR, ox::ModelValueArray const*val) noexcept {
 | 
				
			||||||
	oxReturnError(pad(&(*val)[0]));
 | 
						OX_RETURN_ERROR(pad(&(*val)[0]));
 | 
				
			||||||
	for (auto const&v : *val) {
 | 
						for (auto const&v : *val) {
 | 
				
			||||||
		oxReturnError(this->interface()->field({}, &v));
 | 
							OX_RETURN_ERROR(this->interface()->field({}, &v));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -405,7 +405,7 @@ constexpr size_t Preloader<PlatSpec>::calcPadding(size_t align) const noexcept {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<typename PlatSpec, typename T>
 | 
					template<typename PlatSpec, typename T>
 | 
				
			||||||
constexpr ox::Error preload(Preloader<PlatSpec> *pl, ox::CommonPtrWith<T> auto *obj) noexcept {
 | 
					constexpr ox::Error preload(Preloader<PlatSpec> *pl, ox::CommonPtrWith<T> auto *obj) noexcept {
 | 
				
			||||||
	oxReturnError(model(pl->interface(), obj));
 | 
						OX_RETURN_ERROR(model(pl->interface(), obj));
 | 
				
			||||||
	return pl->pad(obj);
 | 
						return pl->pad(obj);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								deps/ox/src/ox/preloader/sizecatcher.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								deps/ox/src/ox/preloader/sizecatcher.hpp
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 - 2024 gary@drinkingtea.net
 | 
					 * Copyright 2015 - 2025 gary@drinkingtea.net
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
				
			||||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
					 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
				
			||||||
@@ -74,7 +74,7 @@ template<typename T, bool force>
 | 
				
			|||||||
constexpr ox::Error SizeCatcher<PlatSpec>::field(const char*, const UnionView<T, force> val) noexcept {
 | 
					constexpr ox::Error SizeCatcher<PlatSpec>::field(const char*, const UnionView<T, force> val) noexcept {
 | 
				
			||||||
	pad(val.get());
 | 
						pad(val.get());
 | 
				
			||||||
	UnionSizeCatcher<PlatSpec> sc;
 | 
						UnionSizeCatcher<PlatSpec> sc;
 | 
				
			||||||
	oxReturnError(model(sc.interface(), val.get()));
 | 
						OX_RETURN_ERROR(model(sc.interface(), val.get()));
 | 
				
			||||||
	m_size += sc.size();
 | 
						m_size += sc.size();
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -91,7 +91,7 @@ template<typename PlatSpec>
 | 
				
			|||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr ox::Error SizeCatcher<PlatSpec>::field(const char*, const T **val, std::size_t cnt) noexcept {
 | 
					constexpr ox::Error SizeCatcher<PlatSpec>::field(const char*, const T **val, std::size_t cnt) noexcept {
 | 
				
			||||||
	for (std::size_t i = 0; i < cnt; ++i) {
 | 
						for (std::size_t i = 0; i < cnt; ++i) {
 | 
				
			||||||
		oxReturnError(field("", &val[i]));
 | 
							OX_RETURN_ERROR(field("", &val[i]));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return {};
 | 
						return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user