mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-14 00:25:26 +00:00
Compare commits
680 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34aea4361f | ||
|
|
be1ad33910 | ||
|
|
0cf04ad9d5 | ||
|
|
fe483fa380 | ||
|
|
8a8dc4e111 | ||
|
|
7e803c410c | ||
|
|
1336d26252 | ||
|
|
853f7033e0 | ||
|
|
e2c7196ea8 | ||
|
|
61fe2a4fac | ||
|
|
d233b38008 | ||
|
|
ca52bfefc0 | ||
|
|
2edb1dcdda | ||
|
|
6eb031de9a | ||
|
|
5f2af34e02 | ||
|
|
f3f113b24a | ||
|
|
6bb0a728d3 | ||
|
|
97face1527 | ||
|
|
f2627e16ac | ||
|
|
01bac38c84 | ||
|
|
a1b5f565d9 | ||
|
|
0780a7db24 | ||
|
|
9234ddcf11 | ||
|
|
6d9a226f75 | ||
|
|
b0fd1a8c66 | ||
|
|
a0e5d78353 | ||
|
|
bc8a1608a8 | ||
|
|
30e7d16104 | ||
|
|
9c3920d0ab | ||
|
|
5b4acf809e | ||
|
|
86fb05d320 | ||
|
|
5e4739184f | ||
|
|
971a68110e | ||
|
|
7a6b2bf521 | ||
|
|
03e2899985 | ||
|
|
72a99abfb7 | ||
|
|
21a8121982 | ||
|
|
28920aff8f | ||
|
|
77b22aed5a | ||
|
|
cc25516d3e | ||
|
|
1d444f63d3 | ||
|
|
5fa00630af | ||
|
|
97af3d798b | ||
|
|
bb736091f3 | ||
|
|
d5b4db0692 | ||
|
|
5808f7fb03 | ||
|
|
42611f9a83 | ||
|
|
1f0bd12851 | ||
|
|
321a1c9dc0 | ||
|
|
ac1015e3c4 | ||
|
|
513958ea72 | ||
|
|
2f2e4cced4 | ||
|
|
f779962e3e | ||
|
|
69776b9e7e | ||
|
|
00d726fc4c | ||
|
|
ad0f48d7e7 | ||
|
|
801e1b7699 | ||
|
|
432e7582c6 | ||
|
|
d76113100a | ||
|
|
dca33ddb75 | ||
|
|
76744a4345 | ||
|
|
b4e91091ec | ||
|
|
d5f5d382eb | ||
|
|
ffddbdc7ab | ||
|
|
46bb05d952 | ||
|
|
7cc72e4b11 | ||
|
|
a6a3f59253 | ||
|
|
8a58aafda1 | ||
|
|
8dc1641c8a | ||
|
|
4b27c92910 | ||
|
|
7fe281295f | ||
|
|
917ff81b46 | ||
|
|
8a2cc7cc4e | ||
|
|
a64d968473 | ||
|
|
a2b1bfc107 | ||
|
|
f2b3705c2c | ||
|
|
3282a84e30 | ||
|
|
89a68942ac | ||
|
|
360c34467c | ||
|
|
265e43faf0 | ||
|
|
f064a6cc60 | ||
|
|
7fead0f140 | ||
|
|
d6f14b704f | ||
|
|
a892322203 | ||
|
|
2e2063cbeb | ||
|
|
625c989875 | ||
|
|
f20204180d | ||
|
|
0e85eeef2c | ||
|
|
b0fa5e0f42 | ||
|
|
25a15950f5 | ||
|
|
6f94fb51b1 | ||
|
|
57f3752d5e | ||
|
|
f52f848b95 | ||
|
|
3c3742a54a | ||
|
|
f325cce6fd | ||
|
|
88a85ffbbd | ||
|
|
35cbd23f63 | ||
|
|
210a1ab969 | ||
|
|
90c8ded449 | ||
|
|
8f864aad7b | ||
|
|
dddd0865cb | ||
|
|
0a81eb6463 | ||
|
|
b1740688bf | ||
|
|
86b505e412 | ||
|
|
da67c0a71f | ||
|
|
dadd1a926e | ||
|
|
01c50d57a6 | ||
|
|
e9f1f4d9b7 | ||
|
|
dd05f3249a | ||
|
|
43611fcc0b | ||
|
|
642254bee6 | ||
|
|
22743ca45a | ||
|
|
fb87c0d3c6 | ||
|
|
398ae0cb6b | ||
|
|
aaf5598a03 | ||
|
|
3d2cf554d7 | ||
|
|
55dec4d2f8 | ||
|
|
0f5f7faa9f | ||
|
|
90daabd5b1 | ||
|
|
262e1d7bf9 | ||
|
|
c559eb451e | ||
|
|
6a7ec85e83 | ||
|
|
81ecc98e02 | ||
|
|
9aeeddf5ac | ||
|
|
c7bfe06c54 | ||
|
|
349a391208 | ||
|
|
9d01bfaea3 | ||
|
|
cfbab31fb1 | ||
|
|
cb2481efdc | ||
|
|
d7ac3788e8 | ||
|
|
a0a313b101 | ||
|
|
93c0960c3a | ||
|
|
04d734d6d2 | ||
|
|
8468ea1ab4 | ||
|
|
0920d663d5 | ||
|
|
bbb72f0b73 | ||
|
|
8f8a27d6e5 | ||
|
|
86777bd66b | ||
|
|
8b92122f33 | ||
|
|
e93a5652d0 | ||
|
|
0c80b3a7cc | ||
|
|
f52ddfbd68 | ||
|
|
808b44f87a | ||
|
|
340d1a3447 | ||
|
|
ba20d9bff3 | ||
|
|
370693a200 | ||
|
|
33932ceea4 | ||
|
|
fb03f78fb4 | ||
|
|
523f3833eb | ||
|
|
46497e4f9a | ||
|
|
b627b7c6c6 | ||
|
|
e093f72d00 | ||
|
|
728bb64fed | ||
|
|
a07f0d428d | ||
|
|
b90d4e049d | ||
|
|
b0752e179b | ||
|
|
1fc12e0e5b | ||
|
|
e6fa7b1133 | ||
|
|
28e7dbd3d3 | ||
|
|
adc50051e0 | ||
|
|
2aec880347 | ||
|
|
238a8ebb15 | ||
|
|
86992476da | ||
|
|
751aeabc80 | ||
|
|
b4bb1b103f | ||
|
|
cffd187fc7 | ||
|
|
ccfa317486 | ||
|
|
a5cc2092a6 | ||
|
|
89041a1686 | ||
|
|
7a36419f24 | ||
|
|
281284fa5d | ||
|
|
1a27c7017a | ||
|
|
b8f5f84437 | ||
|
|
f2071e4f80 | ||
|
|
9c25ecdcd1 | ||
|
|
1beed12e59 | ||
|
|
4cd71d67f1 | ||
|
|
d9bc5ec047 | ||
|
|
c04c143cf0 | ||
|
|
c6aae45364 | ||
|
|
7f2a1c90d5 | ||
|
|
f5387387de | ||
|
|
e7e4dc755d | ||
|
|
b8224809ad | ||
|
|
bb22fb5756 | ||
|
|
ff274771ba | ||
|
|
15bf626191 | ||
|
|
ac106e835c | ||
|
|
640b525e83 | ||
|
|
0b379211dc | ||
|
|
bb223da258 | ||
|
|
17c5f89d4f | ||
|
|
695d26183a | ||
|
|
f5120a2aaf | ||
|
|
037314a059 | ||
|
|
ebcfbbadf0 | ||
|
|
6561c7a31f | ||
|
|
a6d98fb067 | ||
|
|
3a2d3a232f | ||
|
|
cebdad4d23 | ||
|
|
d798100be9 | ||
|
|
1fb6b9ee6f | ||
|
|
2d6e8f096b | ||
|
|
ec8038cc3d | ||
|
|
2df3d1c965 | ||
|
|
2272229983 | ||
|
|
b7bfecb4ee | ||
|
|
c7c4bbfce2 | ||
|
|
d7ba17dfe5 | ||
|
|
60b11435e6 | ||
|
|
ed2110d7b3 | ||
|
|
a9514de978 | ||
|
|
c57ab92e60 | ||
|
|
f878024d0b | ||
|
|
aac6be1153 | ||
|
|
dabe030890 | ||
|
|
29574282a2 | ||
|
|
2dd6ba57d1 | ||
|
|
6cc2307c71 | ||
|
|
74c8c7137a | ||
|
|
f9055ff9a7 | ||
|
|
9b3d8b318a | ||
|
|
87e29b25de | ||
|
|
f7bc9bd51b | ||
|
|
3dee617c86 | ||
|
|
2fb25e2bb3 | ||
|
|
b395359b6e | ||
|
|
fd61d70205 | ||
|
|
4f4495a693 | ||
|
|
68bbe983e9 | ||
|
|
bbef92c17d | ||
|
|
25c884158f | ||
|
|
3f936c5655 | ||
|
|
42a265b419 | ||
|
|
4bc4979acc | ||
|
|
b095367d17 | ||
|
|
eac2905568 | ||
|
|
12fd0c6838 | ||
|
|
19101826a8 | ||
|
|
7b94eab2b1 | ||
|
|
1a21b54560 | ||
|
|
b55f18649a | ||
|
|
e2373668d9 | ||
|
|
8c1a723ba5 | ||
|
|
ab7949dc16 | ||
|
|
2c4dce5ba7 | ||
|
|
cc84240098 | ||
|
|
b29ba4c70c | ||
|
|
fea6b525ee | ||
|
|
69dc71b5ed | ||
|
|
1a89682251 | ||
|
|
5fd0fefab6 | ||
|
|
f8a964d2b0 | ||
|
|
84033ae035 | ||
|
|
b9efbf6a3d | ||
|
|
13194ececa | ||
|
|
9ec9303abb | ||
|
|
03ee3db240 | ||
|
|
cf825b8819 | ||
|
|
377a8ba6b2 | ||
|
|
13cf6e66e3 | ||
|
|
81b6bacead | ||
|
|
e6fa14a08d | ||
|
|
c66683f27f | ||
|
|
6d6271db2f | ||
|
|
ab76c57ec8 | ||
|
|
d1e8899310 | ||
|
|
ccba2edb7c | ||
|
|
2a7a44be33 | ||
|
|
6301da75d1 | ||
|
|
059661b9ac | ||
|
|
dc5975ba7a | ||
|
|
0de4f3f75b | ||
|
|
b59aafc659 | ||
|
|
92a6ae93fa | ||
|
|
a31ddd2bb3 | ||
|
|
bc2ec7119b | ||
|
|
641b397f8b | ||
|
|
d342918790 | ||
|
|
c4377390a8 | ||
|
|
5608be0f96 | ||
|
|
dbecdf209d | ||
|
|
c05803bf96 | ||
|
|
d298adc4e6 | ||
|
|
c2050aa0e3 | ||
|
|
290e9f270b | ||
|
|
76ae10df42 | ||
|
|
cf0d7829a6 | ||
|
|
af21b9064d | ||
|
|
e31fbb0b23 | ||
|
|
43ba7c6369 | ||
|
|
dae513e0e7 | ||
|
|
d8944e45a2 | ||
|
|
5b5fcbfc00 | ||
|
|
6862b2ff08 | ||
|
|
22e87071dd | ||
|
|
606098cac8 | ||
|
|
b5c622762b | ||
|
|
2beb985fcc | ||
|
|
fd97404c51 | ||
|
|
d9fe4e2769 | ||
|
|
424fc0c3ac | ||
|
|
c81239f6ea | ||
|
|
b830dac266 | ||
|
|
dc38f93ca8 | ||
|
|
f9025eeb52 | ||
|
|
486c048a0d | ||
|
|
ab51b03093 | ||
|
|
dc2fa215b8 | ||
|
|
199157e8f4 | ||
|
|
520d68449f | ||
|
|
b075b8c49d | ||
|
|
f6c1a1ebcf | ||
|
|
c4aede2268 | ||
|
|
4a43c2bb2c | ||
|
|
b2e55c556e | ||
|
|
df0991b7de | ||
|
|
3368407aff | ||
|
|
25f3f358a0 | ||
|
|
00e8aa87b3 | ||
|
|
09ee46a83e | ||
|
|
02dfa64a89 | ||
|
|
f136570417 | ||
|
|
b6ba322a04 | ||
|
|
4b79ff5351 | ||
|
|
edd77ae2f3 | ||
|
|
985de211af | ||
|
|
8e3fa336eb | ||
|
|
582fd90c4a | ||
|
|
a15659e9f8 | ||
|
|
afd230af8d | ||
|
|
52ca75506a | ||
|
|
3bb9b839b8 | ||
|
|
5e7bfd0461 | ||
|
|
d05d114523 | ||
|
|
722b903f89 | ||
|
|
2ff6152204 | ||
|
|
98f9af8ecc | ||
|
|
481d332e72 | ||
|
|
1a18122e3f | ||
|
|
ee56418cef | ||
|
|
e1f8037cb5 | ||
|
|
ea9ee4c99e | ||
|
|
4026117ba1 | ||
|
|
49ee30a207 | ||
|
|
7c69c5dc3d | ||
|
|
223ebebbeb | ||
|
|
f96eb472b3 | ||
|
|
c1b0abe079 | ||
|
|
b04e21db16 | ||
|
|
756050b62c | ||
|
|
ef67a58410 | ||
|
|
2da0821286 | ||
|
|
928effd198 | ||
|
|
2e7806ede0 | ||
|
|
67967476b2 | ||
|
|
79d127c863 | ||
|
|
4f3e1c2831 | ||
|
|
199a49b5b3 | ||
|
|
96ab6ade5a | ||
|
|
9f16090f90 | ||
|
|
63b240ec7b | ||
|
|
c4ba502f57 | ||
|
|
94d5643f97 | ||
|
|
f0d91fa143 | ||
|
|
726a5f523e | ||
|
|
eba6b6f7c9 | ||
|
|
fa74ce6d16 | ||
|
|
8fdced4e11 | ||
|
|
9031597f49 | ||
|
|
a0b8f669ee | ||
|
|
18d67ed83b | ||
|
|
205ddb175f | ||
|
|
be908939da | ||
|
|
c96fc7fcef | ||
|
|
026c6ddb17 | ||
|
|
3eebba789f | ||
|
|
b36bd67b39 | ||
|
|
dc7f5bc0d8 | ||
|
|
ec20233fab | ||
|
|
867dfc5957 | ||
|
|
73d5bf46b4 | ||
|
|
f6416d8471 | ||
|
|
52acb4b347 | ||
|
|
d70f5ac6b0 | ||
|
|
c9b9fd0407 | ||
|
|
6897bb99bb | ||
|
|
4c861daa3e | ||
|
|
c9ee9fb99d | ||
|
|
50e13ef9c6 | ||
|
|
f624065eaa | ||
|
|
03adfa7b1a | ||
|
|
97a9a82324 | ||
|
|
307694e397 | ||
|
|
d268d11ca2 | ||
|
|
094f4d1bad | ||
|
|
a0398ce0f5 | ||
|
|
30c07f4e55 | ||
|
|
fc19f746b0 | ||
|
|
a351124cfd | ||
|
|
0230a7173f | ||
|
|
5f351a35a2 | ||
|
|
2d427e0502 | ||
|
|
1bba4fd9ea | ||
|
|
f98870715a | ||
|
|
b7a26d73ee | ||
|
|
1ba4d3c4c7 | ||
|
|
f61f0449c7 | ||
|
|
06c1ad5a73 | ||
|
|
38b3893211 | ||
|
|
42e0b02149 | ||
|
|
a56c6e5195 | ||
|
|
5efa22447e | ||
|
|
bdd668df7b | ||
|
|
05b00c50ad | ||
|
|
77e9122681 | ||
|
|
e067040375 | ||
|
|
370e101a69 | ||
|
|
91f5cf357c | ||
|
|
7c7c571bbe | ||
|
|
3101e327c0 | ||
|
|
46bf9f5177 | ||
|
|
694725beb0 | ||
|
|
ce3e7fbd72 | ||
|
|
53e9606ea2 | ||
|
|
ffc0d6209a | ||
|
|
9fdb6dcf1f | ||
|
|
298dd21ec8 | ||
|
|
64fa8ba9a9 | ||
|
|
36daedf35f | ||
|
|
a8d2eeee34 | ||
|
|
e21a61d458 | ||
|
|
410fb15a07 | ||
|
|
a69b19fa8f | ||
|
|
58924538a3 | ||
|
|
e750268f0c | ||
|
|
0328dedab5 | ||
|
|
9605dc5981 | ||
|
|
00694d271e | ||
|
|
b22db6e8eb | ||
|
|
14e7e8260e | ||
|
|
3a1f776132 | ||
|
|
4b53762cf2 | ||
|
|
0d56276102 | ||
|
|
98c7a0c169 | ||
|
|
676f0712fd | ||
|
|
7a3f1cf78e | ||
|
|
49c10bc219 | ||
|
|
df9990acf5 | ||
|
|
3d7b1a32a3 | ||
|
|
db99c1aa64 | ||
|
|
247388a20c | ||
|
|
f6f88e567e | ||
|
|
e527b992f9 | ||
|
|
aade31b263 | ||
|
|
e733d95e66 | ||
|
|
14bdce41fe | ||
|
|
4a49493e27 | ||
|
|
df5575de17 | ||
|
|
f0b2cc8f6e | ||
|
|
5f2b4e7872 | ||
|
|
22697722d9 | ||
|
|
ffbc93526e | ||
|
|
d9d47a53bd | ||
|
|
71d30d5c02 | ||
|
|
1661f3a2e8 | ||
|
|
d9767b8315 | ||
|
|
193a631708 | ||
|
|
a6764b9bf1 | ||
|
|
0f5dc152b8 | ||
|
|
8e1aae0fd6 | ||
|
|
084e5dbc4b | ||
|
|
dfbda986d7 | ||
|
|
248432b92d | ||
|
|
f738981ed5 | ||
|
|
4bb6ab3cd5 | ||
|
|
72e8219a65 | ||
|
|
7a955a09f4 | ||
|
|
b730a74a19 | ||
|
|
cc2b04ce1c | ||
|
|
4f8abaaf10 | ||
|
|
5043764247 | ||
|
|
9fd4d66438 | ||
|
|
aae48e3a9d | ||
|
|
ff57f52b72 | ||
|
|
7d84a4914f | ||
|
|
c2411e9c8c | ||
|
|
bf26a0eccc | ||
|
|
68a83eddd4 | ||
|
|
b999d49945 | ||
|
|
c94cb6dae9 | ||
|
|
5ea2b49f58 | ||
|
|
70deb70b76 | ||
|
|
48f37f9e0a | ||
|
|
6dff7c68f1 | ||
|
|
ec59dc026f | ||
|
|
c97abb1eea | ||
|
|
2fdafa9a49 | ||
|
|
f794f97d88 | ||
|
|
03ad8fa4d9 | ||
|
|
43fedfa8ba | ||
|
|
2f52618c4e | ||
|
|
a9e21170bc | ||
|
|
cb6cc3dfb6 | ||
|
|
66f2aac26f | ||
|
|
4a249752ff | ||
|
|
f0695e0edf | ||
|
|
07d4066847 | ||
|
|
57ba8a4d46 | ||
|
|
9e6c5f9f2c | ||
|
|
3639032d1e | ||
|
|
6f75ec8490 | ||
|
|
fd43d3709e | ||
|
|
6e177bf03f | ||
|
|
d3ac0bc149 | ||
|
|
afa276288c | ||
|
|
4832238708 | ||
|
|
1f8e3c13e6 | ||
|
|
5a401aef57 | ||
|
|
78ecf45527 | ||
|
|
3ae503a191 | ||
|
|
bafd48d96c | ||
|
|
cf7e4b027a | ||
|
|
15863c34a0 | ||
|
|
9875b0e0f8 | ||
|
|
2bdf44a25d | ||
|
|
4ffc881fb6 | ||
|
|
e92ae5199d | ||
|
|
a3a2bf890f | ||
|
|
a9194c4c68 | ||
|
|
ca32eb77f3 | ||
|
|
886441df98 | ||
|
|
e02ceca54b | ||
|
|
b3c35750c2 | ||
|
|
3e52fecd1e | ||
|
|
cccd7003ed | ||
|
|
038ea7c1d3 | ||
|
|
0b0cf58f24 | ||
|
|
7d1f372ba6 | ||
|
|
25e4ad19f6 | ||
|
|
7dfe8e726b | ||
|
|
61b101d442 | ||
|
|
cd1493b082 | ||
|
|
a98bff3ea1 | ||
|
|
06eb6e94e3 | ||
|
|
4a8801da34 | ||
|
|
b1e8be27a9 | ||
|
|
b922a3c952 | ||
|
|
b52826e7cc | ||
|
|
0ef72db7bf | ||
|
|
505d0f2288 | ||
|
|
6704b19db6 | ||
|
|
64b91da9cf | ||
|
|
fe9787e58d | ||
|
|
d06e571b31 | ||
|
|
208c15f29d | ||
|
|
a82dbb6e01 | ||
|
|
a42a99029f | ||
|
|
0c7b700895 | ||
|
|
1aa3ee2170 | ||
|
|
8c0d56d55a | ||
|
|
c41a0453c1 | ||
|
|
1a161a8333 | ||
|
|
9d8ae1b0c3 | ||
|
|
2de558057d | ||
|
|
0756caa42e | ||
|
|
99c1ddc792 | ||
|
|
69eef0a0ec | ||
|
|
42bd6447c0 | ||
|
|
747a8c628e | ||
|
|
023fec627e | ||
|
|
3a8bc309e2 | ||
|
|
3400727fff | ||
|
|
77742a3fba | ||
|
|
7cce55d8f0 | ||
|
|
933c195e51 | ||
|
|
d0898fd0c8 | ||
|
|
6765c19d45 | ||
|
|
599f5e3915 | ||
|
|
ba7204a7b7 | ||
|
|
e8ac0f293e | ||
|
|
a0d1161feb | ||
|
|
828b2680c0 | ||
|
|
c17cf022ea | ||
|
|
f6330ab8f1 | ||
|
|
6908826f95 | ||
|
|
fd542c71e3 | ||
|
|
9fb87f813b | ||
|
|
b0146b3d9a | ||
|
|
286587d151 | ||
|
|
6f751d5d26 | ||
|
|
4d7890c2c9 | ||
|
|
fdfaf23361 | ||
|
|
38597160f2 | ||
|
|
791c83aa7e | ||
|
|
29d957ed5e | ||
|
|
8d8b7c19b7 | ||
|
|
039ab48b7a | ||
|
|
8a64afabfd | ||
|
|
4a04bac250 | ||
|
|
72fc45aa6a | ||
|
|
9f2b05df1b | ||
|
|
83dc5ed4a7 | ||
|
|
e597ad8f0f | ||
|
|
3ea5446680 | ||
|
|
8b18e487bd | ||
|
|
c837d29eab | ||
|
|
ec1daef858 | ||
|
|
7d396bc2e7 | ||
|
|
8128df7655 | ||
|
|
cfaa7782b6 | ||
|
|
5e3f9d5175 | ||
|
|
cdc5d5b18d | ||
|
|
e98b1912b3 | ||
|
|
c8c0082413 | ||
|
|
1c1d079113 | ||
|
|
7523e4ad49 | ||
|
|
f4a5c9de50 | ||
|
|
1db9783bfc | ||
|
|
5b38134431 | ||
|
|
4c16038e72 | ||
|
|
2f7f50b8cb | ||
|
|
a1633055f7 | ||
|
|
35f6bb5060 | ||
|
|
28a3c939e7 | ||
|
|
7d9779fc67 | ||
|
|
9b8c91c90b | ||
|
|
47d4b46950 | ||
|
|
a649cb7db5 | ||
|
|
68c69b3717 | ||
|
|
ce4d3316d3 | ||
|
|
e6b79f0002 | ||
|
|
1a63eb46bb | ||
|
|
91c27148c0 | ||
|
|
1e7310e6cd | ||
|
|
b49a7d146d | ||
|
|
fbc8af40e3 | ||
|
|
709e720839 | ||
|
|
3cd9181ef8 | ||
|
|
81e4d3c6c3 | ||
|
|
958fc6ec49 | ||
|
|
19afcdc704 | ||
|
|
51d48bd953 | ||
|
|
26f15bcd77 | ||
|
|
412b8d2c80 | ||
|
|
617fedf349 | ||
|
|
59caa536ed | ||
|
|
3d5f7f64f8 | ||
|
|
66126cc32d | ||
|
|
31b30335f6 | ||
|
|
959866b848 | ||
|
|
cbab26673b | ||
|
|
1cf5e3f751 | ||
|
|
9a76ce8a65 | ||
|
|
574404e2ee | ||
|
|
20c0082ee5 | ||
|
|
9d92aeb182 | ||
|
|
2f5d7ae645 | ||
|
|
d2bc73bbbe | ||
|
|
697cad7027 | ||
|
|
472fb12273 | ||
|
|
d779308b3e | ||
|
|
a03f3287b3 | ||
|
|
a88cf317fd | ||
|
|
4802e8a285 | ||
|
|
b611dc4b99 | ||
|
|
5f19ea5e45 | ||
|
|
e4abeef65c | ||
|
|
ac49eda053 | ||
|
|
1fa803d187 | ||
|
|
6d1ff8a525 | ||
|
|
59dc29a19a | ||
|
|
6db667b6b1 | ||
|
|
07da3fc216 | ||
|
|
c5835b896c | ||
|
|
345e8ca804 | ||
|
|
9202f0cf09 | ||
|
|
d10f9a6abc | ||
|
|
ec0c0b14ca | ||
|
|
6267f8c6c0 |
0
.gitattributes
vendored
Executable file → Normal file
0
.gitattributes
vendored
Executable file → Normal file
12
.github/ISSUE_TEMPLATE.md
vendored
Normal file
12
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Thank you for submitting an issue!
|
||||||
|
|
||||||
|
Please make sure you include the names of the affected language(s), compiler version(s), operating system version(s), and FlatBuffers version(s) in your issue title.
|
||||||
|
|
||||||
|
This helps us get the correct maintainers to look at your issue. Here are examples of good titles:
|
||||||
|
|
||||||
|
- Crash when accessing FlatBuffer [C++, gcc 4.8, OS X, master]
|
||||||
|
- Flatc converts a protobuf 'bytes' field to 'string' in fbs schema file [all languages, FlatBuffers 1.4]
|
||||||
|
|
||||||
|
Include other details as appropriate.
|
||||||
|
|
||||||
|
Thanks!
|
||||||
16
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
16
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Thank you for submitting a PR!
|
||||||
|
|
||||||
|
Please make sure you include the names of the affected language(s) in your PR title.
|
||||||
|
This helps us get the correct maintainers to look at your issue.
|
||||||
|
|
||||||
|
If you make changes to any of the code generators, be sure to run
|
||||||
|
`cd tests && sh generate_code.sh` (or equivalent .bat) and include the generated
|
||||||
|
code changes in the PR. This allows us to better see the effect of the PR.
|
||||||
|
|
||||||
|
If your PR includes C++ code, please adhere to the Google C++ Style Guide,
|
||||||
|
and don't forget we try to support older compilers (e.g. VS2010, GCC 4.6.3),
|
||||||
|
so only some C++11 support is available.
|
||||||
|
|
||||||
|
Include other details as appropriate.
|
||||||
|
|
||||||
|
Thanks!
|
||||||
24
.gitignore
vendored
Executable file → Normal file
24
.gitignore
vendored
Executable file → Normal file
@@ -5,6 +5,7 @@
|
|||||||
*.o.d
|
*.o.d
|
||||||
*.class
|
*.class
|
||||||
*.a
|
*.a
|
||||||
|
*.swp
|
||||||
*~
|
*~
|
||||||
*.vcxproj
|
*.vcxproj
|
||||||
*.vcxproj.filters
|
*.vcxproj.filters
|
||||||
@@ -40,12 +41,17 @@ flatsamplebinary
|
|||||||
flatsamplebinary.exe
|
flatsamplebinary.exe
|
||||||
flatsampletext
|
flatsampletext
|
||||||
flatsampletext.exe
|
flatsampletext.exe
|
||||||
|
grpctest
|
||||||
|
grpctest.exe
|
||||||
snapshot.sh
|
snapshot.sh
|
||||||
|
tags
|
||||||
tests/go_gen
|
tests/go_gen
|
||||||
tests/monsterdata_java_wire.mon
|
tests/monsterdata_java_wire.mon
|
||||||
tests/monsterdata_go_wire.mon
|
tests/monsterdata_go_wire.mon
|
||||||
tests/monsterdata_javascript_wire.mon
|
tests/monsterdata_javascript_wire.mon
|
||||||
tests/unicode_test.mon
|
tests/unicode_test.mon
|
||||||
|
tests/ts/
|
||||||
|
tests/php/
|
||||||
CMakeLists.txt.user
|
CMakeLists.txt.user
|
||||||
CMakeScripts/**
|
CMakeScripts/**
|
||||||
CTestTestfile.cmake
|
CTestTestfile.cmake
|
||||||
@@ -55,9 +61,23 @@ build/Xcode/FlatBuffers.xcodeproj/xcuserdata/**
|
|||||||
FlatBuffers.xcodeproj/
|
FlatBuffers.xcodeproj/
|
||||||
java/.idea
|
java/.idea
|
||||||
java/*.iml
|
java/*.iml
|
||||||
java/target
|
|
||||||
**/*.pyc
|
|
||||||
.idea
|
.idea
|
||||||
|
*.iml
|
||||||
|
target
|
||||||
|
**/*.pyc
|
||||||
build/VS2010/FlatBuffers.sdf
|
build/VS2010/FlatBuffers.sdf
|
||||||
build/VS2010/FlatBuffers.opensdf
|
build/VS2010/FlatBuffers.opensdf
|
||||||
build/VS2010/ipch/**/*.ipch
|
build/VS2010/ipch/**/*.ipch
|
||||||
|
*.so
|
||||||
|
Testing/Temporary
|
||||||
|
.cproject
|
||||||
|
.settings/
|
||||||
|
.project
|
||||||
|
net/**/obj
|
||||||
|
node_modules/
|
||||||
|
android/.externalNativeBuild/
|
||||||
|
android/.gradle/
|
||||||
|
android/build/
|
||||||
|
samples/android/.externalNativeBuild/
|
||||||
|
samples/android/.gradle/
|
||||||
|
samples/android/build/
|
||||||
|
|||||||
78
.travis.yml
78
.travis.yml
@@ -1,30 +1,58 @@
|
|||||||
language: cpp
|
|
||||||
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
- osx
|
|
||||||
|
|
||||||
compiler:
|
|
||||||
- gcc
|
|
||||||
#- clang
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
matrix:
|
|
||||||
- BUILD_TYPE=Debug BIICODE=false
|
|
||||||
- BUILD_TYPE=Release BIICODE=false
|
|
||||||
- BUILD_TYPE=Release BIICODE=true
|
|
||||||
- BUILD_TYPE=Debug BIICODE=true
|
|
||||||
global:
|
global:
|
||||||
|
# Set at the root level as this is ignored when set under matrix.env.
|
||||||
- GCC_VERSION="4.9"
|
- GCC_VERSION="4.9"
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- language: cpp
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
- osx
|
||||||
|
|
||||||
before_install:
|
compiler:
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
|
- gcc
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
|
#- clang
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq g++-$GCC_VERSION; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq gcc-$GCC_VERSION; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which g++-$GCC_VERSION) /usr/bin/g++; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which gcc-$GCC_VERSION) /usr/bin/gcc; fi
|
|
||||||
|
|
||||||
script:
|
env:
|
||||||
- if [ "$BIICODE" == "false" ]; then cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE . && make && make test; fi
|
matrix:
|
||||||
- if [ "$BIICODE" == "true" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then ./biicode/support/bii-travis.sh $BUILD_TYPE; fi
|
- BUILD_TYPE=Debug BIICODE=false
|
||||||
|
- BUILD_TYPE=Release BIICODE=false
|
||||||
|
# biicode .deb files no longer available.
|
||||||
|
# - BUILD_TYPE=Release BIICODE=true
|
||||||
|
# - BUILD_TYPE=Debug BIICODE=true
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq g++-$GCC_VERSION; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq gcc-$GCC_VERSION; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which g++-$GCC_VERSION) /usr/bin/g++; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which gcc-$GCC_VERSION) /usr/bin/gcc; fi
|
||||||
|
|
||||||
|
script:
|
||||||
|
- if [ "$BIICODE" == "false" ]; then cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE . && make && make test; fi
|
||||||
|
- if [ "$BIICODE" == "true" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then ./biicode/support/bii-travis.sh $BUILD_TYPE; fi
|
||||||
|
|
||||||
|
- language: android
|
||||||
|
sudo: true
|
||||||
|
android:
|
||||||
|
components:
|
||||||
|
- tools
|
||||||
|
- platform-tools
|
||||||
|
- build-tools-25.0.2
|
||||||
|
- android-25
|
||||||
|
- extra-android-m2repository
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
before_install:
|
||||||
|
- git clone https://github.com/urho3d/android-ndk.git $HOME/android-ndk-root
|
||||||
|
- export ANDROID_NDK_HOME=$HOME/android-ndk-root
|
||||||
|
# Setup environment for Linux build which is required to build the sample.
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq g++-$GCC_VERSION; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq gcc-$GCC_VERSION; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which g++-$GCC_VERSION) /usr/bin/g++; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which gcc-$GCC_VERSION) /usr/bin/gcc; fi
|
||||||
|
script:
|
||||||
|
- failed=0; for build_gradle in $(git ls-files | grep build.gradle); do ( cd "$(dirname "${build_gradle}")" && ./gradlew build ) || failed=1; done; exit $((failed))
|
||||||
|
|||||||
@@ -63,6 +63,13 @@ function(build_flatbuffers flatbuffers_schemas
|
|||||||
set(FLATC_TARGET flatc)
|
set(FLATC_TARGET flatc)
|
||||||
set(FLATC flatc)
|
set(FLATC flatc)
|
||||||
endif()
|
endif()
|
||||||
|
set(FLATC_SCHEMA_ARGS --gen-mutable)
|
||||||
|
if(FLATBUFFERS_FLATC_SCHEMA_EXTRA_ARGS)
|
||||||
|
set(FLATC_SCHEMA_ARGS
|
||||||
|
${FLATBUFFERS_FLATC_SCHEMA_EXTRA_ARGS}
|
||||||
|
${FLATC_SCHEMA_ARGS}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(schema_glob "*.fbs")
|
set(schema_glob "*.fbs")
|
||||||
# Generate the include files parameters.
|
# Generate the include files parameters.
|
||||||
@@ -86,7 +93,7 @@ function(build_flatbuffers flatbuffers_schemas
|
|||||||
set(generated_include ${generated_includes_dir}/${filename}_generated.h)
|
set(generated_include ${generated_includes_dir}/${filename}_generated.h)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${generated_include}
|
OUTPUT ${generated_include}
|
||||||
COMMAND ${FLATC} --gen-mutable
|
COMMAND ${FLATC} ${FLATC_SCHEMA_ARGS}
|
||||||
-o ${generated_includes_dir}
|
-o ${generated_includes_dir}
|
||||||
${include_params}
|
${include_params}
|
||||||
-c ${schema}
|
-c ${schema}
|
||||||
|
|||||||
4
CMake/FlatbuffersConfig.cmake
Normal file
4
CMake/FlatbuffersConfig.cmake
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/FlatbuffersTargets.cmake" OPTIONAL)
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/FlatcTargets.cmake" OPTIONAL)
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/FlatbuffersSharedTargets.cmake" OPTIONAL)
|
||||||
|
|
||||||
57
CMake/PackageDebian.cmake
Normal file
57
CMake/PackageDebian.cmake
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# ------------------- Debianization ---------------------
|
||||||
|
if (UNIX)
|
||||||
|
|
||||||
|
# Set build environment
|
||||||
|
SET(CPACK_GENERATOR "TGZ;DEB")
|
||||||
|
SET(CPACK_SOURCE_TGZ "ON")
|
||||||
|
|
||||||
|
# Common package information
|
||||||
|
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
|
||||||
|
"FlatBuffers is an efficient cross platform serialization library for C++, with support for Java, C# and Go. It was created at Google specifically for game development and other performance-critical applications.")
|
||||||
|
SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/google/flatbuffers")
|
||||||
|
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Vitaly Isaev <vitalyisaev2@gmail.com>")
|
||||||
|
|
||||||
|
# Derive package version from git
|
||||||
|
EXECUTE_PROCESS(
|
||||||
|
COMMAND date +%Y%m%d
|
||||||
|
OUTPUT_VARIABLE DATE
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
EXECUTE_PROCESS(
|
||||||
|
COMMAND git describe
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_DESCRIBE_DIRTY
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${GIT_DESCRIBE_DIRTY}")
|
||||||
|
string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${GIT_DESCRIBE_DIRTY}")
|
||||||
|
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${GIT_DESCRIBE_DIRTY}")
|
||||||
|
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+\\-([0-9]+).*" "\\1" VERSION_COMMIT "${GIT_DESCRIBE_DIRTY}")
|
||||||
|
SET(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
|
||||||
|
SET(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
|
||||||
|
SET(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
|
||||||
|
SET(CPACK_PACKAGE_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_COMMIT}")
|
||||||
|
SET(CPACK_DEBIAN_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}")
|
||||||
|
|
||||||
|
# Derive architecture
|
||||||
|
IF(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
|
||||||
|
FIND_PROGRAM(DPKG_CMD dpkg)
|
||||||
|
IF(NOT DPKG_CMD)
|
||||||
|
MESSAGE(STATUS "Can not find dpkg in your path, default to i386.")
|
||||||
|
SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE i386)
|
||||||
|
ENDIF(NOT DPKG_CMD)
|
||||||
|
EXECUTE_PROCESS(COMMAND "${DPKG_CMD}" --print-architecture
|
||||||
|
OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
ENDIF(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
|
||||||
|
|
||||||
|
# Package name
|
||||||
|
SET(CPACK_DEBIAN_PACKAGE_NAME "flatbuffers")
|
||||||
|
SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE.txt)
|
||||||
|
SET(CPACK_PACKAGE_FILE_NAME
|
||||||
|
"${CPACK_DEBIAN_PACKAGE_NAME}_${CPACK_DEBIAN_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
|
||||||
|
|
||||||
|
endif(UNIX)
|
||||||
|
|
||||||
|
INCLUDE(CPack)
|
||||||
204
CMakeLists.txt
204
CMakeLists.txt
@@ -6,9 +6,15 @@ project(FlatBuffers)
|
|||||||
option(FLATBUFFERS_CODE_COVERAGE "Enable the code coverage build option." OFF)
|
option(FLATBUFFERS_CODE_COVERAGE "Enable the code coverage build option." OFF)
|
||||||
option(FLATBUFFERS_BUILD_TESTS "Enable the build of tests and samples." ON)
|
option(FLATBUFFERS_BUILD_TESTS "Enable the build of tests and samples." ON)
|
||||||
option(FLATBUFFERS_INSTALL "Enable the installation of targets." ON)
|
option(FLATBUFFERS_INSTALL "Enable the installation of targets." ON)
|
||||||
option(FLATBUFFERS_BUILD_FLATLIB "Enable the build of the flatbuffers library" ON)
|
option(FLATBUFFERS_BUILD_FLATLIB "Enable the build of the flatbuffers library"
|
||||||
option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler" ON)
|
ON)
|
||||||
|
option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler"
|
||||||
|
ON)
|
||||||
option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" ON)
|
option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" ON)
|
||||||
|
option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF)
|
||||||
|
option(FLATBUFFERS_BUILD_SHAREDLIB
|
||||||
|
"Enable the build of the flatbuffers shared library"
|
||||||
|
OFF)
|
||||||
|
|
||||||
if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
|
if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
|
||||||
message(WARNING
|
message(WARNING
|
||||||
@@ -17,15 +23,23 @@ if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(FlatBuffers_Library_SRCS
|
set(FlatBuffers_Library_SRCS
|
||||||
|
include/flatbuffers/code_generators.h
|
||||||
|
include/flatbuffers/base.h
|
||||||
include/flatbuffers/flatbuffers.h
|
include/flatbuffers/flatbuffers.h
|
||||||
include/flatbuffers/hash.h
|
include/flatbuffers/hash.h
|
||||||
include/flatbuffers/idl.h
|
include/flatbuffers/idl.h
|
||||||
include/flatbuffers/util.h
|
include/flatbuffers/util.h
|
||||||
include/flatbuffers/reflection.h
|
include/flatbuffers/reflection.h
|
||||||
include/flatbuffers/reflection_generated.h
|
include/flatbuffers/reflection_generated.h
|
||||||
|
include/flatbuffers/stl_emulation.h
|
||||||
|
include/flatbuffers/flexbuffers.h
|
||||||
|
include/flatbuffers/registry.h
|
||||||
|
include/flatbuffers/minireflect.h
|
||||||
|
src/code_generators.cpp
|
||||||
src/idl_parser.cpp
|
src/idl_parser.cpp
|
||||||
src/idl_gen_text.cpp
|
src/idl_gen_text.cpp
|
||||||
src/reflection.cpp
|
src/reflection.cpp
|
||||||
|
src/util.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(FlatBuffers_Compiler_SRCS
|
set(FlatBuffers_Compiler_SRCS
|
||||||
@@ -37,7 +51,15 @@ set(FlatBuffers_Compiler_SRCS
|
|||||||
src/idl_gen_php.cpp
|
src/idl_gen_php.cpp
|
||||||
src/idl_gen_python.cpp
|
src/idl_gen_python.cpp
|
||||||
src/idl_gen_fbs.cpp
|
src/idl_gen_fbs.cpp
|
||||||
|
src/idl_gen_grpc.cpp
|
||||||
|
src/idl_gen_json_schema.cpp
|
||||||
src/flatc.cpp
|
src/flatc.cpp
|
||||||
|
src/flatc_main.cpp
|
||||||
|
grpc/src/compiler/schema_interface.h
|
||||||
|
grpc/src/compiler/cpp_generator.h
|
||||||
|
grpc/src/compiler/cpp_generator.cc
|
||||||
|
grpc/src/compiler/go_generator.h
|
||||||
|
grpc/src/compiler/go_generator.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
set(FlatHash_SRCS
|
set(FlatHash_SRCS
|
||||||
@@ -48,7 +70,6 @@ set(FlatHash_SRCS
|
|||||||
set(FlatBuffers_Tests_SRCS
|
set(FlatBuffers_Tests_SRCS
|
||||||
${FlatBuffers_Library_SRCS}
|
${FlatBuffers_Library_SRCS}
|
||||||
src/idl_gen_fbs.cpp
|
src/idl_gen_fbs.cpp
|
||||||
src/idl_gen_general.cpp
|
|
||||||
tests/test.cpp
|
tests/test.cpp
|
||||||
# file generate by running compiler on tests/monster_test.fbs
|
# file generate by running compiler on tests/monster_test.fbs
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
|
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
|
||||||
@@ -62,31 +83,75 @@ set(FlatBuffers_Sample_Binary_SRCS
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(FlatBuffers_Sample_Text_SRCS
|
set(FlatBuffers_Sample_Text_SRCS
|
||||||
include/flatbuffers/flatbuffers.h
|
${FlatBuffers_Library_SRCS}
|
||||||
include/flatbuffers/hash.h
|
|
||||||
include/flatbuffers/idl.h
|
|
||||||
include/flatbuffers/util.h
|
|
||||||
src/idl_parser.cpp
|
|
||||||
src/idl_gen_text.cpp
|
|
||||||
samples/sample_text.cpp
|
samples/sample_text.cpp
|
||||||
# file generated by running compiler on samples/monster.fbs
|
# file generated by running compiler on samples/monster.fbs
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
|
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(FlatBuffers_GRPCTest_SRCS
|
||||||
|
include/flatbuffers/flatbuffers.h
|
||||||
|
include/flatbuffers/grpc.h
|
||||||
|
tests/monster_test.grpc.fb.h
|
||||||
|
tests/monster_test.grpc.fb.cc
|
||||||
|
grpc/tests/grpctest.cpp
|
||||||
|
# file generated by running compiler on samples/monster.fbs
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
|
||||||
|
)
|
||||||
|
|
||||||
# source_group(Compiler FILES ${FlatBuffers_Compiler_SRCS})
|
# source_group(Compiler FILES ${FlatBuffers_Compiler_SRCS})
|
||||||
# source_group(Tests FILES ${FlatBuffers_Tests_SRCS})
|
# source_group(Tests FILES ${FlatBuffers_Tests_SRCS})
|
||||||
|
|
||||||
if(APPLE)
|
if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
|
||||||
set(CMAKE_CXX_FLAGS
|
# do not apply any global settings if the toolchain
|
||||||
"${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++ -Wall -pedantic -Werror -Wextra")
|
# is being configured externally
|
||||||
|
elseif(APPLE)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -Werror -Wextra -Wno-unused-parameter")
|
||||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
if(CYGWIN)
|
||||||
|
set(CMAKE_CXX_FLAGS
|
||||||
|
"${CMAKE_CXX_FLAGS} -std=gnu++11")
|
||||||
|
else(CYGWIN)
|
||||||
|
set(CMAKE_CXX_FLAGS
|
||||||
|
"${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||||
|
endif(CYGWIN)
|
||||||
set(CMAKE_CXX_FLAGS
|
set(CMAKE_CXX_FLAGS
|
||||||
"${CMAKE_CXX_FLAGS} -std=c++0x -Wall -pedantic -Werror -Wextra -Werror=shadow -Wunused-result -Werror=unused-result")
|
"${CMAKE_CXX_FLAGS} -Wall -pedantic -Werror -Wextra -Werror=shadow")
|
||||||
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
if (GCC_VERSION VERSION_GREATER 4.4)
|
||||||
|
set(CMAKE_CXX_FLAGS
|
||||||
|
"${CMAKE_CXX_FLAGS} -Wunused-result -Werror=unused-result \
|
||||||
|
-Wunused-parameter -Werror=unused-parameter")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Certain platforms such as ARM do not use signed chars by default
|
||||||
|
# which causes issues with certain bounds checks.
|
||||||
set(CMAKE_CXX_FLAGS
|
set(CMAKE_CXX_FLAGS
|
||||||
"${CMAKE_CXX_FLAGS} -std=c++0x -stdlib=libc++ -Wall -pedantic -Werror -Wextra")
|
"${CMAKE_CXX_FLAGS} -fsigned-char")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS
|
|
||||||
"${CMAKE_EXE_LINKER_FLAGS} -lc++abi")
|
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
||||||
|
set(CMAKE_CXX_FLAGS
|
||||||
|
"${CMAKE_CXX_FLAGS} -std=c++0x -Wall -pedantic -Werror -Wextra -Wno-unused-parameter")
|
||||||
|
if(NOT "${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
|
||||||
|
set(CMAKE_CXX_FLAGS
|
||||||
|
"${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||||
|
endif()
|
||||||
|
if(NOT ("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD" OR
|
||||||
|
"${CMAKE_SYSTEM_NAME}" MATCHES "Linux"))
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS
|
||||||
|
"${CMAKE_EXE_LINKER_FLAGS} -lc++abi")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Certain platforms such as ARM do not use signed chars by default
|
||||||
|
# which causes issues with certain bounds checks.
|
||||||
|
set(CMAKE_CXX_FLAGS
|
||||||
|
"${CMAKE_CXX_FLAGS} -fsigned-char")
|
||||||
|
|
||||||
|
elseif(MSVC)
|
||||||
|
# Visual Studio pedantic build settings
|
||||||
|
# warning C4512: assignment operator could not be generated
|
||||||
|
# warning C4316: object allocated on the heap may not be aligned
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX /wd4512 /wd4316")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FLATBUFFERS_CODE_COVERAGE)
|
if(FLATBUFFERS_CODE_COVERAGE)
|
||||||
@@ -101,6 +166,7 @@ if(BIICODE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
|
include_directories(grpc)
|
||||||
|
|
||||||
if(FLATBUFFERS_BUILD_FLATLIB)
|
if(FLATBUFFERS_BUILD_FLATLIB)
|
||||||
add_library(flatbuffers STATIC ${FlatBuffers_Library_SRCS})
|
add_library(flatbuffers STATIC ${FlatBuffers_Library_SRCS})
|
||||||
@@ -108,18 +174,44 @@ endif()
|
|||||||
|
|
||||||
if(FLATBUFFERS_BUILD_FLATC)
|
if(FLATBUFFERS_BUILD_FLATC)
|
||||||
add_executable(flatc ${FlatBuffers_Compiler_SRCS})
|
add_executable(flatc ${FlatBuffers_Compiler_SRCS})
|
||||||
|
if(NOT FLATBUFFERS_FLATC_EXECUTABLE)
|
||||||
|
set(FLATBUFFERS_FLATC_EXECUTABLE $<TARGET_FILE:flatc>)
|
||||||
|
endif()
|
||||||
|
if(MSVC)
|
||||||
|
# Make flatc.exe not depend on runtime dlls for easy distribution.
|
||||||
|
target_compile_options(flatc PUBLIC $<$<CONFIG:Release>:/MT>)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FLATBUFFERS_BUILD_FLATHASH)
|
if(FLATBUFFERS_BUILD_FLATHASH)
|
||||||
add_executable(flathash ${FlatHash_SRCS})
|
add_executable(flathash ${FlatHash_SRCS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(FLATBUFFERS_BUILD_SHAREDLIB)
|
||||||
|
add_library(flatbuffers_shared SHARED ${FlatBuffers_Library_SRCS})
|
||||||
|
|
||||||
|
# Shared object version: "major.minor.micro"
|
||||||
|
# - micro updated every release when there is no API/ABI changes
|
||||||
|
# - minor updated when there are additions in API/ABI
|
||||||
|
# - major (ABI number) updated when there are changes in ABI (or removals)
|
||||||
|
set(FlatBuffers_Library_SONAME_MAJOR "1")
|
||||||
|
set(FlatBuffers_Library_SONAME_FULL "${FlatBuffers_Library_SONAME_MAJOR}.8.0")
|
||||||
|
set_target_properties(flatbuffers_shared PROPERTIES OUTPUT_NAME flatbuffers
|
||||||
|
SOVERSION "${FlatBuffers_Library_SONAME_MAJOR}"
|
||||||
|
VERSION "${FlatBuffers_Library_SONAME_FULL}")
|
||||||
|
endif()
|
||||||
|
|
||||||
function(compile_flatbuffers_schema_to_cpp SRC_FBS)
|
function(compile_flatbuffers_schema_to_cpp SRC_FBS)
|
||||||
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
|
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
|
||||||
string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS})
|
string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS})
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${GEN_HEADER}
|
OUTPUT ${GEN_HEADER}
|
||||||
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --no-includes --gen-mutable -o "${SRC_FBS_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --no-includes --gen-mutable
|
||||||
|
--gen-object-api -o "${SRC_FBS_DIR}"
|
||||||
|
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
|
||||||
|
--reflect-names
|
||||||
|
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
||||||
DEPENDS flatc)
|
DEPENDS flatc)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
@@ -128,7 +220,8 @@ function(compile_flatbuffers_schema_to_binary SRC_FBS)
|
|||||||
string(REGEX REPLACE "\\.fbs$" ".bfbs" GEN_BINARY_SCHEMA ${SRC_FBS})
|
string(REGEX REPLACE "\\.fbs$" ".bfbs" GEN_BINARY_SCHEMA ${SRC_FBS})
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${GEN_BINARY_SCHEMA}
|
OUTPUT ${GEN_BINARY_SCHEMA}
|
||||||
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -b --schema -o "${SRC_FBS_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -b --schema -o "${SRC_FBS_DIR}"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
||||||
DEPENDS flatc)
|
DEPENDS flatc)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
@@ -136,6 +229,9 @@ if(FLATBUFFERS_BUILD_TESTS)
|
|||||||
compile_flatbuffers_schema_to_cpp(tests/monster_test.fbs)
|
compile_flatbuffers_schema_to_cpp(tests/monster_test.fbs)
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/tests)
|
include_directories(${CMAKE_CURRENT_BINARY_DIR}/tests)
|
||||||
add_executable(flattests ${FlatBuffers_Tests_SRCS})
|
add_executable(flattests ${FlatBuffers_Tests_SRCS})
|
||||||
|
set_property(TARGET flattests
|
||||||
|
PROPERTY COMPILE_DEFINITIONS FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||||
|
FLATBUFFERS_DEBUG_VERIFICATION_FAILURE=1)
|
||||||
|
|
||||||
compile_flatbuffers_schema_to_cpp(samples/monster.fbs)
|
compile_flatbuffers_schema_to_cpp(samples/monster.fbs)
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/samples)
|
include_directories(${CMAKE_CURRENT_BINARY_DIR}/samples)
|
||||||
@@ -143,13 +239,69 @@ if(FLATBUFFERS_BUILD_TESTS)
|
|||||||
add_executable(flatsampletext ${FlatBuffers_Sample_Text_SRCS})
|
add_executable(flatsampletext ${FlatBuffers_Sample_Text_SRCS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FLATBUFFERS_INSTALL)
|
if(FLATBUFFERS_BUILD_GRPCTEST)
|
||||||
install(DIRECTORY include/flatbuffers DESTINATION include)
|
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
if(FLATBUFFERS_BUILD_FLATLIB)
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter -Wno-shadow")
|
||||||
install(TARGETS flatbuffers DESTINATION lib)
|
|
||||||
endif()
|
endif()
|
||||||
|
add_executable(grpctest ${FlatBuffers_GRPCTest_SRCS})
|
||||||
|
target_link_libraries(grpctest grpc++_unsecure grpc_unsecure pthread dl)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(FLATBUFFERS_INSTALL)
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
install(DIRECTORY include/flatbuffers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
|
||||||
|
set(FB_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/flatbuffers")
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES "CMake/FlatbuffersConfig.cmake"
|
||||||
|
DESTINATION ${FB_CMAKE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(FLATBUFFERS_BUILD_FLATLIB)
|
||||||
|
install(
|
||||||
|
TARGETS flatbuffers EXPORT FlatbuffersTargets
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(EXPORT FlatbuffersTargets
|
||||||
|
FILE FlatbuffersTargets.cmake
|
||||||
|
NAMESPACE flatbuffers::
|
||||||
|
DESTINATION ${FB_CMAKE_DIR}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(FLATBUFFERS_BUILD_FLATC)
|
if(FLATBUFFERS_BUILD_FLATC)
|
||||||
install(TARGETS flatc DESTINATION bin)
|
install(
|
||||||
|
TARGETS flatc EXPORT FlatcTargets
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
CONFIGURATIONS Release
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
EXPORT FlatcTargets
|
||||||
|
FILE FlatcTargets.cmake
|
||||||
|
NAMESPACE flatbuffers::
|
||||||
|
DESTINATION ${FB_CMAKE_DIR}
|
||||||
|
CONFIGURATIONS Release
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(FLATBUFFERS_BUILD_SHAREDLIB)
|
||||||
|
install(
|
||||||
|
TARGETS flatbuffers_shared EXPORT FlatbuffersSharedTargets
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
EXPORT FlatbuffersSharedTargets
|
||||||
|
FILE FlatbuffersSharedTargets.cmake
|
||||||
|
NAMESPACE flatbuffers::
|
||||||
|
DESTINATION ${FB_CMAKE_DIR}
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -162,3 +314,7 @@ if(FLATBUFFERS_BUILD_TESTS)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(CMake/BuildFlatBuffers.cmake)
|
include(CMake/BuildFlatBuffers.cmake)
|
||||||
|
|
||||||
|
if(FLATBUFFERS_PACKAGE_DEBIAN)
|
||||||
|
include(CMake/PackageDebian.cmake)
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ use Github pull requests for this purpose.
|
|||||||
|
|
||||||
Some tips for good pull requests:
|
Some tips for good pull requests:
|
||||||
* Use our code
|
* Use our code
|
||||||
[style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.html).
|
[style guide](https://google.github.io/styleguide/cppguide.html).
|
||||||
When in doubt, try to stay true to the existing code of the project.
|
When in doubt, try to stay true to the existing code of the project.
|
||||||
* Write a descriptive commit message. What problem are you solving and what
|
* Write a descriptive commit message. What problem are you solving and what
|
||||||
are the consequences? Where and what did you test? Some good tips:
|
are the consequences? Where and what did you test? Some good tips:
|
||||||
0
android/.project
Executable file → Normal file
0
android/.project
Executable file → Normal file
11
android/AndroidManifest.xml
Executable file → Normal file
11
android/AndroidManifest.xml
Executable file → Normal file
@@ -17,17 +17,14 @@
|
|||||||
-->
|
-->
|
||||||
<!-- BEGIN_INCLUDE(manifest) -->
|
<!-- BEGIN_INCLUDE(manifest) -->
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.FlatBufferTest"
|
package="com.example.FlatBufferTest">
|
||||||
android:versionCode="1"
|
|
||||||
android:versionName="1.0">
|
|
||||||
|
|
||||||
<uses-feature android:glEsVersion="0x00020000"></uses-feature>
|
<uses-feature android:glEsVersion="0x00020000"></uses-feature>
|
||||||
<!-- This is the platform API where NativeActivity was introduced. -->
|
|
||||||
<uses-sdk android:minSdkVersion="9" />
|
|
||||||
|
|
||||||
<!-- This .apk has no Java code itself, so set hasCode to false. -->
|
<!-- This .apk has no Java code itself, so set hasCode to false. -->
|
||||||
<application android:label="@string/app_name" android:hasCode="false">
|
<application android:label="@string/app_name"
|
||||||
|
android:hasCode="false"
|
||||||
|
android:allowBackup="false">
|
||||||
<!-- Our activity is the built-in NativeActivity framework class.
|
<!-- Our activity is the built-in NativeActivity framework class.
|
||||||
This will take care of integrating with our NDK code. -->
|
This will take care of integrating with our NDK code. -->
|
||||||
<activity android:name="android.app.NativeActivity"
|
<activity android:name="android.app.NativeActivity"
|
||||||
|
|||||||
108
android/build.gradle
Normal file
108
android/build.gradle
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
// Copyright (c) 2017 Google, Inc.
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would be
|
||||||
|
// appreciated but is not required.
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
// misrepresented as being the original software.
|
||||||
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:2.3.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 25
|
||||||
|
buildToolsVersion '25.0.2'
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
manifest.srcFile 'AndroidManifest.xml'
|
||||||
|
res.srcDirs = ['res']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
path "jni/Android.mk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId 'com.example.FlatBufferTest'
|
||||||
|
// This is the platform API where NativeActivity was introduced.
|
||||||
|
minSdkVersion 9
|
||||||
|
targetSdkVersion 25
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
targets "FlatBufferTest"
|
||||||
|
arguments "-j" + Runtime.getRuntime().availableProcessors()
|
||||||
|
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lintOptions {
|
||||||
|
abortOnError false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build with each STL variant.
|
||||||
|
productFlavors {
|
||||||
|
stlport {
|
||||||
|
applicationIdSuffix ".stlport"
|
||||||
|
versionNameSuffix "-stlport"
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
arguments "APP_STL=stlport_static"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gnustl {
|
||||||
|
applicationIdSuffix ".gnustl"
|
||||||
|
versionNameSuffix "-gnustl"
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
arguments "APP_STL=gnustl_static"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
libcpp {
|
||||||
|
applicationIdSuffix ".libcpp"
|
||||||
|
versionNameSuffix "-libcpp"
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
arguments "APP_STL=c++_static"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,510 +0,0 @@
|
|||||||
#!/bin/bash -eu
|
|
||||||
# Copyright (c) 2013 Google, Inc.
|
|
||||||
#
|
|
||||||
# This software is provided 'as-is', without any express or implied
|
|
||||||
# warranty. In no event will the authors be held liable for any damages
|
|
||||||
# arising from the use of this software.
|
|
||||||
# Permission is granted to anyone to use this software for any purpose,
|
|
||||||
# including commercial applications, and to alter it and redistribute it
|
|
||||||
# freely, subject to the following restrictions:
|
|
||||||
# 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
# claim that you wrote the original software. If you use this software
|
|
||||||
# in a product, an acknowledgment in the product documentation would be
|
|
||||||
# appreciated but is not required.
|
|
||||||
# 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
# misrepresented as being the original software.
|
|
||||||
# 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
#
|
|
||||||
# Build, deploy, debug / execute a native Android package based upon
|
|
||||||
# NativeActivity.
|
|
||||||
|
|
||||||
declare -r script_directory=$(dirname $0)
|
|
||||||
declare -r android_root=${script_directory}/../../../../../../
|
|
||||||
declare -r script_name=$(basename $0)
|
|
||||||
declare -r android_manifest=AndroidManifest.xml
|
|
||||||
declare -r os_name=$(uname -s)
|
|
||||||
|
|
||||||
# Minimum Android target version supported by this project.
|
|
||||||
: ${BUILDAPK_ANDROID_TARGET_MINVERSION:=10}
|
|
||||||
# Directory containing the Android SDK
|
|
||||||
# (http://developer.android.com/sdk/index.html).
|
|
||||||
: ${ANDROID_SDK_HOME:=}
|
|
||||||
# Directory containing the Android NDK
|
|
||||||
# (http://developer.android.com/tools/sdk/ndk/index.html).
|
|
||||||
: ${NDK_HOME:=}
|
|
||||||
|
|
||||||
# Display script help and exit.
|
|
||||||
usage() {
|
|
||||||
echo "
|
|
||||||
Build the Android package in the current directory and deploy it to a
|
|
||||||
connected device.
|
|
||||||
|
|
||||||
Usage: ${script_name} \\
|
|
||||||
[ADB_DEVICE=serial_number] [BUILD=0] [DEPLOY=0] [RUN_DEBUGGER=1] \
|
|
||||||
[LAUNCH=0] [SWIG_BIN=swig_binary_directory] [SWIG_LIB=swig_include_directory] [ndk-build arguments ...]
|
|
||||||
|
|
||||||
ADB_DEVICE=serial_number:
|
|
||||||
serial_number specifies the device to deploy the built apk to if multiple
|
|
||||||
Android devices are connected to the host.
|
|
||||||
BUILD=0:
|
|
||||||
Disables the build of the package.
|
|
||||||
DEPLOY=0:
|
|
||||||
Disables the deployment of the built apk to the Android device.
|
|
||||||
RUN_DEBUGGER=1:
|
|
||||||
Launches the application in gdb after it has been deployed. To debug in
|
|
||||||
gdb, NDK_DEBUG=1 must also be specified on the command line to build a
|
|
||||||
debug apk.
|
|
||||||
LAUNCH=0:
|
|
||||||
Disable the launch of the apk on the Android device.
|
|
||||||
SWIG_BIN=swig_binary_directory:
|
|
||||||
The directory where the SWIG binary lives. No need to set this if SWIG is
|
|
||||||
installed and point to from your PATH variable.
|
|
||||||
SWIG_LIB=swig_include_directory:
|
|
||||||
The directory where SWIG shared include files are, usually obtainable from
|
|
||||||
commandline with \"swig -swiglib\". No need to set this if SWIG is installed
|
|
||||||
and point to from your PATH variable.
|
|
||||||
ndk-build arguments...:
|
|
||||||
Additional arguments for ndk-build. See ndk-build -h for more information.
|
|
||||||
" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the number of CPU cores present on the host.
|
|
||||||
get_number_of_cores() {
|
|
||||||
case ${os_name} in
|
|
||||||
Darwin)
|
|
||||||
sysctl hw.ncpu | awk '{ print $2 }'
|
|
||||||
;;
|
|
||||||
CYGWIN*|Linux)
|
|
||||||
awk '/^processor/ { n=$3 } END { print n + 1 }' /proc/cpuinfo
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the package name from an AndroidManifest.xml file.
|
|
||||||
get_package_name_from_manifest() {
|
|
||||||
xmllint --xpath 'string(/manifest/@package)' "${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the library name from an AndroidManifest.xml file.
|
|
||||||
get_library_name_from_manifest() {
|
|
||||||
echo "\
|
|
||||||
setns android=http://schemas.android.com/apk/res/android
|
|
||||||
xpath string(/manifest/application/activity\
|
|
||||||
[@android:name=\"android.app.NativeActivity\"]/meta-data\
|
|
||||||
[@android:name=\"android.app.lib_name\"]/@android:value)" |
|
|
||||||
xmllint --shell "${1}" | awk '/Object is a string/ { print $NF }'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the number of Android devices connected to the system.
|
|
||||||
get_number_of_devices_connected() {
|
|
||||||
adb devices -l | \
|
|
||||||
awk '/^..*$/ { if (p) { print $0 } }
|
|
||||||
/List of devices attached/ { p = 1 }' | \
|
|
||||||
wc -l
|
|
||||||
return ${PIPESTATUS[0]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Kill a process and its' children. This is provided for cygwin which
|
|
||||||
# doesn't ship with pkill.
|
|
||||||
kill_process_group() {
|
|
||||||
local parent_pid="${1}"
|
|
||||||
local child_pid=
|
|
||||||
for child_pid in $(ps -f | \
|
|
||||||
awk '{ if ($3 == '"${parent_pid}"') { print $2 } }'); do
|
|
||||||
kill_process_group "${child_pid}"
|
|
||||||
done
|
|
||||||
kill "${parent_pid}" 2>/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Find and run "adb".
|
|
||||||
adb() {
|
|
||||||
local adb_path=
|
|
||||||
for path in "$(which adb 2>/dev/null)" \
|
|
||||||
"${ANDROID_SDK_HOME}/sdk/platform-tools/adb" \
|
|
||||||
"${android_root}/prebuilts/sdk/platform-tools/adb"; do
|
|
||||||
if [[ -e "${path}" ]]; then
|
|
||||||
adb_path="${path}"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [[ "${adb_path}" == "" ]]; then
|
|
||||||
echo -e "Unable to find adb." \
|
|
||||||
"\nAdd the Android ADT sdk/platform-tools directory to the" \
|
|
||||||
"PATH." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
"${adb_path}" "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Find and run "android".
|
|
||||||
android() {
|
|
||||||
local android_executable=android
|
|
||||||
if echo "${os_name}" | grep -q CYGWIN; then
|
|
||||||
android_executable=android.bat
|
|
||||||
fi
|
|
||||||
local android_path=
|
|
||||||
for path in "$(which ${android_executable})" \
|
|
||||||
"${ANDROID_SDK_HOME}/sdk/tools/${android_executable}" \
|
|
||||||
"${android_root}/prebuilts/sdk/tools/${android_executable}"; do
|
|
||||||
if [[ -e "${path}" ]]; then
|
|
||||||
android_path="${path}"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [[ "${android_path}" == "" ]]; then
|
|
||||||
echo -e "Unable to find android tool." \
|
|
||||||
"\nAdd the Android ADT sdk/tools directory to the PATH." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Make sure ant is installed.
|
|
||||||
if [[ "$(which ant)" == "" ]]; then
|
|
||||||
echo -e "Unable to find ant." \
|
|
||||||
"\nPlease install ant and add to the PATH." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
"${android_path}" "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Find and run "ndk-build"
|
|
||||||
ndkbuild() {
|
|
||||||
local ndkbuild_path=
|
|
||||||
for path in "$(which ndk-build 2>/dev/null)" \
|
|
||||||
"${NDK_HOME}/ndk-build" \
|
|
||||||
"${android_root}/prebuilts/ndk/current/ndk-build"; do
|
|
||||||
if [[ -e "${path}" ]]; then
|
|
||||||
ndkbuild_path="${path}"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [[ "${ndkbuild_path}" == "" ]]; then
|
|
||||||
echo -e "Unable to find ndk-build." \
|
|
||||||
"\nAdd the Android NDK directory to the PATH." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
"${ndkbuild_path}" "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get file modification time of $1 in seconds since the epoch.
|
|
||||||
stat_mtime() {
|
|
||||||
local filename="${1}"
|
|
||||||
case ${os_name} in
|
|
||||||
Darwin) stat -f%m "${filename}" 2>/dev/null || echo 0 ;;
|
|
||||||
*) stat -c%Y "${filename}" 2>/dev/null || echo 0 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Build the native (C/C++) build targets in the current directory.
|
|
||||||
build_native_targets() {
|
|
||||||
# Save the list of output modules in the install directory so that it's
|
|
||||||
# possible to restore their timestamps after the build is complete. This
|
|
||||||
# works around a bug in ndk/build/core/setup-app.mk which results in the
|
|
||||||
# unconditional execution of the clean-installed-binaries rule.
|
|
||||||
restore_libraries="$(find libs -type f 2>/dev/null | \
|
|
||||||
sed -E 's@^libs/(.*)@\1@')"
|
|
||||||
|
|
||||||
# Build native code.
|
|
||||||
ndkbuild -j$(get_number_of_cores) "$@"
|
|
||||||
|
|
||||||
# Restore installed libraries.
|
|
||||||
# Obviously this is a nasty hack (along with ${restore_libraries} above) as
|
|
||||||
# it assumes it knows where the NDK will be placing output files.
|
|
||||||
(
|
|
||||||
IFS=$'\n'
|
|
||||||
for libpath in ${restore_libraries}; do
|
|
||||||
source_library="obj/local/${libpath}"
|
|
||||||
target_library="libs/${libpath}"
|
|
||||||
if [[ -e "${source_library}" ]]; then
|
|
||||||
cp -a "${source_library}" "${target_library}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Select the oldest installed android build target that is at least as new as
|
|
||||||
# BUILDAPK_ANDROID_TARGET_MINVERSION. If a suitable build target isn't found,
|
|
||||||
# this function prints an error message and exits with an error.
|
|
||||||
select_android_build_target() {
|
|
||||||
local -r android_targets_installed=$( \
|
|
||||||
android list targets | \
|
|
||||||
awk -F'"' '/^id:.*android/ { print $2 }')
|
|
||||||
local android_build_target=
|
|
||||||
for android_target in $(echo "${android_targets_installed}" | \
|
|
||||||
awk -F- '{ print $2 }' | sort -n); do
|
|
||||||
local isNumber='^[0-9]+$'
|
|
||||||
# skip preview API releases e.g. 'android-L'
|
|
||||||
if [[ $android_target =~ $isNumber ]]; then
|
|
||||||
if [[ $((android_target)) -ge \
|
|
||||||
$((BUILDAPK_ANDROID_TARGET_MINVERSION)) ]]; then
|
|
||||||
android_build_target="android-${android_target}"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
# else
|
|
||||||
# The API version is a letter, so skip it.
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [[ "${android_build_target}" == "" ]]; then
|
|
||||||
echo -e \
|
|
||||||
"Found installed Android targets:" \
|
|
||||||
"$(echo ${android_targets_installed} | sed 's/ /\n /g;s/^/\n /;')" \
|
|
||||||
"\nAndroid SDK platform" \
|
|
||||||
"android-$((BUILDAPK_ANDROID_TARGET_MINVERSION))" \
|
|
||||||
"must be installed to build this project." \
|
|
||||||
"\nUse the \"android\" application to install API" \
|
|
||||||
"$((BUILDAPK_ANDROID_TARGET_MINVERSION)) or newer." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "${android_build_target}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sign unsigned apk $1 and write the result to $2 with key store file $3 and
|
|
||||||
# password $4.
|
|
||||||
# If a key store file $3 and password $4 aren't specified, a temporary
|
|
||||||
# (60 day) key is generated and used to sign the package.
|
|
||||||
sign_apk() {
|
|
||||||
local unsigned_apk="${1}"
|
|
||||||
local signed_apk="${2}"
|
|
||||||
if [[ $(stat_mtime "${unsigned_apk}") -gt \
|
|
||||||
$(stat_mtime "${signed_apk}") ]]; then
|
|
||||||
local -r key_alias=$(basename ${signed_apk} .apk)
|
|
||||||
local keystore="${3}"
|
|
||||||
local key_password="${4}"
|
|
||||||
[[ "${keystore}" == "" ]] && keystore="${unsigned_apk}.keystore"
|
|
||||||
[[ "${key_password}" == "" ]] && \
|
|
||||||
key_password="${key_alias}123456"
|
|
||||||
if [[ ! -e ${keystore} ]]; then
|
|
||||||
keytool -genkey -v -dname "cn=, ou=${key_alias}, o=fpl" \
|
|
||||||
-storepass ${key_password} \
|
|
||||||
-keypass ${key_password} -keystore ${keystore} \
|
|
||||||
-alias ${key_alias} -keyalg RSA -keysize 2048 -validity 60
|
|
||||||
fi
|
|
||||||
cp "${unsigned_apk}" "${signed_apk}"
|
|
||||||
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 \
|
|
||||||
-keystore ${keystore} -storepass ${key_password} \
|
|
||||||
-keypass ${key_password} "${signed_apk}" ${key_alias}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Build the apk $1 for package filename $2 in the current directory using the
|
|
||||||
# ant build target $3.
|
|
||||||
build_apk() {
|
|
||||||
local -r output_apk="${1}"
|
|
||||||
local -r package_filename="${2}"
|
|
||||||
local -r ant_target="${3}"
|
|
||||||
# Get the list of installed android targets and select the oldest target
|
|
||||||
# that is at least as new as BUILDAPK_ANDROID_TARGET_MINVERSION.
|
|
||||||
local -r android_build_target=$(select_android_build_target)
|
|
||||||
[[ "${android_build_target}" == "" ]] && exit 1
|
|
||||||
echo "Building ${output_apk} for target ${android_build_target}" >&2
|
|
||||||
|
|
||||||
# Create / update build.xml and local.properties files.
|
|
||||||
if [[ $(stat_mtime "${android_manifest}") -gt \
|
|
||||||
$(stat_mtime build.xml) ]]; then
|
|
||||||
android update project --target "${android_build_target}" \
|
|
||||||
-n ${package_filename} --path .
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Use ant to build the apk.
|
|
||||||
ant -quiet ${ant_target}
|
|
||||||
|
|
||||||
# Sign release apks with a temporary key as these packages will not be
|
|
||||||
# redistributed.
|
|
||||||
local unsigned_apk="bin/${package_filename}-${ant_target}-unsigned.apk"
|
|
||||||
if [[ "${ant_target}" == "release" ]]; then
|
|
||||||
sign_apk "${unsigned_apk}" "${output_apk}" "" ""
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Uninstall package $1 and install apk $2 on device $3 where $3 is "-s device"
|
|
||||||
# or an empty string. If $3 is an empty string adb will fail when multiple
|
|
||||||
# devices are connected to the host system.
|
|
||||||
install_apk() {
|
|
||||||
local -r uninstall_package_name="${1}"
|
|
||||||
local -r install_apk="${2}"
|
|
||||||
local -r adb_device="${3}"
|
|
||||||
# Uninstall the package if it's already installed.
|
|
||||||
adb ${adb_device} uninstall "${uninstall_package_name}" 1>&2 > /dev/null || \
|
|
||||||
true # no error check
|
|
||||||
|
|
||||||
# Install the apk.
|
|
||||||
# NOTE: The following works around adb not returning an error code when
|
|
||||||
# it fails to install an apk.
|
|
||||||
echo "Install ${install_apk}" >&2
|
|
||||||
local -r adb_install_result=$(adb ${adb_device} install "${install_apk}")
|
|
||||||
echo "${adb_install_result}"
|
|
||||||
if echo "${adb_install_result}" | grep -qF 'Failure ['; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Launch previously installed package $1 on device $2.
|
|
||||||
# If $2 is an empty string adb will fail when multiple devices are connected
|
|
||||||
# to the host system.
|
|
||||||
launch_package() {
|
|
||||||
(
|
|
||||||
# Determine the SDK version of Android on the device.
|
|
||||||
local -r android_sdk_version=$(
|
|
||||||
adb ${adb_device} shell cat system/build.prop | \
|
|
||||||
awk -F= '/ro.build.version.sdk/ {
|
|
||||||
v=$2; sub(/[ \r\n]/, "", v); print v
|
|
||||||
}')
|
|
||||||
|
|
||||||
# Clear logs from previous runs.
|
|
||||||
# Note that logcat does not just 'tail' the logs, it dumps the entire log
|
|
||||||
# history.
|
|
||||||
adb ${adb_device} logcat -c
|
|
||||||
|
|
||||||
local finished_msg='Displayed '"${package_name}"
|
|
||||||
local timeout_msg='Activity destroy timeout.*'"${package_name}"
|
|
||||||
# Maximum time to wait before stopping log monitoring. 0 = infinity.
|
|
||||||
local launch_timeout=0
|
|
||||||
# If this is a Gingerbread device, kill log monitoring after 10 seconds.
|
|
||||||
if [[ $((android_sdk_version)) -le 10 ]]; then
|
|
||||||
launch_timeout=10
|
|
||||||
fi
|
|
||||||
# Display logcat in the background.
|
|
||||||
# Stop displaying the log when the app launch / execution completes or the
|
|
||||||
# logcat
|
|
||||||
(
|
|
||||||
adb ${adb_device} logcat | \
|
|
||||||
awk "
|
|
||||||
{
|
|
||||||
print \$0
|
|
||||||
}
|
|
||||||
|
|
||||||
/ActivityManager.*: ${finished_msg}/ {
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/ActivityManager.*: ${timeout_msg}/ {
|
|
||||||
exit 0
|
|
||||||
}" &
|
|
||||||
adb_logcat_pid=$!;
|
|
||||||
if [[ $((launch_timeout)) -gt 0 ]]; then
|
|
||||||
sleep $((launch_timeout));
|
|
||||||
kill ${adb_logcat_pid};
|
|
||||||
else
|
|
||||||
wait ${adb_logcat_pid};
|
|
||||||
fi
|
|
||||||
) &
|
|
||||||
logcat_pid=$!
|
|
||||||
# Kill adb logcat if this shell exits.
|
|
||||||
trap "kill_process_group ${logcat_pid}" SIGINT SIGTERM EXIT
|
|
||||||
|
|
||||||
# If the SDK is newer than 10, "am" supports stopping an activity.
|
|
||||||
adb_stop_activity=
|
|
||||||
if [[ $((android_sdk_version)) -gt 10 ]]; then
|
|
||||||
adb_stop_activity=-S
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Launch the activity and wait for it to complete.
|
|
||||||
adb ${adb_device} shell am start ${adb_stop_activity} -n \
|
|
||||||
${package_name}/android.app.NativeActivity
|
|
||||||
|
|
||||||
wait "${logcat_pid}"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
# See usage().
|
|
||||||
main() {
|
|
||||||
# Parse arguments for this script.
|
|
||||||
local adb_device=
|
|
||||||
local ant_target=release
|
|
||||||
local disable_deploy=0
|
|
||||||
local disable_build=0
|
|
||||||
local run_debugger=0
|
|
||||||
local launch=1
|
|
||||||
local build_package=1
|
|
||||||
for opt; do
|
|
||||||
case ${opt} in
|
|
||||||
# NDK_DEBUG=0 tells ndk-build to build this as debuggable but to not
|
|
||||||
# modify the underlying code whereas NDK_DEBUG=1 also builds as debuggable
|
|
||||||
# but does modify the code
|
|
||||||
NDK_DEBUG=1) ant_target=debug ;;
|
|
||||||
NDK_DEBUG=0) ant_target=debug ;;
|
|
||||||
ADB_DEVICE*) adb_device="$(\
|
|
||||||
echo "${opt}" | sed -E 's/^ADB_DEVICE=([^ ]+)$/-s \1/;t;s/.*//')" ;;
|
|
||||||
BUILD=0) disable_build=1 ;;
|
|
||||||
DEPLOY=0) disable_deploy=1 ;;
|
|
||||||
RUN_DEBUGGER=1) run_debugger=1 ;;
|
|
||||||
LAUNCH=0) launch=0 ;;
|
|
||||||
clean) build_package=0 disable_deploy=1 launch=0 ;;
|
|
||||||
-h|--help|help) usage ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# If a target device hasn't been specified and multiple devices are connected
|
|
||||||
# to the host machine, display an error.
|
|
||||||
local -r devices_connected=$(get_number_of_devices_connected)
|
|
||||||
if [[ "${adb_device}" == "" && $((devices_connected)) -gt 1 && \
|
|
||||||
($((disable_deploy)) -eq 0 || $((launch)) -ne 0 || \
|
|
||||||
$((run_debugger)) -ne 0) ]]; then
|
|
||||||
if [[ $((disable_deploy)) -ne 0 ]]; then
|
|
||||||
echo "Deployment enabled, disable using DEPLOY=0" >&2
|
|
||||||
fi
|
|
||||||
if [[ $((launch)) -ne 0 ]]; then
|
|
||||||
echo "Launch enabled." >&2
|
|
||||||
fi
|
|
||||||
if [[ $((disable_deploy)) -eq 0 ]]; then
|
|
||||||
echo "Deployment enabled." >&2
|
|
||||||
fi
|
|
||||||
if [[ $((run_debugger)) -ne 0 ]]; then
|
|
||||||
echo "Debugger launch enabled." >&2
|
|
||||||
fi
|
|
||||||
echo "
|
|
||||||
Multiple Android devices are connected to this host. Either disable deployment
|
|
||||||
and execution of the built .apk using:
|
|
||||||
\"${script_name} DEPLOY=0 LAUNCH=0\"
|
|
||||||
|
|
||||||
or specify a device to deploy to using:
|
|
||||||
\"${script_name} ADB_DEVICE=\${device_serial}\".
|
|
||||||
|
|
||||||
The Android devices connected to this machine are:
|
|
||||||
$(adb devices -l)
|
|
||||||
" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $((disable_build)) -eq 0 ]]; then
|
|
||||||
# Build the native target.
|
|
||||||
build_native_targets "$@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the package name from the manifest.
|
|
||||||
local -r package_name=$(get_package_name_from_manifest "${android_manifest}")
|
|
||||||
if [[ "${package_name}" == "" ]]; then
|
|
||||||
echo -e "No package name specified in ${android_manifest},"\
|
|
||||||
"skipping apk build, deploy"
|
|
||||||
"\nand launch steps." >&2
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
local -r package_basename=${package_name/*./}
|
|
||||||
local package_filename=$(get_library_name_from_manifest ${android_manifest})
|
|
||||||
[[ "${package_filename}" == "" ]] && package_filename="${package_basename}"
|
|
||||||
|
|
||||||
# Output apk name.
|
|
||||||
local -r output_apk="bin/${package_filename}-${ant_target}.apk"
|
|
||||||
|
|
||||||
if [[ $((disable_build)) -eq 0 && $((build_package)) -eq 1 ]]; then
|
|
||||||
# Build the apk.
|
|
||||||
build_apk "${output_apk}" "${package_filename}" "${ant_target}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Deploy to the device.
|
|
||||||
if [[ $((disable_deploy)) -eq 0 ]]; then
|
|
||||||
install_apk "${package_name}" "${output_apk}" "${adb_device}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${ant_target}" == "debug" && $((run_debugger)) -eq 1 ]]; then
|
|
||||||
# Start debugging.
|
|
||||||
ndk-gdb ${adb_device} --start
|
|
||||||
elif [[ $((launch)) -eq 1 ]]; then
|
|
||||||
launch_package "${package_name}" "${adb_device}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#Mon Jun 19 11:54:59 PDT 2017
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-all.zip
|
||||||
172
android/gradlew
vendored
Executable file
172
android/gradlew
vendored
Executable file
@@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=$(save "$@")
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||||
|
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
||||||
84
android/gradlew.bat
vendored
Normal file
84
android/gradlew.bat
vendored
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
||||||
11
android/jni/Android.mk
Executable file → Normal file
11
android/jni/Android.mk
Executable file → Normal file
@@ -24,7 +24,9 @@ LOCAL_PATH := $(call realpath-portable,$(LOCAL_PATH))
|
|||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := flatbuffers
|
LOCAL_MODULE := flatbuffers
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
|
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
|
||||||
LOCAL_EXPORT_CPPFLAGS := -std=c++11 -fexceptions -Wall -Wno-literal-suffix
|
LOCAL_EXPORT_CPPFLAGS := -std=c++11 -fexceptions -Wall \
|
||||||
|
-DFLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||||
|
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
# static library that additionally includes text parsing/generation/reflection
|
# static library that additionally includes text parsing/generation/reflection
|
||||||
@@ -33,8 +35,11 @@ include $(CLEAR_VARS)
|
|||||||
LOCAL_MODULE := flatbuffers_extra
|
LOCAL_MODULE := flatbuffers_extra
|
||||||
LOCAL_SRC_FILES := src/idl_parser.cpp \
|
LOCAL_SRC_FILES := src/idl_parser.cpp \
|
||||||
src/idl_gen_text.cpp \
|
src/idl_gen_text.cpp \
|
||||||
src/reflection.cpp
|
src/reflection.cpp \
|
||||||
|
src/util.cpp \
|
||||||
|
src/code_generators.cpp
|
||||||
LOCAL_STATIC_LIBRARIES := flatbuffers
|
LOCAL_STATIC_LIBRARIES := flatbuffers
|
||||||
|
LOCAL_ARM_MODE := arm
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
# FlatBuffers test
|
# FlatBuffers test
|
||||||
@@ -44,7 +49,7 @@ LOCAL_SRC_FILES := android/jni/main.cpp \
|
|||||||
tests/test.cpp \
|
tests/test.cpp \
|
||||||
src/idl_gen_fbs.cpp \
|
src/idl_gen_fbs.cpp \
|
||||||
src/idl_gen_general.cpp
|
src/idl_gen_general.cpp
|
||||||
LOCAL_LDLIBS := -llog -landroid
|
LOCAL_LDLIBS := -llog -landroid -latomic
|
||||||
LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers_extra
|
LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers_extra
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|||||||
6
android/jni/Application.mk
Executable file → Normal file
6
android/jni/Application.mk
Executable file → Normal file
@@ -13,10 +13,8 @@
|
|||||||
# 2. Altered source versions must be plainly marked as such, and must not be
|
# 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
# misrepresented as being the original software.
|
# misrepresented as being the original software.
|
||||||
# 3. This notice may not be removed or altered from any source distribution.
|
# 3. This notice may not be removed or altered from any source distribution.
|
||||||
APP_PLATFORM := android-10
|
APP_PLATFORM := android-9
|
||||||
APP_PROJECT_PATH := $(call my-dir)/..
|
APP_PROJECT_PATH := $(call my-dir)/..
|
||||||
APP_STL := gnustl_static
|
APP_STL ?= stlport_static
|
||||||
|
|
||||||
APP_ABI := armeabi-v7a
|
APP_ABI := armeabi-v7a
|
||||||
NDK_TOOLCHAIN_VERSION := 4.8
|
|
||||||
APP_CPPFLAGS += -std=c++11
|
APP_CPPFLAGS += -std=c++11
|
||||||
|
|||||||
0
android/jni/build_flatc.bat
Executable file → Normal file
0
android/jni/build_flatc.bat
Executable file → Normal file
0
android/res/values/strings.xml
Executable file → Normal file
0
android/res/values/strings.xml
Executable file → Normal file
83
appveyor.yml
Normal file
83
appveyor.yml
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
os: Visual Studio 2015
|
||||||
|
|
||||||
|
environment:
|
||||||
|
|
||||||
|
global:
|
||||||
|
# Workaround for https://github.com/conda/conda-build/issues/636
|
||||||
|
PYTHONIOENCODING: UTF-8
|
||||||
|
CONDA_INSTALL_LOCN: "C:\\Miniconda35-x64"
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
- CMAKE_VS_VERSION: "10 2010"
|
||||||
|
- CMAKE_VS_VERSION: "14 2015"
|
||||||
|
|
||||||
|
platform:
|
||||||
|
- x86
|
||||||
|
- x64
|
||||||
|
|
||||||
|
configuration:
|
||||||
|
- Debug
|
||||||
|
- Release
|
||||||
|
|
||||||
|
before_build:
|
||||||
|
- cmake -G"Visual Studio %CMAKE_VS_VERSION%"
|
||||||
|
# This cuts down on a lot of noise generated by xamarin warnings.
|
||||||
|
- del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
|
||||||
|
|
||||||
|
build:
|
||||||
|
project: ALL_BUILD.vcxproj
|
||||||
|
verbosity: minimal
|
||||||
|
|
||||||
|
install:
|
||||||
|
- set PATH=%CONDA_INSTALL_LOCN%;%CONDA_INSTALL_LOCN%\scripts;%PATH%;
|
||||||
|
|
||||||
|
test_script:
|
||||||
|
- "cd tests"
|
||||||
|
- rem "Building all code"
|
||||||
|
- generate_code.bat -b %CONFIGURATION%
|
||||||
|
- 7z a GeneratedMyGameCode.zip MyGame\
|
||||||
|
- rem "---------------- C++ -----------------"
|
||||||
|
- "cd .."
|
||||||
|
- "%CONFIGURATION%\\flattests.exe"
|
||||||
|
- "cd tests"
|
||||||
|
- rem "---------------- Java -----------------"
|
||||||
|
- "java -version"
|
||||||
|
- "JavaTest.bat"
|
||||||
|
- rem "---------------- JS -----------------"
|
||||||
|
- "node --version"
|
||||||
|
- "..\\%CONFIGURATION%\\flatc -b -I include_test monster_test.fbs unicode_test.json"
|
||||||
|
- "node JavaScriptTest ./monster_test_generated"
|
||||||
|
- rem "-------------- Python ---------------"
|
||||||
|
- where python
|
||||||
|
- python --version
|
||||||
|
- where pip
|
||||||
|
- pip --version
|
||||||
|
- where conda
|
||||||
|
- conda --version
|
||||||
|
- rem "installing flatbuffers python library"
|
||||||
|
- pip install ../python
|
||||||
|
- rem "testing without installing Numpy"
|
||||||
|
- python py_test.py 0 0 0
|
||||||
|
- rem "testing after installing Numpy - disabled"
|
||||||
|
# FIXME: This has a LOT of unnecessary dependencies and makes the tests fail
|
||||||
|
# with timeouts.
|
||||||
|
# - conda install --yes numpy
|
||||||
|
# - python py_test.py 0 0 0
|
||||||
|
- rem "---------------- C# -----------------"
|
||||||
|
# Have to compile this here rather than in "build" above because AppVeyor only
|
||||||
|
# supports building one project??
|
||||||
|
- "cd FlatBuffers.Test"
|
||||||
|
- "msbuild.exe /property:Configuration=Release;OutputPath=tempcs /verbosity:minimal FlatBuffers.Test.csproj"
|
||||||
|
- "tempcs\\FlatBuffers.Test.exe"
|
||||||
|
# TODO: add more languages.
|
||||||
|
- "cd ..\\.."
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
- path: $(CONFIGURATION)\flatc.exe
|
||||||
|
name: flatc.exe
|
||||||
|
- path: tests\GeneratedMyGameCode.zip
|
||||||
|
name: GeneratedMyGameCode.zip
|
||||||
@@ -1,4 +1,18 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Copyright 2016 Google Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
sudo apt-get update -qq
|
sudo apt-get update -qq
|
||||||
sudo apt-get install libglu1-mesa-dev xorg-dev
|
sudo apt-get install libglu1-mesa-dev xorg-dev
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
|
||||||
# Visual Studio 2010
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flatc", "flatc.vcxproj", "{5B5857E1-64E2-4CED-A12E-45E1B3880496}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flatsamplebinary", "flatsamplebinary.vcxproj", "{16FA5518-3DE1-4B15-A1E0-F4734C276FB4}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flatsampletext", "flatsampletext.vcxproj", "{F0A15675-1017-4217-BB5B-3372F2C636AB}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flattests", "flattests.vcxproj", "{DC7BBA00-9FC6-48AF-B7E9-12CA91AC02AA}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Win32 = Debug|Win32
|
|
||||||
Debug|x64 = Debug|x64
|
|
||||||
Release|Win32 = Release|Win32
|
|
||||||
Release|x64 = Release|x64
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{5B5857E1-64E2-4CED-A12E-45E1B3880496}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{5B5857E1-64E2-4CED-A12E-45E1B3880496}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{5B5857E1-64E2-4CED-A12E-45E1B3880496}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{5B5857E1-64E2-4CED-A12E-45E1B3880496}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{5B5857E1-64E2-4CED-A12E-45E1B3880496}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{5B5857E1-64E2-4CED-A12E-45E1B3880496}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{5B5857E1-64E2-4CED-A12E-45E1B3880496}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{5B5857E1-64E2-4CED-A12E-45E1B3880496}.Release|x64.Build.0 = Release|x64
|
|
||||||
{16FA5518-3DE1-4B15-A1E0-F4734C276FB4}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{16FA5518-3DE1-4B15-A1E0-F4734C276FB4}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{16FA5518-3DE1-4B15-A1E0-F4734C276FB4}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{16FA5518-3DE1-4B15-A1E0-F4734C276FB4}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{16FA5518-3DE1-4B15-A1E0-F4734C276FB4}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{16FA5518-3DE1-4B15-A1E0-F4734C276FB4}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{16FA5518-3DE1-4B15-A1E0-F4734C276FB4}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{16FA5518-3DE1-4B15-A1E0-F4734C276FB4}.Release|x64.Build.0 = Release|x64
|
|
||||||
{F0A15675-1017-4217-BB5B-3372F2C636AB}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{F0A15675-1017-4217-BB5B-3372F2C636AB}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{F0A15675-1017-4217-BB5B-3372F2C636AB}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{F0A15675-1017-4217-BB5B-3372F2C636AB}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{F0A15675-1017-4217-BB5B-3372F2C636AB}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{F0A15675-1017-4217-BB5B-3372F2C636AB}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{F0A15675-1017-4217-BB5B-3372F2C636AB}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{F0A15675-1017-4217-BB5B-3372F2C636AB}.Release|x64.Build.0 = Release|x64
|
|
||||||
{DC7BBA00-9FC6-48AF-B7E9-12CA91AC02AA}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{DC7BBA00-9FC6-48AF-B7E9-12CA91AC02AA}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{DC7BBA00-9FC6-48AF-B7E9-12CA91AC02AA}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{DC7BBA00-9FC6-48AF-B7E9-12CA91AC02AA}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{DC7BBA00-9FC6-48AF-B7E9-12CA91AC02AA}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{DC7BBA00-9FC6-48AF-B7E9-12CA91AC02AA}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{DC7BBA00-9FC6-48AF-B7E9-12CA91AC02AA}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{DC7BBA00-9FC6-48AF-B7E9-12CA91AC02AA}.Release|x64.Build.0 = Release|x64
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
@@ -1,285 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Debug|x64">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|x64">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGUID>{5B5857E1-64E2-4CED-A12E-45E1B3880496}</ProjectGUID>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
<ProjectName>flatc</ProjectName>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)</OutDir>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)</OutDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">flatc.dir\Debug\</IntDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">flatc.dir\Debug\</IntDir>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">flatc</TargetName>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">flatc</TargetName>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.exe</TargetExt>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.exe</TargetExt>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</GenerateManifest>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</GenerateManifest>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)</OutDir>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)</OutDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">flatc.dir\Release\</IntDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">flatc.dir\Release\</IntDir>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">flatc</TargetName>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">flatc</TargetName>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.exe</TargetExt>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.exe</TargetExt>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</GenerateManifest>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateManifest>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Debug</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Debug/flatc.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalOptions> /machine:X86 /debug %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Debug/flatc.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Debug/flatc.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Debug</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Debug/flatc.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalOptions>/debug %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Debug/flatc.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Debug/flatc.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<DebugInformationFormat>
|
|
||||||
</DebugInformationFormat>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Release</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Release/flatc.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalOptions> /machine:X86 %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Release/flatc.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Release/flatc.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<DebugInformationFormat>
|
|
||||||
</DebugInformationFormat>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Release</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Release/flatc.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Release/flatc.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Release/flatc.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="..\..\include\flatbuffers\flatbuffers.h" />
|
|
||||||
<ClInclude Include="..\..\include\flatbuffers\idl.h" />
|
|
||||||
<ClInclude Include="..\..\include\flatbuffers\util.h" />
|
|
||||||
<ClCompile Include="..\..\src\idl_gen_fbs.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\idl_gen_general.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\idl_gen_go.cpp">
|
|
||||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\src\idl_gen_js.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\idl_gen_php.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\idl_gen_python.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\idl_parser.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\idl_gen_cpp.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\idl_gen_text.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\flatc.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..\tests</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
<LocalDebuggerCommandArguments>-j -c -n -g --php --no-includes --gen-mutable monster_test.fbs</LocalDebuggerCommandArguments>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
<LocalDebuggerCommandArguments>-j -c -n -g -b -t monster_test.fbs monsterdata_test.golden</LocalDebuggerCommandArguments>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<LocalDebuggerCommandArguments>-j -c -g -n -b -t monster_test.fbs monsterdata_test.golden</LocalDebuggerCommandArguments>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..\tests</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<LocalDebuggerCommandArguments>-j -c -g -b -t monster_test.fbs monsterdata_test.json</LocalDebuggerCommandArguments>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..\tests</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,273 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Debug|x64">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|x64">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGUID>{16FA5518-3DE1-4B15-A1E0-F4734C276FB4}</ProjectGUID>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
<ProjectName>flatsamplebinary</ProjectName>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)</OutDir>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)</OutDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">flatsamplebinary.dir\Debug\</IntDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">flatsamplebinary.dir\Debug\</IntDir>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">flatsamplebinary</TargetName>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">flatsamplebinary</TargetName>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.exe</TargetExt>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.exe</TargetExt>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</GenerateManifest>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</GenerateManifest>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)</OutDir>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)</OutDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">flatsamplebinary.dir\Release\</IntDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">flatsamplebinary.dir\Release\</IntDir>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">flatsamplebinary</TargetName>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">flatsamplebinary</TargetName>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.exe</TargetExt>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.exe</TargetExt>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</GenerateManifest>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateManifest>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Debug</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Debug/flatsamplebinary.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalOptions> /machine:X86 /debug %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Debug/flatsamplebinary.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Debug/flatsamplebinary.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Debug</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Debug/flatsamplebinary.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalOptions>/debug %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Debug/flatsamplebinary.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Debug/flatsamplebinary.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<DebugInformationFormat>
|
|
||||||
</DebugInformationFormat>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Release</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Release/flatsamplebinary.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalOptions> /machine:X86 %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Release/flatsamplebinary.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Release/flatsamplebinary.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<DebugInformationFormat>
|
|
||||||
</DebugInformationFormat>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Release</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Release/flatsamplebinary.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Release/flatsamplebinary.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Release/flatsamplebinary.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="..\..\include\flatbuffers\flatbuffers.h" />
|
|
||||||
<ClInclude Include="..\..\samples\monster_generated.h" />
|
|
||||||
<ClCompile Include="..\..\samples\sample_binary.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,277 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Debug|x64">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|x64">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGUID>{F0A15675-1017-4217-BB5B-3372F2C636AB}</ProjectGUID>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
<ProjectName>flatsampletext</ProjectName>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)</OutDir>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)</OutDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">flatsampletext.dir\Debug\</IntDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">flatsampletext.dir\Debug\</IntDir>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">flatsampletext</TargetName>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">flatsampletext</TargetName>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.exe</TargetExt>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.exe</TargetExt>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</GenerateManifest>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</GenerateManifest>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)</OutDir>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)</OutDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">flatsampletext.dir\Release\</IntDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">flatsampletext.dir\Release\</IntDir>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">flatsampletext</TargetName>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">flatsampletext</TargetName>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.exe</TargetExt>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.exe</TargetExt>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</GenerateManifest>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateManifest>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Debug</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Debug/flatsampletext.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalOptions> /machine:X86 /debug %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Debug/flatsampletext.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Debug/flatsampletext.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Debug</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Debug/flatsampletext.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalOptions>/debug %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Debug/flatsampletext.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Debug/flatsampletext.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<DebugInformationFormat>
|
|
||||||
</DebugInformationFormat>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Release</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Release/flatsampletext.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalOptions> /machine:X86 %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Release/flatsampletext.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Release/flatsampletext.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<DebugInformationFormat>
|
|
||||||
</DebugInformationFormat>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Release</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Release/flatsampletext.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Release/flatsampletext.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Release/flatsampletext.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="..\..\include\flatbuffers\flatbuffers.h" />
|
|
||||||
<ClInclude Include="..\..\include\flatbuffers\idl.h" />
|
|
||||||
<ClInclude Include="..\..\include\flatbuffers\util.h" />
|
|
||||||
<ClInclude Include="..\..\samples\monster_generated.h" />
|
|
||||||
<ClCompile Include="..\..\src\idl_parser.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\idl_gen_text.cpp" />
|
|
||||||
<ClCompile Include="..\..\samples\sample_text.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,281 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Debug|x64">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|x64">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGUID>{DC7BBA00-9FC6-48AF-B7E9-12CA91AC02AA}</ProjectGUID>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
<ProjectName>flattests</ProjectName>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)</OutDir>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)</OutDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">flattests.dir\Debug\</IntDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">flattests.dir\Debug\</IntDir>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">flattests</TargetName>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">flattests</TargetName>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.exe</TargetExt>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.exe</TargetExt>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</GenerateManifest>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</GenerateManifest>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)</OutDir>
|
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)</OutDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">flattests.dir\Release\</IntDir>
|
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">flattests.dir\Release\</IntDir>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">flattests</TargetName>
|
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">flattests</TargetName>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.exe</TargetExt>
|
|
||||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.exe</TargetExt>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</GenerateManifest>
|
|
||||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateManifest>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Debug</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Debug/flattests.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalOptions> /machine:X86 /debug %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Debug/flattests.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Debug/flattests.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Debug</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Debug/flattests.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalOptions>/debug %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Debug/flattests.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Debug/flattests.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<DebugInformationFormat>
|
|
||||||
</DebugInformationFormat>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Release</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Release/flattests.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalOptions> /machine:X86 %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Release/flattests.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Release/flattests.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<CompileAs>CompileAsCpp</CompileAs>
|
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
|
||||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<DebugInformationFormat>
|
|
||||||
</DebugInformationFormat>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AssemblerListingLocation>Release</AssemblerListingLocation>
|
|
||||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
|
||||||
<ProgramDataBaseFileName>../../Release/flattests.pdb</ProgramDataBaseFileName>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
<Midl>
|
|
||||||
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
|
||||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
|
||||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
|
||||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
|
||||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
|
||||||
</Midl>
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
|
||||||
<ImportLibrary>../../Release/flattests.lib</ImportLibrary>
|
|
||||||
<ProgramDataBaseFile>../../Release/flattests.pdb</ProgramDataBaseFile>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<Version>
|
|
||||||
</Version>
|
|
||||||
</Link>
|
|
||||||
<ProjectReference>
|
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="..\..\include\flatbuffers\flatbuffers.h" />
|
|
||||||
<ClInclude Include="..\..\include\flatbuffers\idl.h" />
|
|
||||||
<ClInclude Include="..\..\include\flatbuffers\reflection.h" />
|
|
||||||
<ClInclude Include="..\..\include\flatbuffers\util.h" />
|
|
||||||
<ClInclude Include="..\..\tests\monster_test_generated.h" />
|
|
||||||
<ClCompile Include="..\..\src\idl_gen_fbs.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\idl_gen_general.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\idl_parser.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\idl_gen_text.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\reflection.cpp" />
|
|
||||||
<ClCompile Include="..\..\tests\test.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<LocalDebuggerWorkingDirectory>..\..</LocalDebuggerWorkingDirectory>
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
||||||
File diff suppressed because it is too large
Load Diff
0
docs/footer.html
Executable file → Normal file
0
docs/footer.html
Executable file → Normal file
2
docs/source/Benchmarks.md
Executable file → Normal file
2
docs/source/Benchmarks.md
Executable file → Normal file
@@ -1,4 +1,4 @@
|
|||||||
Benchmarks {#flatbuffers_benchmarks}
|
C++ Benchmarks {#flatbuffers_benchmarks}
|
||||||
==========
|
==========
|
||||||
|
|
||||||
Comparing against other serialization solutions, running on Windows 7
|
Comparing against other serialization solutions, running on Windows 7
|
||||||
|
|||||||
7
docs/source/Building.md
Executable file → Normal file
7
docs/source/Building.md
Executable file → Normal file
@@ -1,14 +1,9 @@
|
|||||||
Building {#flatbuffers_guide_building}
|
Building {#flatbuffers_guide_building}
|
||||||
========
|
========
|
||||||
|
|
||||||
## Building with Visual Studio or Xcode projects
|
|
||||||
|
|
||||||
There are project files for Visual Studio and Xcode that should allow you
|
|
||||||
to build the compiler `flatc`, the samples and the tests out of the box.
|
|
||||||
|
|
||||||
## Building with CMake
|
## Building with CMake
|
||||||
|
|
||||||
Alternatively, the distribution comes with a `cmake` file that should allow
|
The distribution comes with a `cmake` file that should allow
|
||||||
you to build project/make files for any platform. For details on `cmake`, see
|
you to build project/make files for any platform. For details on `cmake`, see
|
||||||
<http://www.cmake.org>. In brief, depending on your platform, use one of
|
<http://www.cmake.org>. In brief, depending on your platform, use one of
|
||||||
e.g.:
|
e.g.:
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
../../CONTRIBUTING
|
../../CONTRIBUTING.md
|
||||||
224
docs/source/CUsage.md
Normal file
224
docs/source/CUsage.md
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
Use in C {#flatbuffers_guide_use_c}
|
||||||
|
==========
|
||||||
|
|
||||||
|
The C language binding exists in a separate project named [FlatCC](https://github.com/dvidelabs/flatcc).
|
||||||
|
|
||||||
|
The `flatcc` C schema compiler can generate code offline as well as
|
||||||
|
online via a C library. It can also generate buffer verifiers and fast
|
||||||
|
JSON parsers, printers.
|
||||||
|
|
||||||
|
Great care has been taken to ensure compatibily with the main `flatc`
|
||||||
|
project.
|
||||||
|
|
||||||
|
## General Documention
|
||||||
|
|
||||||
|
- [Tutorial](@ref flatbuffers_guide_tutorial) - select C as language
|
||||||
|
when scrolling down
|
||||||
|
- [FlatCC Guide](https://github.com/dvidelabs/flatcc#flatcc-flatbuffers-in-c-for-c)
|
||||||
|
- [The C Builder Interface](https://github.com/dvidelabs/flatcc/blob/master/doc/builder.md#the-builder-interface)
|
||||||
|
- [The Monster Sample in C](https://github.com/dvidelabs/flatcc/blob/master/samples/monster/monster.c)
|
||||||
|
- [GitHub](https://github.com/dvidelabs/flatcc)
|
||||||
|
|
||||||
|
|
||||||
|
## Supported Platforms
|
||||||
|
|
||||||
|
- Ubuntu (clang / gcc, ninja / gnu make)
|
||||||
|
- OS-X (clang / gcc, ninja / gnu make)
|
||||||
|
- Windows MSVC 2010, 2013, 2015
|
||||||
|
|
||||||
|
CI builds recent versions of gcc, clang and MSVC on OS-X, Ubuntu, and
|
||||||
|
Windows, and occasionally older compiler versions. See main project [Status](https://github.com/dvidelabs/flatcc#status).
|
||||||
|
|
||||||
|
Other platforms may well work, including Centos, but are not tested
|
||||||
|
regularly.
|
||||||
|
|
||||||
|
The monster sample project was specifically written for C99 in order to
|
||||||
|
follow the C++ version and for that reason it will not work with MSVC
|
||||||
|
2010.
|
||||||
|
|
||||||
|
## Modular Object Creation
|
||||||
|
|
||||||
|
In the tutorial we used the call `Monster_create_as_root` to create the
|
||||||
|
root buffer object since this is easier in simple use cases. Sometimes
|
||||||
|
we need more modularity so we can reuse a function to create nested
|
||||||
|
tables and root tables the same way. For this we need the
|
||||||
|
`flatcc_builder_buffer_create_call`. It is best to keep `flatcc_builder`
|
||||||
|
calls isolated at the top driver level, so we get:
|
||||||
|
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
ns(Monster_ref_t) create_orc(flatcc_builder_t *B)
|
||||||
|
{
|
||||||
|
// ... same as in the tutorial.
|
||||||
|
return s(Monster_create(B, ...));
|
||||||
|
}
|
||||||
|
|
||||||
|
void create_monster_buffer()
|
||||||
|
{
|
||||||
|
uint8_t *buf;
|
||||||
|
size_t size;
|
||||||
|
flatcc_builder_t builder, *B;
|
||||||
|
|
||||||
|
// Initialize the builder object.
|
||||||
|
B = &builder;
|
||||||
|
flatcc_builder_init(B);
|
||||||
|
// Only use `buffer_create` without `create/start/end_as_root`.
|
||||||
|
flatcc_builder_buffer_create(create_orc(B));
|
||||||
|
// Allocate and copy buffer to user memory.
|
||||||
|
buf = flatcc_builder_finalize_buffer(B, &size);
|
||||||
|
// ... write the buffer to disk or network, or something.
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
flatcc_builder_clear(B);
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
|
The same principle applies with `start/end` vs `start/end_as_root` in
|
||||||
|
the top-down approach.
|
||||||
|
|
||||||
|
|
||||||
|
## Top Down Example
|
||||||
|
|
||||||
|
The tutorial uses a bottom up approach. In C it is also possible to use
|
||||||
|
a top-down approach by starting and ending objects nested within each
|
||||||
|
other. In the tutorial there is no deep nesting, so the difference is
|
||||||
|
limited, but it shows the idea:
|
||||||
|
|
||||||
|
<div class="language-c">
|
||||||
|
<br>
|
||||||
|
~~~{.c}
|
||||||
|
uint8_t treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
|
size_t treasure_count = c_vec_len(treasure);
|
||||||
|
ns(Weapon_ref_t) axe;
|
||||||
|
|
||||||
|
// NOTE: if we use end_as_root, we MUST also start as root.
|
||||||
|
ns(Monster_start_as_root(B));
|
||||||
|
ns(Monster_pos_create(B, 1.0f, 2.0f, 3.0f));
|
||||||
|
ns(Monster_hp_add(B, 300));
|
||||||
|
ns(Monster_mana_add(B, 150));
|
||||||
|
// We use create_str instead of add because we have no existing string reference.
|
||||||
|
ns(Monster_name_create_str(B, "Orc"));
|
||||||
|
// Again we use create because we no existing vector object, only a C-array.
|
||||||
|
ns(Monster_inventory_create(B, treasure, treasure_count));
|
||||||
|
ns(Monster_color_add(B, ns(Color_Red)));
|
||||||
|
if (1) {
|
||||||
|
ns(Monster_weapons_start(B));
|
||||||
|
ns(Monster_weapons_push_create(B, flatbuffers_string_create_str(B, "Sword"), 3));
|
||||||
|
// We reuse the axe object later. Note that we dereference a pointer
|
||||||
|
// because push always returns a short-term pointer to the stored element.
|
||||||
|
// We could also have created the axe object first and simply pushed it.
|
||||||
|
axe = *ns(Monster_weapons_push_create(B, flatbuffers_string_create_str(B, "Axe"), 5));
|
||||||
|
ns(Monster_weapons_end(B));
|
||||||
|
} else {
|
||||||
|
// We can have more control with the table elements added to a vector:
|
||||||
|
//
|
||||||
|
ns(Monster_weapons_start(B));
|
||||||
|
ns(Monster_weapons_push_start(B));
|
||||||
|
ns(Weapon_name_create_str(B, "Sword"));
|
||||||
|
ns(Weapon_damage_add(B, 3));
|
||||||
|
ns(Monster_weapons_push_end(B));
|
||||||
|
ns(Monster_weapons_push_start(B));
|
||||||
|
ns(Monster_weapons_push_start(B));
|
||||||
|
ns(Weapon_name_create_str(B, "Axe"));
|
||||||
|
ns(Weapon_damage_add(B, 5));
|
||||||
|
axe = *ns(Monster_weapons_push_end(B));
|
||||||
|
ns(Monster_weapons_end(B));
|
||||||
|
}
|
||||||
|
// Unions can get their type by using a type-specific add/create/start method.
|
||||||
|
ns(Monster_equipped_Weapon_add(B, axe));
|
||||||
|
|
||||||
|
ns(Monster_end_as_root(B));
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
## Basic Reflection
|
||||||
|
|
||||||
|
The C-API does support reading binary schema (.bfbs)
|
||||||
|
files via code generated from the `reflection.fbs` schema, and an
|
||||||
|
[example usage](https://github.com/dvidelabs/flatcc/tree/master/samples/reflection)
|
||||||
|
shows how to use this. The reflection schema files are pre-generated
|
||||||
|
in the [runtime distribution](https://github.com/dvidelabs/flatcc/tree/master/include/flatcc/reflection).
|
||||||
|
|
||||||
|
|
||||||
|
## Mutations and Reflection
|
||||||
|
|
||||||
|
The C-API does not support mutating reflection like C++ does, nor does
|
||||||
|
the reader interface support mutating scalars (and it is generally
|
||||||
|
unsafe to do so even after verification).
|
||||||
|
|
||||||
|
The generated reader interface supports sorting vectors in-place after
|
||||||
|
casting them to a mutating type because it is not practical to do so
|
||||||
|
while building a buffer. This is covered in the builder documentation.
|
||||||
|
The reflection example makes use of this feature to look up objects by
|
||||||
|
name.
|
||||||
|
|
||||||
|
It is possible to build new buffers using complex objects from existing
|
||||||
|
buffers as source. This can be very efficient due to direct copy
|
||||||
|
semantics without endian conversion or temporary stack allocation.
|
||||||
|
|
||||||
|
Scalars, structs and strings can be used as source, as well vectors of
|
||||||
|
these.
|
||||||
|
|
||||||
|
It is currently not possible to use an existing table or vector of table
|
||||||
|
as source, but it would be possible to add support for this at some
|
||||||
|
point.
|
||||||
|
|
||||||
|
|
||||||
|
## Namespaces
|
||||||
|
|
||||||
|
The `FLATBUFFERS_WRAP_NAMESPACE` approach used in the tutorial is convenient
|
||||||
|
when each function has a very long namespace prefix. But it isn't always
|
||||||
|
the best approach. If the namespace is absent, or simple and
|
||||||
|
informative, we might as well use the prefix directly. The
|
||||||
|
[reflection example](https://github.com/dvidelabs/flatcc/blob/master/samples/reflection/bfbs2json.c)
|
||||||
|
mentioned above uses this approach.
|
||||||
|
|
||||||
|
|
||||||
|
## Checking for Present Members
|
||||||
|
|
||||||
|
Not all languages support testing if a field is present, but in C we can
|
||||||
|
elaborate the reader section of the tutorial with tests for this. Recall
|
||||||
|
that `mana` was set to the default value `150` and therefore shouldn't
|
||||||
|
be present.
|
||||||
|
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
int hp_present = ns(Monster_hp_is_present(monster)); // 1
|
||||||
|
int mana_present = ns(Monster_mana_is_present(monster)); // 0
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## Alternative ways to add a Union
|
||||||
|
|
||||||
|
In the tutorial we used a single call to add a union. Here we show
|
||||||
|
different ways to accomplish the same thing. The last form is rarely
|
||||||
|
used, but is the low-level way to do it. It can be used to group small
|
||||||
|
values together in the table by adding type and data at different
|
||||||
|
points in time.
|
||||||
|
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
ns(Equipment_union_ref_t) equipped = ns(Equipment_as_Weapon(axe));
|
||||||
|
ns(Monster_equipped_add(B, equipped));
|
||||||
|
// or alternatively
|
||||||
|
ns(Monster_equipped_Weapon_add(B, axe);
|
||||||
|
// or alternatively
|
||||||
|
ns(Monster_equipped_add_type(B, ns(Equipment_Weapon));
|
||||||
|
ns(Monster_equipped_add_member(B, axe));
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## Why not integrate with the `flatc` tool?
|
||||||
|
|
||||||
|
[It was considered how the C code generator could be integrated into the
|
||||||
|
`flatc` tool](https://github.com/dvidelabs/flatcc/issues/1), but it
|
||||||
|
would either require that the standalone C implementation of the schema
|
||||||
|
compiler was dropped, or it would lead to excessive code duplication, or
|
||||||
|
a complicated intermediate representation would have to be invented.
|
||||||
|
Neither of these alternatives are very attractive, and it isn't a big
|
||||||
|
deal to use the `flatcc` tool instead of `flatc` given that the
|
||||||
|
FlatBuffers C runtime library needs to be made available regardless.
|
||||||
|
|
||||||
|
|
||||||
29
docs/source/Compiler.md
Executable file → Normal file
29
docs/source/Compiler.md
Executable file → Normal file
@@ -29,10 +29,12 @@ For any schema input files, one or more generators can be specified:
|
|||||||
|
|
||||||
- `--python`, `-p`: Generate Python code.
|
- `--python`, `-p`: Generate Python code.
|
||||||
|
|
||||||
- `--javascript`, `-s`: Generate JavaScript code.
|
- `--js`, `-s`: Generate JavaScript code.
|
||||||
|
|
||||||
- `--php`: Generate PHP code.
|
- `--php`: Generate PHP code.
|
||||||
|
|
||||||
|
- `--grpc`: Generate RPC stub code for GRPC.
|
||||||
|
|
||||||
For any data input files:
|
For any data input files:
|
||||||
|
|
||||||
- `--binary`, `-b` : If data is contained in this file, generate a
|
- `--binary`, `-b` : If data is contained in this file, generate a
|
||||||
@@ -79,6 +81,11 @@ Additional options:
|
|||||||
- `--gen-mutable` : Generate additional non-const accessors for mutating
|
- `--gen-mutable` : Generate additional non-const accessors for mutating
|
||||||
FlatBuffers in-place.
|
FlatBuffers in-place.
|
||||||
|
|
||||||
|
`--gen-object-api` : Generate an additional object-based API. This API is
|
||||||
|
more convenient for object construction and mutation than the base API,
|
||||||
|
at the cost of efficiency (object allocation). Recommended only to be used
|
||||||
|
if other options are insufficient.
|
||||||
|
|
||||||
- `--gen-onefile` : Generate single output file (useful for C#)
|
- `--gen-onefile` : Generate single output file (useful for C#)
|
||||||
|
|
||||||
- `--gen-all`: Generate not just code for the current schema files, but
|
- `--gen-all`: Generate not just code for the current schema files, but
|
||||||
@@ -86,6 +93,12 @@ Additional options:
|
|||||||
output (by default the case for C++ and JS), all code will end up in
|
output (by default the case for C++ and JS), all code will end up in
|
||||||
this one file.
|
this one file.
|
||||||
|
|
||||||
|
- `--no-js-exports` : Removes Node.js style export lines (useful for JS)
|
||||||
|
|
||||||
|
- `--goog-js-export` : Uses goog.exportsSymbol and goog.exportsProperty
|
||||||
|
instead of Node.js style exporting. Needed for compatibility with the
|
||||||
|
Google closure compiler (useful for JS).
|
||||||
|
|
||||||
- `--raw-binary` : Allow binaries without a file_indentifier to be read.
|
- `--raw-binary` : Allow binaries without a file_indentifier to be read.
|
||||||
This may crash flatc given a mismatched schema.
|
This may crash flatc given a mismatched schema.
|
||||||
|
|
||||||
@@ -101,5 +114,19 @@ Additional options:
|
|||||||
to the reflection/reflection.fbs schema. Loading this binary file is the
|
to the reflection/reflection.fbs schema. Loading this binary file is the
|
||||||
basis for reflection functionality.
|
basis for reflection functionality.
|
||||||
|
|
||||||
|
- `--bfbs-comments`: Add doc comments to the binary schema files.
|
||||||
|
|
||||||
|
- `--conform FILE` : Specify a schema the following schemas should be
|
||||||
|
an evolution of. Gives errors if not. Useful to check if schema
|
||||||
|
modifications don't break schema evolution rules.
|
||||||
|
|
||||||
|
- `--include-prefix PATH` : Prefix this path to any generated include
|
||||||
|
statements.
|
||||||
|
|
||||||
|
- `--keep-prefix` : Keep original prefix of schema include statement.
|
||||||
|
|
||||||
|
- `--reflect-types` : Add minimal type reflection to code generation.
|
||||||
|
- `--reflect-names` : Add minimal type/name reflection.
|
||||||
|
|
||||||
NOTE: short-form options for generators are deprecated, use the long form
|
NOTE: short-form options for generators are deprecated, use the long form
|
||||||
whenever possible.
|
whenever possible.
|
||||||
|
|||||||
169
docs/source/CppUsage.md
Executable file → Normal file
169
docs/source/CppUsage.md
Executable file → Normal file
@@ -26,8 +26,7 @@ your program by including the header. As noted, this header relies on
|
|||||||
|
|
||||||
The code for the FlatBuffers C++ library can be found at
|
The code for the FlatBuffers C++ library can be found at
|
||||||
`flatbuffers/include/flatbuffers`. You can browse the library code on the
|
`flatbuffers/include/flatbuffers`. You can browse the library code on the
|
||||||
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
|
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/include/flatbuffers).
|
||||||
include/flatbuffers).
|
|
||||||
|
|
||||||
## Testing the FlatBuffers C++ library
|
## Testing the FlatBuffers C++ library
|
||||||
|
|
||||||
@@ -86,6 +85,130 @@ convenient accessors for all fields, e.g. `hp()`, `mana()`, etc:
|
|||||||
|
|
||||||
*Note: That we never stored a `mana` value, so it will return the default.*
|
*Note: That we never stored a `mana` value, so it will return the default.*
|
||||||
|
|
||||||
|
## Object based API. {#flatbuffers_cpp_object_based_api}
|
||||||
|
|
||||||
|
FlatBuffers is all about memory efficiency, which is why its base API is written
|
||||||
|
around using as little as possible of it. This does make the API clumsier
|
||||||
|
(requiring pre-order construction of all data, and making mutation harder).
|
||||||
|
|
||||||
|
For times when efficiency is less important a more convenient object based API
|
||||||
|
can be used (through `--gen-object-api`) that is able to unpack & pack a
|
||||||
|
FlatBuffer into objects and standard STL containers, allowing for convenient
|
||||||
|
construction, access and mutation.
|
||||||
|
|
||||||
|
To use:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||||
|
// Autogenerated class from table Monster.
|
||||||
|
MonsterT monsterobj;
|
||||||
|
|
||||||
|
// Deserialize from buffer into object.
|
||||||
|
UnPackTo(&monsterobj, flatbuffer);
|
||||||
|
|
||||||
|
// Update object directly like a C++ class instance.
|
||||||
|
cout << monsterobj->name; // This is now a std::string!
|
||||||
|
monsterobj->name = "Bob"; // Change the name.
|
||||||
|
|
||||||
|
// Serialize into new flatbuffer.
|
||||||
|
FlatBufferBuilder fbb;
|
||||||
|
Pack(fbb, &monsterobj);
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The following attributes are specific to the object-based API code generation:
|
||||||
|
|
||||||
|
- `native_inline` (on a field): Because FlatBuffer tables and structs are
|
||||||
|
optionally present in a given buffer, they are best represented as pointers
|
||||||
|
(specifically std::unique_ptrs) in the native class since they can be null.
|
||||||
|
This attribute changes the member declaration to use the type directly
|
||||||
|
rather than wrapped in a unique_ptr.
|
||||||
|
|
||||||
|
- `native_default`: "value" (on a field): For members that are declared
|
||||||
|
"native_inline", the value specified with this attribute will be included
|
||||||
|
verbatim in the class constructor initializer list for this member.
|
||||||
|
|
||||||
|
- `native_type`' "type" (on a struct): In some cases, a more optimal C++ data
|
||||||
|
type exists for a given struct. For example, the following schema:
|
||||||
|
|
||||||
|
struct Vec2 {
|
||||||
|
x: float;
|
||||||
|
y: float;
|
||||||
|
}
|
||||||
|
|
||||||
|
generates the following Object-Based API class:
|
||||||
|
|
||||||
|
struct Vec2T : flatbuffers::NativeTable {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
};
|
||||||
|
|
||||||
|
However, it can be useful to instead use a user-defined C++ type since it
|
||||||
|
can provide more functionality, eg.
|
||||||
|
|
||||||
|
struct vector2 {
|
||||||
|
float x = 0, y = 0;
|
||||||
|
vector2 operator+(vector2 rhs) const { ... }
|
||||||
|
vector2 operator-(vector2 rhs) const { ... }
|
||||||
|
float length() const { ... }
|
||||||
|
// etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
The `native_type` attribute will replace the usage of the generated class
|
||||||
|
with the given type. So, continuing with the example, the generated
|
||||||
|
code would use |vector2| in place of |Vec2T| for all generated code.
|
||||||
|
|
||||||
|
However, becuase the native_type is unknown to flatbuffers, the user must
|
||||||
|
provide the following functions to aide in the serialization process:
|
||||||
|
|
||||||
|
namespace flatbuffers {
|
||||||
|
FlatbufferStruct Pack(const native_type& obj);
|
||||||
|
native_type UnPack(const FlatbufferStruct& obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
Finally, the following top-level attribute
|
||||||
|
|
||||||
|
- native_include: "path" (at file level): Because the `native_type` attribute
|
||||||
|
can be used to introduce types that are unknown to flatbuffers, it may be
|
||||||
|
necessary to include "external" header files in the generated code. This
|
||||||
|
attribute can be used to directly add an #include directive to the top of
|
||||||
|
the generated code that includes the specified path directly.
|
||||||
|
|
||||||
|
# External references.
|
||||||
|
|
||||||
|
An additional feature of the object API is the ability to allow you to load
|
||||||
|
multiple independent FlatBuffers, and have them refer to eachothers objects
|
||||||
|
using hashes which are then represented as typed pointers in the object API.
|
||||||
|
|
||||||
|
To make this work have a field in the objects you want to referred to which is
|
||||||
|
using the string hashing feature (see `hash` attribute in the
|
||||||
|
[schema](@ref flatbuffers_guide_writing_schema) documentation). Then you have
|
||||||
|
a similar hash in the field referring to it, along with a `cpp_type`
|
||||||
|
attribute specifying the C++ type this will refer to (this can be any C++
|
||||||
|
type, and will get a `*` added).
|
||||||
|
|
||||||
|
Then, in JSON or however you create these buffers, make sure they use the
|
||||||
|
same string (or hash).
|
||||||
|
|
||||||
|
When you call `UnPack` (or `Create`), you'll need a function that maps from
|
||||||
|
hash to the object (see `resolver_function_t` for details).
|
||||||
|
|
||||||
|
# Using different pointer types.
|
||||||
|
|
||||||
|
By default the object tree is built out of `std::unique_ptr`, but you can
|
||||||
|
influence this either globally (using the `--cpp-ptr-type` argument to
|
||||||
|
`flatc`) or per field (using the `cpp_ptr_type` attribute) to by any smart
|
||||||
|
pointer type (`my_ptr<T>`), or by specifying `naked` as the type to get `T *`
|
||||||
|
pointers. Unlike the smart pointers, naked pointers do not manage memory for
|
||||||
|
you, so you'll have to manage their lifecycles manually.
|
||||||
|
|
||||||
|
|
||||||
|
# Using different string type.
|
||||||
|
|
||||||
|
By default the object tree is built out of `std::string`, but you can
|
||||||
|
influence this either globally (using the `--cpp-str-type` argument to
|
||||||
|
`flatc`) or per field using the `cpp_str_type` attribute.
|
||||||
|
|
||||||
|
The type must support T::c_str() and T::length() as member functions.
|
||||||
|
|
||||||
## Reflection (& Resizing)
|
## Reflection (& Resizing)
|
||||||
|
|
||||||
There is experimental support for reflection in FlatBuffers, allowing you to
|
There is experimental support for reflection in FlatBuffers, allowing you to
|
||||||
@@ -108,6 +231,30 @@ schema, as well as a lot of helper functions.
|
|||||||
And example of usage, for the time being, can be found in
|
And example of usage, for the time being, can be found in
|
||||||
`test.cpp/ReflectionTest()`.
|
`test.cpp/ReflectionTest()`.
|
||||||
|
|
||||||
|
## Mini Reflection
|
||||||
|
|
||||||
|
A more limited form of reflection is available for direct inclusion in
|
||||||
|
generated code, which doesn't any (binary) schema access at all. It was designed
|
||||||
|
to keep the overhead of reflection as low as possible (on the order of 2-6
|
||||||
|
bytes per field added to your executable), but doesn't contain all the
|
||||||
|
information the (binary) schema contains.
|
||||||
|
|
||||||
|
You add this information to your generated code by specifying `--reflect-types`
|
||||||
|
(or instead `--reflect-names` if you also want field / enum names).
|
||||||
|
|
||||||
|
You can now use this information, for example to print a FlatBuffer to text:
|
||||||
|
|
||||||
|
auto s = flatbuffers::FlatBufferToString(flatbuf, MonsterTypeTable());
|
||||||
|
|
||||||
|
`MonsterTypeTable()` is declared in the generated code for each type. The
|
||||||
|
string produced is very similar to the JSON produced by the `Parser` based
|
||||||
|
text generator.
|
||||||
|
|
||||||
|
You'll need `flatbuffers/minireflect.h` for this functionality. In there is also
|
||||||
|
a convenient visitor/iterator so you can write your own output / functionality
|
||||||
|
based on the mini reflection tables without having to know the FlatBuffers or
|
||||||
|
reflection encoding.
|
||||||
|
|
||||||
## Storing maps / dictionaries in a FlatBuffer
|
## Storing maps / dictionaries in a FlatBuffer
|
||||||
|
|
||||||
FlatBuffers doesn't support maps natively, but there is support to
|
FlatBuffers doesn't support maps natively, but there is support to
|
||||||
@@ -288,4 +435,22 @@ manually wrap it in synchronisation primites. There's no automatic way to
|
|||||||
accomplish this, by design, as we feel multithreaded construction
|
accomplish this, by design, as we feel multithreaded construction
|
||||||
of a single buffer will be rare, and synchronisation overhead would be costly.
|
of a single buffer will be rare, and synchronisation overhead would be costly.
|
||||||
|
|
||||||
|
## Advanced union features
|
||||||
|
|
||||||
|
The C++ implementation currently supports vectors of unions (i.e. you can
|
||||||
|
declare a field as `[T]` where `T` is a union type instead of a table type). It
|
||||||
|
also supports structs and strings in unions, besides tables.
|
||||||
|
|
||||||
|
For an example of these features, see `tests/union_vector`, and
|
||||||
|
`UnionVectorTest` in `test.cpp`.
|
||||||
|
|
||||||
|
Since these features haven't been ported to other languages yet, if you
|
||||||
|
choose to use them, you won't be able to use these buffers in other languages
|
||||||
|
(`flatc` will refuse to compile a schema that uses these features).
|
||||||
|
|
||||||
|
These features reduce the amount of "table wrapping" that was previously
|
||||||
|
needed to use unions.
|
||||||
|
|
||||||
|
To use scalars, simply wrap them in a struct.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ FlatBuffers {#flatbuffers_index}
|
|||||||
# Overview {#flatbuffers_overview}
|
# Overview {#flatbuffers_overview}
|
||||||
|
|
||||||
[FlatBuffers](@ref flatbuffers_overview) is an efficient cross platform
|
[FlatBuffers](@ref flatbuffers_overview) is an efficient cross platform
|
||||||
serialization library for C++, C#, Go, Java, JavaScript, PHP, and Python
|
serialization library for C++, C#, C, Go, Java, JavaScript, PHP, and Python.
|
||||||
(C and Ruby in progress). It was originally created at Google for game
|
It was originally created at Google for game development and other
|
||||||
development and other performance-critical applications.
|
performance-critical applications.
|
||||||
|
|
||||||
It is available as Open Source on [GitHub](http://github.com/google/flatbuffers)
|
It is available as Open Source on [GitHub](http://github.com/google/flatbuffers)
|
||||||
under the Apache license, v2 (see LICENSE.txt).
|
under the Apache license, v2 (see LICENSE.txt).
|
||||||
@@ -78,6 +78,9 @@ inefficiency, but also forces you to write *more* code to access data
|
|||||||
In this context, it is only a better choice for systems that have very
|
In this context, it is only a better choice for systems that have very
|
||||||
little to no information ahead of time about what data needs to be stored.
|
little to no information ahead of time about what data needs to be stored.
|
||||||
|
|
||||||
|
If you do need to store data that doesn't fit a schema, FlatBuffers also
|
||||||
|
offers a schema-less (self-describing) version!
|
||||||
|
|
||||||
Read more about the "why" of FlatBuffers in the
|
Read more about the "why" of FlatBuffers in the
|
||||||
[white paper](@ref flatbuffers_white_paper).
|
[white paper](@ref flatbuffers_white_paper).
|
||||||
|
|
||||||
@@ -131,11 +134,15 @@ sections provide a more in-depth usage guide.
|
|||||||
in your own programs.
|
in your own programs.
|
||||||
- How to [use the generated Go code](@ref flatbuffers_guide_use_go) in your
|
- How to [use the generated Go code](@ref flatbuffers_guide_use_go) in your
|
||||||
own programs.
|
own programs.
|
||||||
|
- How to [use FlatBuffers in C with `flatcc`](@ref flatbuffers_guide_use_c) in your
|
||||||
|
own programs.
|
||||||
- [Support matrix](@ref flatbuffers_support) for platforms/languages/features.
|
- [Support matrix](@ref flatbuffers_support) for platforms/languages/features.
|
||||||
- Some [benchmarks](@ref flatbuffers_benchmarks) showing the advantage of
|
- Some [benchmarks](@ref flatbuffers_benchmarks) showing the advantage of
|
||||||
using FlatBuffers.
|
using FlatBuffers.
|
||||||
- A [white paper](@ref flatbuffers_white_paper) explaining the "why" of
|
- A [white paper](@ref flatbuffers_white_paper) explaining the "why" of
|
||||||
FlatBuffers.
|
FlatBuffers.
|
||||||
|
- How to use the [schema-less](@ref flexbuffers) version of
|
||||||
|
FlatBuffers.
|
||||||
- A description of the [internals](@ref flatbuffers_internals) of FlatBuffers.
|
- A description of the [internals](@ref flatbuffers_internals) of FlatBuffers.
|
||||||
- A formal [grammar](@ref flatbuffers_grammar) of the schema language.
|
- A formal [grammar](@ref flatbuffers_grammar) of the schema language.
|
||||||
|
|
||||||
@@ -143,7 +150,7 @@ sections provide a more in-depth usage guide.
|
|||||||
|
|
||||||
- [GitHub repository](http://github.com/google/flatbuffers)
|
- [GitHub repository](http://github.com/google/flatbuffers)
|
||||||
- [Landing page](http://google.github.io/flatbuffers)
|
- [Landing page](http://google.github.io/flatbuffers)
|
||||||
- [FlatBuffers Google Group](http://group.google.com/group/flatbuffers)
|
- [FlatBuffers Google Group](https://groups.google.com/forum/#!forum/flatbuffers)
|
||||||
- [FlatBuffers Issues Tracker](http://github.com/google/flatbuffers/issues)
|
- [FlatBuffers Issues Tracker](http://github.com/google/flatbuffers/issues)
|
||||||
- Independent implementations & tools:
|
- Independent implementations & tools:
|
||||||
- [FlatCC](https://github.com/dvidelabs/flatcc) Alternative FlatBuffers
|
- [FlatCC](https://github.com/dvidelabs/flatcc) Alternative FlatBuffers
|
||||||
|
|||||||
166
docs/source/FlexBuffers.md
Normal file
166
docs/source/FlexBuffers.md
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
FlexBuffers {#flexbuffers}
|
||||||
|
==========
|
||||||
|
|
||||||
|
FlatBuffers was designed around schemas, because when you want maximum
|
||||||
|
performance and data consistency, strong typing is helpful.
|
||||||
|
|
||||||
|
There are however times when you want to store data that doesn't fit a
|
||||||
|
schema, because you can't know ahead of time what all needs to be stored.
|
||||||
|
|
||||||
|
For this, FlatBuffers has a dedicated format, called FlexBuffers.
|
||||||
|
This is a binary format that can be used in conjunction
|
||||||
|
with FlatBuffers (by storing a part of a buffer in FlexBuffers
|
||||||
|
format), or also as its own independent serialization format.
|
||||||
|
|
||||||
|
While it loses the strong typing, you retain the most unique advantage
|
||||||
|
FlatBuffers has over other serialization formats (schema-based or not):
|
||||||
|
FlexBuffers can also be accessed without parsing / copying / object allocation.
|
||||||
|
This is a huge win in efficiency / memory friendly-ness, and allows unique
|
||||||
|
use cases such as mmap-ing large amounts of free-form data.
|
||||||
|
|
||||||
|
FlexBuffers' design and implementation allows for a very compact encoding,
|
||||||
|
combining automatic pooling of strings with automatic sizing of containers to
|
||||||
|
their smallest possible representation (8/16/32/64 bits). Many values and
|
||||||
|
offsets can be encoded in just 8 bits. While a schema-less representation is
|
||||||
|
usually more bulky because of the need to be self-descriptive, FlexBuffers
|
||||||
|
generates smaller binaries for many cases than regular FlatBuffers.
|
||||||
|
|
||||||
|
FlexBuffers is still slower than regular FlatBuffers though, so we recommend to
|
||||||
|
only use it if you need it.
|
||||||
|
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
This is for C++, other languages may follow.
|
||||||
|
|
||||||
|
Include the header `flexbuffers.h`, which in turn depends on `flatbuffers.h`
|
||||||
|
and `util.h`.
|
||||||
|
|
||||||
|
To create a buffer:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||||
|
flexbuffers::Builder fbb;
|
||||||
|
fbb.Int(13);
|
||||||
|
fbb.Finish();
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
You create any value, followed by `Finish`. Unlike FlatBuffers which requires
|
||||||
|
the root value to be a table, here any value can be the root, including a lonely
|
||||||
|
int value.
|
||||||
|
|
||||||
|
You can now access the `std::vector<uint8_t>` that contains the encoded value
|
||||||
|
as `fbb.GetBuffer()`. Write it, send it, or store it in a parent FlatBuffer. In
|
||||||
|
this case, the buffer is just 3 bytes in size.
|
||||||
|
|
||||||
|
To read this value back, you could just say:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||||
|
auto root = flexbuffers::GetRoot(my_buffer);
|
||||||
|
int64_t i = root.AsInt64();
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
FlexBuffers stores ints only as big as needed, so it doesn't differentiate
|
||||||
|
between different sizes of ints. You can ask for the 64 bit version,
|
||||||
|
regardless of what you put in. In fact, since you demand to read the root
|
||||||
|
as an int, if you supply a buffer that actually contains a float, or a
|
||||||
|
string with numbers in it, it will convert it for you on the fly as well,
|
||||||
|
or return 0 if it can't. If instead you actually want to know what is inside
|
||||||
|
the buffer before you access it, you can call `root.GetType()` or `root.IsInt()`
|
||||||
|
etc.
|
||||||
|
|
||||||
|
Here's a slightly more complex value you could write instead of `fbb.Int` above:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||||
|
fbb.Map([&]() {
|
||||||
|
fbb.Vector("vec", [&]() {
|
||||||
|
fbb.Int(-100);
|
||||||
|
fbb.String("Fred");
|
||||||
|
fbb.IndirectFloat(4.0f);
|
||||||
|
});
|
||||||
|
fbb.UInt("foo", 100);
|
||||||
|
});
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This stores the equivalent of the JSON value
|
||||||
|
`{ vec: [ -100, "Fred", 4.0 ], foo: 100 }`. The root is a dictionary that has
|
||||||
|
just two key-value pairs, with keys `vec` and `foo`. Unlike FlatBuffers, it
|
||||||
|
actually has to store these keys in the buffer (which it does only once if
|
||||||
|
you store multiple such objects, by pooling key values), but also unlike
|
||||||
|
FlatBuffers it has no restriction on the keys (fields) that you use.
|
||||||
|
|
||||||
|
The map constructor uses a C++11 Lambda to group its children, but you can
|
||||||
|
also use more conventional start/end calls if you prefer.
|
||||||
|
|
||||||
|
The first value in the map is a vector. You'll notice that unlike FlatBuffers,
|
||||||
|
you can use mixed types. There is also a `TypedVector` variant that only
|
||||||
|
allows a single type, and uses a bit less memory.
|
||||||
|
|
||||||
|
`IndirectFloat` is an interesting feature that allows you to store values
|
||||||
|
by offset rather than inline. Though that doesn't make any visible change
|
||||||
|
to the user, the consequence is that large values (especially doubles or
|
||||||
|
64 bit ints) that occur more than once can be shared. Another use case is
|
||||||
|
inside of vectors, where the largest element makes up the size of all elements
|
||||||
|
(e.g. a single double forces all elements to 64bit), so storing a lot of small
|
||||||
|
integers together with a double is more efficient if the double is indirect.
|
||||||
|
|
||||||
|
Accessing it:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||||
|
auto map = flexbuffers::GetRoot(my_buffer).AsMap();
|
||||||
|
map.size(); // 2
|
||||||
|
auto vec = map["vec"].AsVector();
|
||||||
|
vec.size(); // 3
|
||||||
|
vec[0].AsInt64(); // -100;
|
||||||
|
vec[1].AsString().c_str(); // "Fred";
|
||||||
|
vec[1].AsInt64(); // 0 (Number parsing failed).
|
||||||
|
vec[2].AsDouble(); // 4.0
|
||||||
|
vec[2].AsString().IsTheEmptyString(); // true (Wrong Type).
|
||||||
|
vec[2].AsString().c_str(); // "" (This still works though).
|
||||||
|
vec[2].ToString().c_str(); // "4" (Or have it converted).
|
||||||
|
map["foo"].AsUInt8(); // 100
|
||||||
|
map["unknown"].IsNull(); // true
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
# Binary encoding
|
||||||
|
|
||||||
|
A description of how FlexBuffers are encoded is in the
|
||||||
|
[internals](@ref flatbuffers_internals) document.
|
||||||
|
|
||||||
|
|
||||||
|
# Nesting inside a FlatBuffer
|
||||||
|
|
||||||
|
You can mark a field as containing a FlexBuffer, e.g.
|
||||||
|
|
||||||
|
a:[ubyte] (flexbuffer);
|
||||||
|
|
||||||
|
A special accessor will be generated that allows you to access the root value
|
||||||
|
directly, e.g. `a_flexbuffer_root().AsInt64()`.
|
||||||
|
|
||||||
|
|
||||||
|
# Efficiency tips
|
||||||
|
|
||||||
|
* Vectors generally are a lot more efficient than maps, so prefer them over maps
|
||||||
|
when possible for small objects. Instead of a map with keys `x`, `y` and `z`,
|
||||||
|
use a vector. Better yet, use a typed vector. Or even better, use a fixed
|
||||||
|
size typed vector.
|
||||||
|
* Maps are backwards compatible with vectors, and can be iterated as such.
|
||||||
|
You can iterate either just the values (`map.Values()`), or in parallel with
|
||||||
|
the keys vector (`map.Keys()`). If you intend
|
||||||
|
to access most or all elements, this is faster than looking up each element
|
||||||
|
by key, since that involves a binary search of the key vector.
|
||||||
|
* When possible, don't mix values that require a big bit width (such as double)
|
||||||
|
in a large vector of smaller values, since all elements will take on this
|
||||||
|
width. Use `IndirectDouble` when this is a possibility. Note that
|
||||||
|
integers automatically use the smallest width possible, i.e. if you ask
|
||||||
|
to serialize an int64_t whose value is actually small, you will use less
|
||||||
|
bits. Doubles are represented as floats whenever possible losslessly, but
|
||||||
|
this is only possible for few values.
|
||||||
|
Since nested vectors/maps are stored over offsets, they typically don't
|
||||||
|
affect the vector width.
|
||||||
|
* To store large arrays of byte data, use a blob. If you'd use a typed
|
||||||
|
vector, the bit width of the size field may make it use more space than
|
||||||
|
expected, and may not be compatible with `memcpy`.
|
||||||
|
Similarly, large arrays of (u)int16_t may be better off stored as a
|
||||||
|
binary blob if their size could exceed 64k elements.
|
||||||
|
Construction and use are otherwise similar to strings.
|
||||||
@@ -67,6 +67,29 @@ Now you can access values like this:
|
|||||||
pos := monster.Pos(nil)
|
pos := monster.Pos(nil)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
In some cases it's necessary to modify values in an existing FlatBuffer in place (without creating a copy). For this reason, scalar fields of a Flatbuffer table or struct can be mutated.
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.go}
|
||||||
|
monster := example.GetRootAsMonster(buf, 0)
|
||||||
|
|
||||||
|
// Set table field.
|
||||||
|
if ok := monster.MutateHp(10); !ok {
|
||||||
|
panic("failed to mutate Hp")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set struct field.
|
||||||
|
monster.Pos().MutateZ(4)
|
||||||
|
|
||||||
|
// This mutation will fail because the mana field is not available in
|
||||||
|
// the buffer. It should be set when creating the buffer.
|
||||||
|
if ok := monster.MutateMana(20); !ok {
|
||||||
|
panic("failed to mutate Hp")
|
||||||
|
}
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The term `mutate` is used instead of `set` to indicate that this is a special use case. All mutate functions return a boolean value which is false if the field we're trying to mutate is not available in the buffer.
|
||||||
|
|
||||||
## Text Parsing
|
## Text Parsing
|
||||||
|
|
||||||
There currently is no support for parsing text (Schema's and JSON) directly
|
There currently is no support for parsing text (Schema's and JSON) directly
|
||||||
|
|||||||
25
docs/source/Grammar.md
Executable file → Normal file
25
docs/source/Grammar.md
Executable file → Normal file
@@ -4,7 +4,7 @@ Grammar of the schema language {#flatbuffers_grammar}
|
|||||||
schema = include*
|
schema = include*
|
||||||
( namespace\_decl | type\_decl | enum\_decl | root\_decl |
|
( namespace\_decl | type\_decl | enum\_decl | root\_decl |
|
||||||
file_extension_decl | file_identifier_decl |
|
file_extension_decl | file_identifier_decl |
|
||||||
attribute\_decl | object )*
|
attribute\_decl | rpc\_decl | object )*
|
||||||
|
|
||||||
include = `include` string\_constant `;`
|
include = `include` string\_constant `;`
|
||||||
|
|
||||||
@@ -14,16 +14,22 @@ attribute\_decl = `attribute` string\_constant `;`
|
|||||||
|
|
||||||
type\_decl = ( `table` | `struct` ) ident metadata `{` field\_decl+ `}`
|
type\_decl = ( `table` | `struct` ) ident metadata `{` field\_decl+ `}`
|
||||||
|
|
||||||
enum\_decl = ( `enum` | `union` ) ident [ `:` type ] metadata `{` commasep(
|
enum\_decl = ( `enum` ident [ `:` type ] | `union` ident ) metadata `{`
|
||||||
enumval\_decl ) `}`
|
commasep( enumval\_decl ) `}`
|
||||||
|
|
||||||
root\_decl = `root_type` ident `;`
|
root\_decl = `root_type` ident `;`
|
||||||
|
|
||||||
field\_decl = ident `:` type [ `=` scalar ] metadata `;`
|
field\_decl = ident `:` type [ `=` scalar ] metadata `;`
|
||||||
|
|
||||||
|
rpc\_decl = `rpc_service` ident `{` rpc\_method+ `}`
|
||||||
|
|
||||||
|
rpc\_method = ident `(` ident `)` `:` ident metadata `;`
|
||||||
|
|
||||||
type = `bool` | `byte` | `ubyte` | `short` | `ushort` | `int` | `uint` |
|
type = `bool` | `byte` | `ubyte` | `short` | `ushort` | `int` | `uint` |
|
||||||
`float` | `long` | `ulong` | `double`
|
`float` | `long` | `ulong` | `double` |
|
||||||
| `string` | `[` type `]` | ident
|
`int8` | `uint8` | `int16` | `uint16` | `int32` | `uint32`| `int64` | `uint64` |
|
||||||
|
`float32` | `float64` |
|
||||||
|
`string` | `[` type `]` | ident
|
||||||
|
|
||||||
enumval\_decl = ident [ `=` integer\_constant ]
|
enumval\_decl = ident [ `=` integer\_constant ]
|
||||||
|
|
||||||
@@ -43,6 +49,11 @@ file_extension_decl = `file_extension` string\_constant `;`
|
|||||||
|
|
||||||
file_identifier_decl = `file_identifier` string\_constant `;`
|
file_identifier_decl = `file_identifier` string\_constant `;`
|
||||||
|
|
||||||
integer\_constant = -?[0-9]+ | `true` | `false`
|
integer\_constant = `-?[0-9]+` | `true` | `false`
|
||||||
|
|
||||||
|
float\_constant = `-?[0-9]+.[0-9]+((e|E)(+|-)?[0-9]+)?`
|
||||||
|
|
||||||
|
string\_constant = `\".*?\"`
|
||||||
|
|
||||||
|
ident = `[a-zA-Z_][a-zA-Z0-9_]*`
|
||||||
|
|
||||||
float\_constant = -?[0-9]+.[0-9]+((e|E)(+|-)?[0-9]+)?
|
|
||||||
|
|||||||
154
docs/source/Internals.md
Executable file → Normal file
154
docs/source/Internals.md
Executable file → Normal file
@@ -292,4 +292,158 @@ flexibility in which of the children of root object to write first (though in
|
|||||||
this case there's only one string), and what order to write the fields in.
|
this case there's only one string), and what order to write the fields in.
|
||||||
Different orders may also cause different alignments to happen.
|
Different orders may also cause different alignments to happen.
|
||||||
|
|
||||||
|
### Additional reading.
|
||||||
|
|
||||||
|
The author of the C language implementation has made a similar
|
||||||
|
[document](https://github.com/dvidelabs/flatcc/blob/master/doc/binary-format.md#flatbuffers-binary-format)
|
||||||
|
that may further help clarify the format.
|
||||||
|
|
||||||
|
# FlexBuffers
|
||||||
|
|
||||||
|
The [schema-less](@ref flexbuffers) version of FlatBuffers have their
|
||||||
|
own encoding, detailed here.
|
||||||
|
|
||||||
|
It shares many properties mentioned above, in that all data is accessed
|
||||||
|
over offsets, all scalars are aligned to their own size, and
|
||||||
|
all data is always stored in little endian format.
|
||||||
|
|
||||||
|
One difference is that FlexBuffers are built front to back, so children are
|
||||||
|
stored before parents, and the root of the data starts at the last byte.
|
||||||
|
|
||||||
|
Another difference is that scalar data is stored with a variable number of bits
|
||||||
|
(8/16/32/64). The current width is always determined by the *parent*, i.e. if
|
||||||
|
the scalar sits in a vector, the vector determines the bit width for all
|
||||||
|
elements at once. Selecting the minimum bit width for a particular vector is
|
||||||
|
something the encoder does automatically and thus is typically of no concern
|
||||||
|
to the user, though being aware of this feature (and not sticking a double in
|
||||||
|
the same vector as a bunch of byte sized elements) is helpful for efficiency.
|
||||||
|
|
||||||
|
Unlike FlatBuffers there is only one kind of offset, and that is an unsigned
|
||||||
|
integer indicating the number of bytes in a negative direction from the address
|
||||||
|
of itself (where the offset is stored).
|
||||||
|
|
||||||
|
### Vectors
|
||||||
|
|
||||||
|
The representation of the vector is at the core of how FlexBuffers works (since
|
||||||
|
maps are really just a combination of 2 vectors), so it is worth starting there.
|
||||||
|
|
||||||
|
As mentioned, a vector is governed by a single bit width (supplied by its
|
||||||
|
parent). This includes the size field. For example, a vector that stores the
|
||||||
|
integer values `1, 2, 3` is encoded as follows:
|
||||||
|
|
||||||
|
uint8_t 3, 1, 2, 3, 4, 4, 4
|
||||||
|
|
||||||
|
The first `3` is the size field, and is placed before the vector (an offset
|
||||||
|
from the parent to this vector points to the first element, not the size
|
||||||
|
field, so the size field is effectively at index -1).
|
||||||
|
Since this is an untyped vector `SL_VECTOR`, it is followed by 3 type
|
||||||
|
bytes (one per element of the vector), which are always following the vector,
|
||||||
|
and are always a uint8_t even if the vector is made up of bigger scalars.
|
||||||
|
|
||||||
|
### Types
|
||||||
|
|
||||||
|
A type byte is made up of 2 components (see flexbuffers.h for exact values):
|
||||||
|
|
||||||
|
* 2 lower bits representing the bit-width of the child (8, 16, 32, 64).
|
||||||
|
This is only used if the child is accessed over an offset, such as a child
|
||||||
|
vector. It is ignored for inline types.
|
||||||
|
* 6 bits representing the actual type (see flexbuffers.h).
|
||||||
|
|
||||||
|
Thus, in this example `4` means 8 bit child (value 0, unused, since the value is
|
||||||
|
in-line), type `SL_INT` (value 1).
|
||||||
|
|
||||||
|
### Typed Vectors
|
||||||
|
|
||||||
|
These are like the Vectors above, but omit the type bytes. The type is instead
|
||||||
|
determined by the vector type supplied by the parent. Typed vectors are only
|
||||||
|
available for a subset of types for which these savings can be significant,
|
||||||
|
namely inline signed/unsigned integers (`TYPE_VECTOR_INT` / `TYPE_VECTOR_UINT`),
|
||||||
|
floats (`TYPE_VECTOR_FLOAT`), and keys (`TYPE_VECTOR_KEY`, see below).
|
||||||
|
|
||||||
|
Additionally, for scalars, there are fixed length vectors of sizes 2 / 3 / 4
|
||||||
|
that don't store the size (`TYPE_VECTOR_INT2` etc.), for an additional savings
|
||||||
|
in space when storing common vector or color data.
|
||||||
|
|
||||||
|
### Scalars
|
||||||
|
|
||||||
|
FlexBuffers supports integers (`TYPE_INT` and `TYPE_UINT`) and floats
|
||||||
|
(`TYPE_FLOAT`), available in the bit-widths mentioned above. They can be stored
|
||||||
|
both inline and over an offset (`TYPE_INDIRECT_*`).
|
||||||
|
|
||||||
|
The offset version is useful to encode costly 64bit (or even 32bit) quantities
|
||||||
|
into vectors / maps of smaller sizes, and to share / repeat a value multiple
|
||||||
|
times.
|
||||||
|
|
||||||
|
### Booleans and Nulls
|
||||||
|
|
||||||
|
Booleans (`TYPE_BOOL`) and nulls (`TYPE_NULL`) are encoded as inlined unsigned integers.
|
||||||
|
|
||||||
|
### Blobs, Strings and Keys.
|
||||||
|
|
||||||
|
A blob (`TYPE_BLOB`) is encoded similar to a vector, with one difference: the
|
||||||
|
elements are always `uint8_t`. The parent bit width only determines the width of
|
||||||
|
the size field, allowing blobs to be large without the elements being large.
|
||||||
|
|
||||||
|
Strings (`TYPE_STRING`) are similar to blobs, except they have an additional 0
|
||||||
|
termination byte for convenience, and they MUST be UTF-8 encoded (since an
|
||||||
|
accessor in a language that does not support pointers to UTF-8 data may have to
|
||||||
|
convert them to a native string type).
|
||||||
|
|
||||||
|
A "Key" (`TYPE_KEY`) is similar to a string, but doesn't store the size
|
||||||
|
field. They're so named because they are used with maps, which don't care
|
||||||
|
for the size, and can thus be even more compact. Unlike strings, keys cannot
|
||||||
|
contain bytes of value 0 as part of their data (size can only be determined by
|
||||||
|
`strlen`), so while you can use them outside the context of maps if you so
|
||||||
|
desire, you're usually better off with strings.
|
||||||
|
|
||||||
|
### Maps
|
||||||
|
|
||||||
|
A map (`TYPE_MAP`) is like an (untyped) vector, but with 2 prefixes before the
|
||||||
|
size field:
|
||||||
|
|
||||||
|
| index | field |
|
||||||
|
| ----: | :----------------------------------------------------------- |
|
||||||
|
| -3 | An offset to the keys vector (may be shared between tables). |
|
||||||
|
| -2 | Byte width of the keys vector. |
|
||||||
|
| -1 | Size (from here on it is compatible with `TYPE_VECTOR`) |
|
||||||
|
| 0 | Elements. |
|
||||||
|
| Size | Types. |
|
||||||
|
|
||||||
|
Since a map is otherwise the same as a vector, it can be iterated like
|
||||||
|
a vector (which is probably faster than lookup by key).
|
||||||
|
|
||||||
|
The keys vector is a typed vector of keys. Both the keys and corresponding
|
||||||
|
values *have* to be stored in sorted order (as determined by `strcmp`), such
|
||||||
|
that lookups can be made using binary search.
|
||||||
|
|
||||||
|
The reason the key vector is a seperate structure from the value vector is
|
||||||
|
such that it can be shared between multiple value vectors, and also to
|
||||||
|
allow it to be treated as its own individual vector in code.
|
||||||
|
|
||||||
|
An example map { foo: 13, bar: 14 } would be encoded as:
|
||||||
|
|
||||||
|
0 : uint8_t 'b', 'a', 'r', 0
|
||||||
|
4 : uint8_t 'f', 'o', 'o', 0
|
||||||
|
8 : uint8_t 2 // key vector of size 2
|
||||||
|
// key vector offset points here
|
||||||
|
9 : uint8_t 9, 6 // offsets to bar_key and foo_key
|
||||||
|
11: uint8_t 2, 1 // offset to key vector, and its byte width
|
||||||
|
13: uint8_t 2 // value vector of size
|
||||||
|
// value vector offset points here
|
||||||
|
14: uint8_t 14, 13 // values
|
||||||
|
16: uint8_t 4, 4 // types
|
||||||
|
|
||||||
|
### The root
|
||||||
|
|
||||||
|
As mentioned, the root starts at the end of the buffer.
|
||||||
|
The last uint8_t is the width in bytes of the root (normally the parent
|
||||||
|
determines the width, but the root has no parent). The uint8_t before this is
|
||||||
|
the type of the root, and the bytes before that are the root value (of the
|
||||||
|
number of bytes specified by the last byte).
|
||||||
|
|
||||||
|
So for example, the integer value `13` as root would be:
|
||||||
|
|
||||||
|
uint8_t 13, 4, 1 // Value, type, root byte width.
|
||||||
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|||||||
31
docs/source/JavaCsharpUsage.md
Executable file → Normal file
31
docs/source/JavaCsharpUsage.md
Executable file → Normal file
@@ -131,6 +131,37 @@ object are prefixed with `Get`, e.g.:
|
|||||||
monster.GetPos(preconstructedPos);
|
monster.GetPos(preconstructedPos);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
## Storing dictionaries in a FlatBuffer
|
||||||
|
|
||||||
|
FlatBuffers doesn't support dictionaries natively, but there is support to
|
||||||
|
emulate their behavior with vectors and binary search, which means you
|
||||||
|
can have fast lookups directly from a FlatBuffer without having to unpack
|
||||||
|
your data into a `Dictionary` or similar.
|
||||||
|
|
||||||
|
To use it:
|
||||||
|
- Designate one of the fields in a table as the "key" field. You do this
|
||||||
|
by setting the `key` attribute on this field, e.g.
|
||||||
|
`name:string (key)`.
|
||||||
|
You may only have one key field, and it must be of string or scalar type.
|
||||||
|
- Write out tables of this type as usual, collect their offsets in an
|
||||||
|
array.
|
||||||
|
- Instead of calling standard generated method,
|
||||||
|
e.g.: `Monster.createTestarrayoftablesVector`,
|
||||||
|
call `CreateSortedVectorOfMonster` in C# or
|
||||||
|
`createSortedVectorOfTables` (from the `FlatBufferBuilder` object) in Java,
|
||||||
|
which will first sort all offsets such that the tables they refer to
|
||||||
|
are sorted by the key field, then serialize it.
|
||||||
|
- Now when you're accessing the FlatBuffer, you can use
|
||||||
|
the `ByKey` accessor to access elements of the vector, e.g.:
|
||||||
|
`monster.testarrayoftablesByKey("Frodo")` in Java or
|
||||||
|
`monster.TestarrayoftablesByKey("Frodo")` in C#,
|
||||||
|
which returns an object of the corresponding table type,
|
||||||
|
or `null` if not found.
|
||||||
|
`ByKey` performs a binary search, so should have a similar
|
||||||
|
speed to `Dictionary`, though may be faster because of better caching.
|
||||||
|
`ByKey` only works if the vector has been sorted, it will
|
||||||
|
likely not find elements if it hasn't been sorted.
|
||||||
|
|
||||||
## Text parsing
|
## Text parsing
|
||||||
|
|
||||||
There currently is no support for parsing text (Schema's and JSON) directly
|
There currently is no support for parsing text (Schema's and JSON) directly
|
||||||
|
|||||||
0
docs/source/JavaScriptUsage.md
Executable file → Normal file
0
docs/source/JavaScriptUsage.md
Executable file → Normal file
27
docs/source/PythonUsage.md
Executable file → Normal file
27
docs/source/PythonUsage.md
Executable file → Normal file
@@ -64,6 +64,33 @@ Now you can access values like this:
|
|||||||
pos = monster.Pos()
|
pos = monster.Pos()
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
## Support for Numpy arrays
|
||||||
|
|
||||||
|
The Flatbuffers python library also has support for accessing scalar
|
||||||
|
vectors as numpy arrays. This can be orders of magnitude faster than
|
||||||
|
iterating over the vector one element at a time, and is particularly
|
||||||
|
useful when unpacking large nested flatbuffers. The generated code for
|
||||||
|
a scalar vector will have a method `<vector name>AsNumpy()`. In the
|
||||||
|
case of the Monster example, you could access the inventory vector
|
||||||
|
like this:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
|
||||||
|
inventory = monster.InventoryAsNumpy()
|
||||||
|
# inventory is a numpy array of type np.dtype('uint8')
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
instead of
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
|
||||||
|
inventory = []
|
||||||
|
for i in range(monster.InventoryLength()):
|
||||||
|
inventory.append(int(monster.Inventory(i)))
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Numpy is not a requirement. If numpy is not installed on your system,
|
||||||
|
then attempting to access one of the `*asNumpy()` methods will result
|
||||||
|
in a `NumpyRequiredForThisFeature` exception.
|
||||||
|
|
||||||
## Text Parsing
|
## Text Parsing
|
||||||
|
|
||||||
There currently is no support for parsing text (Schema's and JSON) directly
|
There currently is no support for parsing text (Schema's and JSON) directly
|
||||||
|
|||||||
154
docs/source/Schemas.md
Executable file → Normal file
154
docs/source/Schemas.md
Executable file → Normal file
@@ -84,15 +84,19 @@ parent object, and use no virtual table).
|
|||||||
|
|
||||||
### Types
|
### Types
|
||||||
|
|
||||||
Built-in scalar types are:
|
Built-in scalar types are
|
||||||
|
|
||||||
- 8 bit: `byte`, `ubyte`, `bool`
|
- 8 bit: `byte` (`int8`), `ubyte` (`uint8`), `bool`
|
||||||
|
|
||||||
- 16 bit: `short`, `ushort`
|
- 16 bit: `short` (`int16`), `ushort` (`uint16`)
|
||||||
|
|
||||||
- 32 bit: `int`, `uint`, `float`
|
- 32 bit: `int` (`int32`), `uint` (`uint32`), `float` (`float32`)
|
||||||
|
|
||||||
- 64 bit: `long`, `ulong`, `double`
|
- 64 bit: `long` (`int64`), `ulong` (`uint64`), `double` (`float64`)
|
||||||
|
|
||||||
|
The type names in parentheses are alias names such that for example
|
||||||
|
`uint8` can be used in place of `ubyte`, and `int32` can be used in
|
||||||
|
place of `int` without affecting code generation.
|
||||||
|
|
||||||
Built-in non-scalar types:
|
Built-in non-scalar types:
|
||||||
|
|
||||||
@@ -122,7 +126,8 @@ default to `NULL` when not present.
|
|||||||
|
|
||||||
You generally do not want to change default values after they're initially
|
You generally do not want to change default values after they're initially
|
||||||
defined. Fields that have the default value are not actually stored in the
|
defined. Fields that have the default value are not actually stored in the
|
||||||
serialized data but are generated in code, so when you change the default, you'd
|
serialized data (see also Gotchas below) but are generated in code,
|
||||||
|
so when you change the default, you'd
|
||||||
now get a different value than from code generated from an older version of
|
now get a different value than from code generated from an older version of
|
||||||
the schema. There are situations, however, where this may be
|
the schema. There are situations, however, where this may be
|
||||||
desirable, especially if you can ensure a simultaneous rebuild of
|
desirable, especially if you can ensure a simultaneous rebuild of
|
||||||
@@ -157,6 +162,10 @@ If you have a need to distinguish between different FlatBuffers in a more
|
|||||||
open-ended way, for example for use as files, see the file identification
|
open-ended way, for example for use as files, see the file identification
|
||||||
feature below.
|
feature below.
|
||||||
|
|
||||||
|
There is an experimental support only in C++ for a vector of unions
|
||||||
|
(and types). In the example IDL file above, use [Any] to add a
|
||||||
|
vector of Any to Monster table.
|
||||||
|
|
||||||
### Namespaces
|
### Namespaces
|
||||||
|
|
||||||
These will generate the corresponding namespace in C++ for all helper
|
These will generate the corresponding namespace in C++ for all helper
|
||||||
@@ -224,6 +233,21 @@ This declaration in the schema will change that to whatever you want:
|
|||||||
|
|
||||||
file_extension "ext";
|
file_extension "ext";
|
||||||
|
|
||||||
|
### RPC interface declarations
|
||||||
|
|
||||||
|
You can declare RPC calls in a schema, that define a set of functions
|
||||||
|
that take a FlatBuffer as an argument (the request) and return a FlatBuffer
|
||||||
|
as the response (both of which must be table types):
|
||||||
|
|
||||||
|
rpc_service MonsterStorage {
|
||||||
|
Store(Monster):StoreResponse;
|
||||||
|
Retrieve(MonsterId):Monster;
|
||||||
|
}
|
||||||
|
|
||||||
|
What code this produces and how it is used depends on language and RPC system
|
||||||
|
used, there is preliminary support for GRPC through the `--grpc` code generator,
|
||||||
|
see `grpc/tests` for an example.
|
||||||
|
|
||||||
### Comments & documentation
|
### Comments & documentation
|
||||||
|
|
||||||
May be written as in most C-based languages. Additionally, a triple
|
May be written as in most C-based languages. Additionally, a triple
|
||||||
@@ -256,9 +280,12 @@ Current understood attributes:
|
|||||||
the union field should have id 8, and the unions type field will
|
the union field should have id 8, and the unions type field will
|
||||||
implicitly be 7.
|
implicitly be 7.
|
||||||
IDs allow the fields to be placed in any order in the schema.
|
IDs allow the fields to be placed in any order in the schema.
|
||||||
When a new field is added to the schema is must use the next available ID.
|
When a new field is added to the schema it must use the next available ID.
|
||||||
- `deprecated` (on a field): do not generate accessors for this field
|
- `deprecated` (on a field): do not generate accessors for this field
|
||||||
anymore, code should stop using this data.
|
anymore, code should stop using this data. Old data may still contain this
|
||||||
|
field, but it won't be accessible anymore by newer code. Note that if you
|
||||||
|
deprecate a field that was previous required, old code may fail to validate
|
||||||
|
new data (when using the optional verifier).
|
||||||
- `required` (on a non-scalar table field): this field must always be set.
|
- `required` (on a non-scalar table field): this field must always be set.
|
||||||
By default, all fields are optional, i.e. may be left out. This is
|
By default, all fields are optional, i.e. may be left out. This is
|
||||||
desirable, as it helps with forwards/backwards compatibility, and
|
desirable, as it helps with forwards/backwards compatibility, and
|
||||||
@@ -268,10 +295,10 @@ Current understood attributes:
|
|||||||
constructs FlatBuffers to ensure this field is initialized, so the reading
|
constructs FlatBuffers to ensure this field is initialized, so the reading
|
||||||
code may access it directly, without checking for NULL. If the constructing
|
code may access it directly, without checking for NULL. If the constructing
|
||||||
code does not initialize this field, they will get an assert, and also
|
code does not initialize this field, they will get an assert, and also
|
||||||
the verifier will fail on buffers that have missing required fields.
|
the verifier will fail on buffers that have missing required fields. Note
|
||||||
- `original_order` (on a table): since elements in a table do not need
|
that if you add this attribute to an existing field, this will only be
|
||||||
to be stored in any particular order, they are often optimized for
|
valid if existing data always contains this field / existing code always
|
||||||
space by sorting them to size. This attribute stops that from happening.
|
writes this field.
|
||||||
- `force_align: size` (on a struct): force the alignment of this struct
|
- `force_align: size` (on a struct): force the alignment of this struct
|
||||||
to be something higher than what it is naturally aligned to. Causes
|
to be something higher than what it is naturally aligned to. Causes
|
||||||
these structs to be aligned to that amount inside a buffer, IF that
|
these structs to be aligned to that amount inside a buffer, IF that
|
||||||
@@ -285,9 +312,24 @@ Current understood attributes:
|
|||||||
(which must be a vector of ubyte) contains flatbuffer data, for which the
|
(which must be a vector of ubyte) contains flatbuffer data, for which the
|
||||||
root type is given by `table_name`. The generated code will then produce
|
root type is given by `table_name`. The generated code will then produce
|
||||||
a convenient accessor for the nested FlatBuffer.
|
a convenient accessor for the nested FlatBuffer.
|
||||||
|
- `flexbuffer` (on a field): this indicates that the field
|
||||||
|
(which must be a vector of ubyte) contains flexbuffer data. The generated
|
||||||
|
code will then produce a convenient accessor for the FlexBuffer root.
|
||||||
- `key` (on a field): this field is meant to be used as a key when sorting
|
- `key` (on a field): this field is meant to be used as a key when sorting
|
||||||
a vector of the type of table it sits in. Can be used for in-place
|
a vector of the type of table it sits in. Can be used for in-place
|
||||||
binary search.
|
binary search.
|
||||||
|
- `hash` (on a field). This is an (un)signed 32/64 bit integer field, whose
|
||||||
|
value during JSON parsing is allowed to be a string, which will then be
|
||||||
|
stored as its hash. The value of attribute is the hashing algorithm to
|
||||||
|
use, one of `fnv1_32` `fnv1_64` `fnv1a_32` `fnv1a_64`.
|
||||||
|
- `original_order` (on a table): since elements in a table do not need
|
||||||
|
to be stored in any particular order, they are often optimized for
|
||||||
|
space by sorting them to size. This attribute stops that from happening.
|
||||||
|
There should generally not be any reason to use this flag.
|
||||||
|
- 'native_*'. Several attributes have been added to support the [C++ object
|
||||||
|
Based API](@ref flatbuffers_cpp_object_based_api). All such attributes
|
||||||
|
are prefixed with the term "native_".
|
||||||
|
|
||||||
|
|
||||||
## JSON Parsing
|
## JSON Parsing
|
||||||
|
|
||||||
@@ -318,6 +360,10 @@ JSON:
|
|||||||
- A field that has the value `null` (e.g. `field: null`) is intended to
|
- A field that has the value `null` (e.g. `field: null`) is intended to
|
||||||
have the default value for that field (thus has the same effect as if
|
have the default value for that field (thus has the same effect as if
|
||||||
that field wasn't specified at all).
|
that field wasn't specified at all).
|
||||||
|
- It has some built in conversion functions, so you can write for example
|
||||||
|
`rad(180)` where ever you'd normally write `3.14159`.
|
||||||
|
Currently supports the following functions: `rad`, `deg`, `cos`, `sin`,
|
||||||
|
`tan`, `acos`, `asin`, `atan`.
|
||||||
|
|
||||||
When parsing JSON, it recognizes the following escape codes in strings:
|
When parsing JSON, it recognizes the following escape codes in strings:
|
||||||
|
|
||||||
@@ -339,6 +385,66 @@ When parsing JSON, it recognizes the following escape codes in strings:
|
|||||||
It also generates these escape codes back again when generating JSON from a
|
It also generates these escape codes back again when generating JSON from a
|
||||||
binary representation.
|
binary representation.
|
||||||
|
|
||||||
|
## Guidelines
|
||||||
|
|
||||||
|
### Efficiency
|
||||||
|
|
||||||
|
FlatBuffers is all about efficiency, but to realize that efficiency you
|
||||||
|
require an efficient schema. There are usually multiple choices on
|
||||||
|
how to represent data that have vastly different size characteristics.
|
||||||
|
|
||||||
|
It is very common nowadays to represent any kind of data as dictionaries
|
||||||
|
(as in e.g. JSON), because of its flexibility and extensibility. While
|
||||||
|
it is possible to emulate this in FlatBuffers (as a vector
|
||||||
|
of tables with key and value(s)), this is a bad match for a strongly
|
||||||
|
typed system like FlatBuffers, leading to relatively large binaries.
|
||||||
|
FlatBuffer tables are more flexible than classes/structs in most systems,
|
||||||
|
since having a large number of fields only few of which are actually
|
||||||
|
used is still efficient. You should thus try to organize your data
|
||||||
|
as much as possible such that you can use tables where you might be
|
||||||
|
tempted to use a dictionary.
|
||||||
|
|
||||||
|
Similarly, strings as values should only be used when they are
|
||||||
|
truely open-ended. If you can, always use an enum instead.
|
||||||
|
|
||||||
|
FlatBuffers doesn't have inheritance, so the way to represent a set
|
||||||
|
of related data structures is a union. Unions do have a cost however,
|
||||||
|
so an alternative to a union is to have a single table that has
|
||||||
|
all the fields of all the data structures you are trying to
|
||||||
|
represent, if they are relatively similar / share many fields.
|
||||||
|
Again, this is efficient because optional fields are cheap.
|
||||||
|
|
||||||
|
FlatBuffers supports the full range of integer sizes, so try to pick
|
||||||
|
the smallest size needed, rather than defaulting to int/long.
|
||||||
|
|
||||||
|
Remember that you can share data (refer to the same string/table
|
||||||
|
within a buffer), so factoring out repeating data into its own
|
||||||
|
data structure may be worth it.
|
||||||
|
|
||||||
|
### Style guide
|
||||||
|
|
||||||
|
Identifiers in a schema are meant to translate to many different programming
|
||||||
|
languages, so using the style of your "main" language is generally a bad idea.
|
||||||
|
|
||||||
|
For this reason, below is a suggested style guide to adhere to, to keep schemas
|
||||||
|
consistent for interoperation regardless of the target language.
|
||||||
|
|
||||||
|
Where possible, the code generators for specific languages will generate
|
||||||
|
identifiers that adhere to the language style, based on the schema identifiers.
|
||||||
|
|
||||||
|
- Table, struct, enum and rpc names (types): UpperCamelCase.
|
||||||
|
- Table and struct field names: snake_case. This is translated to lowerCamelCase
|
||||||
|
automatically for some languages, e.g. Java.
|
||||||
|
- Enum values: UpperCamelCase.
|
||||||
|
- namespaces: UpperCamelCase.
|
||||||
|
|
||||||
|
Formatting (this is less important, but still worth adhering to):
|
||||||
|
|
||||||
|
- Opening brace: on the same line as the start of the declaration.
|
||||||
|
- Spacing: Indent by 2 spaces. None around `:` for types, on both sides for `=`.
|
||||||
|
|
||||||
|
For an example, see the schema at the top of this file.
|
||||||
|
|
||||||
## Gotchas
|
## Gotchas
|
||||||
|
|
||||||
### Schemas and version control
|
### Schemas and version control
|
||||||
@@ -425,4 +531,28 @@ incompatible with the actual binary buffers, since those only ever address
|
|||||||
fields by id/offset.
|
fields by id/offset.
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
### Testing whether a field is present in a table
|
||||||
|
|
||||||
|
Most serialization formats (e.g. JSON or Protocol Buffers) make it very
|
||||||
|
explicit in the format whether a field is present in an object or not,
|
||||||
|
allowing you to use this as "extra" information.
|
||||||
|
|
||||||
|
In FlatBuffers, this also holds for everything except scalar values.
|
||||||
|
|
||||||
|
FlatBuffers by default will not write fields that are equal to the default
|
||||||
|
value (for scalars), sometimes resulting in a significant space savings.
|
||||||
|
|
||||||
|
However, this also means testing whether a field is "present" is somewhat
|
||||||
|
meaningless, since it does not tell you if the field was actually written by
|
||||||
|
calling `add_field` style calls, unless you're only interested in this
|
||||||
|
information for non-default values.
|
||||||
|
|
||||||
|
Some `FlatBufferBuilder` implementations have an option called `force_defaults`
|
||||||
|
that circumvents this behavior, and writes fields even if they are equal to
|
||||||
|
the default. You can then use `IsFieldPresent` to query this.
|
||||||
|
|
||||||
|
Another option that works in all languages is to wrap a scalar field in a
|
||||||
|
struct. This way it will return null if it is not present. The cool thing
|
||||||
|
is that structs don't take up any more space than the scalar they represent.
|
||||||
|
|
||||||
[Interface Definition Language]: https://en.wikipedia.org/wiki/Interface_description_language
|
[Interface Definition Language]: https://en.wikipedia.org/wiki/Interface_description_language
|
||||||
|
|||||||
34
docs/source/Support.md
Executable file → Normal file
34
docs/source/Support.md
Executable file → Normal file
@@ -18,23 +18,23 @@ In general:
|
|||||||
|
|
||||||
NOTE: this table is a start, it needs to be extended.
|
NOTE: this table is a start, it needs to be extended.
|
||||||
|
|
||||||
Feature | C++ | Java | C# | Go | Python | JS | C | PHP | Ruby
|
Feature | C++ | Java | C# | Go | Python | JS | C | PHP | Ruby
|
||||||
------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | ---- | --- | ----
|
------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | ------ | --- | ----
|
||||||
Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | WiP | WiP | WiP
|
Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | Yes | WiP | WiP
|
||||||
JSON parsing | Yes | No | No | No | No | No | No | No | No
|
JSON parsing | Yes | No | No | No | No | No | Yes | No | No
|
||||||
Simple mutation | Yes | WIP | WIP | No | No | No | No | No | No
|
Simple mutation | Yes | WIP | WIP | No | No | No | No | No | No
|
||||||
Reflection | Yes | No | No | No | No | No | No | No | No
|
Reflection | Yes | No | No | No | No | No | Basic | No | No
|
||||||
Buffer verifier | Yes | No | No | No | No | No | No | No | No
|
Buffer verifier | Yes | No | No | No | No | No | Yes | No | No
|
||||||
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | ? | ? | ?
|
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | ?
|
||||||
Testing: fuzz | Yes | No | No | Yes | Yes | No | ? | ? | ?
|
Testing: fuzz | Yes | No | No | Yes | Yes | No | No | ? | ?
|
||||||
Performance: | Superb | Great | Great | Great | Ok | ? |Superb| ? | ?
|
Performance: | Superb | Great | Great | Great | Ok | ? | Superb | ? | ?
|
||||||
Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | ? | ? | ?
|
Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | VS2010 | ? | ?
|
||||||
Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | ? | ? | ?
|
Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | Yes | ? | ?
|
||||||
Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | ? | ? | ?
|
Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | Yes | ? | ?
|
||||||
Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ?
|
Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ?
|
||||||
Platform: iOS | ? | ? | ? | ? | ? | ? | ? | ? | ?
|
Platform: iOS | ? | ? | ? | ? | ? | ? | ? | ? | ?
|
||||||
Engine: Unity | ? | ? | Yes | ? | ? | ? | ? | ? | ?
|
Engine: Unity | ? | ? | Yes | ? | ? | ? | ? | ? | ?
|
||||||
Primary authors (github) | gwvo | gwvo | ev*/js*| rw | rw | evanw/ev* | mik* | ch* | rw
|
Primary authors (github) | gwvo | gwvo | ev*/js*| rw | rw | evanw/ev* | mik* | ch* | rw
|
||||||
|
|
||||||
* ev = evolutional
|
* ev = evolutional
|
||||||
* js = jonsimantov
|
* js = jonsimantov
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ character, the hero of the story, needs to slay some `orc`s. We will walk
|
|||||||
through each step necessary to create this monster type using FlatBuffers.
|
through each step necessary to create this monster type using FlatBuffers.
|
||||||
|
|
||||||
Please select your desired language for our quest:
|
Please select your desired language for our quest:
|
||||||
|
|
||||||
\htmlonly
|
\htmlonly
|
||||||
<form>
|
<form>
|
||||||
<input type="radio" name="language" value="cpp" checked="checked">C++</input>
|
<input type="radio" name="language" value="cpp" checked="checked">C++</input>
|
||||||
@@ -29,6 +28,7 @@ Please select your desired language for our quest:
|
|||||||
<input type="radio" name="language" value="python">Python</input>
|
<input type="radio" name="language" value="python">Python</input>
|
||||||
<input type="radio" name="language" value="javascript">JavaScript</input>
|
<input type="radio" name="language" value="javascript">JavaScript</input>
|
||||||
<input type="radio" name="language" value="php">PHP</input>
|
<input type="radio" name="language" value="php">PHP</input>
|
||||||
|
<input type="radio" name="language" value="c">C</input>
|
||||||
</form>
|
</form>
|
||||||
\endhtmlonly
|
\endhtmlonly
|
||||||
|
|
||||||
@@ -98,6 +98,10 @@ Samples demonstating the concepts in this example are located in the source code
|
|||||||
package, under the `samples` directory. You can browse the samples on GitHub
|
package, under the `samples` directory. You can browse the samples on GitHub
|
||||||
[here](https://github.com/google/flatbuffers/tree/master/samples).
|
[here](https://github.com/google/flatbuffers/tree/master/samples).
|
||||||
|
|
||||||
|
<div class="language-c">
|
||||||
|
*Note: The above does not apply to C, instead [look here](https://github.com/dvidelabs/flatcc/tree/master/samples).*
|
||||||
|
</div>
|
||||||
|
|
||||||
For your chosen language, please cross-reference with:
|
For your chosen language, please cross-reference with:
|
||||||
|
|
||||||
<div class="language-cpp">
|
<div class="language-cpp">
|
||||||
@@ -121,6 +125,9 @@ For your chosen language, please cross-reference with:
|
|||||||
<div class="language-php">
|
<div class="language-php">
|
||||||
[SampleBinary.php](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.php)
|
[SampleBinary.php](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.php)
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
[monster.c](https://github.com/dvidelabs/flatcc/blob/master/samples/monster/monster.c)
|
||||||
|
</div>
|
||||||
|
|
||||||
## Writing the Monsters' FlatBuffer Schema
|
## Writing the Monsters' FlatBuffer Schema
|
||||||
|
|
||||||
@@ -153,6 +160,7 @@ the `schema` that defines the template for our monsters:
|
|||||||
color:Color = Blue; // Enum.
|
color:Color = Blue; // Enum.
|
||||||
weapons:[Weapon]; // Vector of tables.
|
weapons:[Weapon]; // Vector of tables.
|
||||||
equipped:Equipment; // Union.
|
equipped:Equipment; // Union.
|
||||||
|
path:[Vec3]; // Vector of structs.
|
||||||
}
|
}
|
||||||
|
|
||||||
table Weapon {
|
table Weapon {
|
||||||
@@ -202,12 +210,21 @@ The `Weapon` table is a sub-table used within our FlatBuffer. It is
|
|||||||
used twice: once within the `Monster` table and once within the `Equipment`
|
used twice: once within the `Monster` table and once within the `Equipment`
|
||||||
enum. For our `Monster`, it is used to populate a `vector of tables` via the
|
enum. For our `Monster`, it is used to populate a `vector of tables` via the
|
||||||
`weapons` field within our `Monster`. It is also the only table referenced by
|
`weapons` field within our `Monster`. It is also the only table referenced by
|
||||||
the `Equipment` enum.
|
the `Equipment` union.
|
||||||
|
|
||||||
The last part of the `schema` is the `root_type`. The root type declares what
|
The last part of the `schema` is the `root_type`. The root type declares what
|
||||||
will be the root table for the serialized data. In our case, the root type is
|
will be the root table for the serialized data. In our case, the root type is
|
||||||
our `Monster` table.
|
our `Monster` table.
|
||||||
|
|
||||||
|
The scalar types can also use alias type names such as `int16` instead
|
||||||
|
of `short` and `float32` instead of `float`. Thus we could also write
|
||||||
|
the `Weapon` table as:
|
||||||
|
|
||||||
|
table Weapon {
|
||||||
|
name:string;
|
||||||
|
damage:int16;
|
||||||
|
}
|
||||||
|
|
||||||
#### More Information About Schemas
|
#### More Information About Schemas
|
||||||
|
|
||||||
You can find a complete guide to writing `schema` files in the
|
You can find a complete guide to writing `schema` files in the
|
||||||
@@ -225,6 +242,15 @@ FlatBuffer compiler.
|
|||||||
|
|
||||||
Once `flatc` is built successfully, compile the schema for your language:
|
Once `flatc` is built successfully, compile the schema for your language:
|
||||||
|
|
||||||
|
<div class="language-c">
|
||||||
|
*Note: If you're working in C, you need to use the separate project [FlatCC](https://github.com/dvidelabs/flatcc) which contains a schema compiler and runtime library in C for C.*
|
||||||
|
<br>
|
||||||
|
See [flatcc build instructions](https://github.com/dvidelabs/flatcc#building).
|
||||||
|
<br>
|
||||||
|
Please be aware of the difference between `flatc` and `flatcc` tools.
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="language-cpp">
|
<div class="language-cpp">
|
||||||
~~~{.sh}
|
~~~{.sh}
|
||||||
cd flatbuffers/sample
|
cd flatbuffers/sample
|
||||||
@@ -267,8 +293,17 @@ Once `flatc` is built successfully, compile the schema for your language:
|
|||||||
./../flatc --php samples/monster.fbs
|
./../flatc --php samples/monster.fbs
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.sh}
|
||||||
|
cd flatcc
|
||||||
|
mkdir -p build/tmp/samples/monster
|
||||||
|
bin/flatcc -a -o build/tmp/samples/monster samples/monster/monster.fbs
|
||||||
|
# or just
|
||||||
|
flatcc/samples/monster/build.sh
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
For a more complete guide to using the `flatc` compiler, pleaes read the
|
For a more complete guide to using the `flatc` compiler, please read the
|
||||||
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler)
|
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler)
|
||||||
section of the Programmer's Guide.
|
section of the Programmer's Guide.
|
||||||
|
|
||||||
@@ -359,58 +394,79 @@ The first step is to import/include the library, generated files, etc.
|
|||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
#include "monster_builder.h" // Generated by `flatcc`.
|
||||||
|
|
||||||
|
// Convenient namespace macro to manage long namespace prefix.
|
||||||
|
#undef ns
|
||||||
|
#define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x) // Specified in the schema.
|
||||||
|
|
||||||
|
// A helper to simplify creating vectors from C-arrays.
|
||||||
|
#define c_vec_len(V) (sizeof(V)/sizeof((V)[0]))
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
Now we are ready to start building some buffers. In order to start, we need
|
Now we are ready to start building some buffers. In order to start, we need
|
||||||
to create an instance of the `FlatBufferBuilder`, which will contain the buffer
|
to create an instance of the `FlatBufferBuilder`, which will contain the buffer
|
||||||
as it grows:
|
as it grows. You can pass an initial size of the buffer (here 1024 bytes),
|
||||||
|
which will grow automatically if needed:
|
||||||
|
|
||||||
<div class="language-cpp">
|
<div class="language-cpp">
|
||||||
~~~{.cpp}
|
~~~{.cpp}
|
||||||
// Create a `FlatBufferBuilder`, which will be used to create our
|
// Create a `FlatBufferBuilder`, which will be used to create our
|
||||||
// monsters' FlatBuffers.
|
// monsters' FlatBuffers.
|
||||||
flatbuffers::FlatBufferBuilder builder;
|
flatbuffers::FlatBufferBuilder builder(1024);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-java">
|
<div class="language-java">
|
||||||
~~~{.java}
|
~~~{.java}
|
||||||
// Create a `FlatBufferBuilder`, which will be used to create our
|
// Create a `FlatBufferBuilder`, which will be used to create our
|
||||||
// monsters' FlatBuffers.
|
// monsters' FlatBuffers.
|
||||||
FlatBufferBuilder builder = new FlatBufferBuilder(0);
|
FlatBufferBuilder builder = new FlatBufferBuilder(1024);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
// Create a `FlatBufferBuilder`, which will be used to create our
|
// Create a `FlatBufferBuilder`, which will be used to create our
|
||||||
// monsters' FlatBuffers.
|
// monsters' FlatBuffers.
|
||||||
var builder = new FlatBufferBuilder(1);
|
var builder = new FlatBufferBuilder(1024);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-go">
|
<div class="language-go">
|
||||||
~~~{.go}
|
~~~{.go}
|
||||||
// Create a `FlatBufferBuilder`, which will be used to create our
|
// Create a `FlatBufferBuilder`, which will be used to create our
|
||||||
// monsters' FlatBuffers.
|
// monsters' FlatBuffers.
|
||||||
builder := flatbuffers.NewBuilder(0)
|
builder := flatbuffers.NewBuilder(1024)
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-python">
|
<div class="language-python">
|
||||||
~~~{.py}
|
~~~{.py}
|
||||||
# Create a `FlatBufferBuilder`, which will be used to create our
|
# Create a `FlatBufferBuilder`, which will be used to create our
|
||||||
# monsters' FlatBuffers.
|
# monsters' FlatBuffers.
|
||||||
builder = flatbuffers.Builder(0)
|
builder = flatbuffers.Builder(1024)
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-javascript">
|
<div class="language-javascript">
|
||||||
~~~{.js}
|
~~~{.js}
|
||||||
// Create a `flatbuffer.Builder`, which will be used to create our
|
// Create a `flatbuffer.Builder`, which will be used to create our
|
||||||
// monsters' FlatBuffers.
|
// monsters' FlatBuffers.
|
||||||
var builder = new flatbuffers.Builder(1);
|
var builder = new flatbuffers.Builder(1024);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-php">
|
<div class="language-php">
|
||||||
~~~{.php}
|
~~~{.php}
|
||||||
// Create a `FlatBufferBuilder`, which will be used to create our
|
// Create a `FlatBufferBuilder`, which will be used to create our
|
||||||
// monsters' FlatBuffers.
|
// monsters' FlatBuffers.
|
||||||
$builder = new Google\FlatBuffers\FlatbufferBuilder(0);
|
$builder = new Google\FlatBuffers\FlatbufferBuilder(1024);
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
flatcc_builder_t builder, *B;
|
||||||
|
B = &builder;
|
||||||
|
// Initialize the builder object.
|
||||||
|
flatcc_builder_init(B);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -432,10 +488,10 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
|
|||||||
</div>
|
</div>
|
||||||
<div class="language-java">
|
<div class="language-java">
|
||||||
~~~{.java}
|
~~~{.java}
|
||||||
String weaponOneName = builder.createString("Sword")
|
int weaponOneName = builder.createString("Sword")
|
||||||
short weaponOneDamage = 3;
|
short weaponOneDamage = 3;
|
||||||
|
|
||||||
String weaponTwoName = builder.createString("Axe");
|
int weaponTwoName = builder.createString("Axe");
|
||||||
short weaponTwoDamage = 5;
|
short weaponTwoDamage = 5;
|
||||||
|
|
||||||
// Use the `createWeapon()` helper function to create the weapons, since we set every field.
|
// Use the `createWeapon()` helper function to create the weapons, since we set every field.
|
||||||
@@ -525,6 +581,18 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
|
|||||||
$weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps);
|
$weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
ns(Weapon_ref_t) weapon_one_name = flatbuffers_string_create_str(B, "Sword");
|
||||||
|
uint16_t weapon_one_damage = 3;
|
||||||
|
|
||||||
|
ns(Weapon_ref_t) weapon_two_name = flatbuffers_string_create_str(B, "Axe");
|
||||||
|
uint16_t weapon_two_damage = 5;
|
||||||
|
|
||||||
|
ns(Weapon_ref_t) sword = ns(Weapon_create(B, weapon_one_name, weapon_one_damage));
|
||||||
|
ns(Weapon_ref_t) axe = ns(Weapon_create(B, weapon_two_name, weapon_two_damage));
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
Now let's create our monster, the `orc`. For this `orc`, lets make him
|
Now let's create our monster, the `orc`. For this `orc`, lets make him
|
||||||
`red` with rage, positioned at `(1.0, 2.0, 3.0)`, and give him
|
`red` with rage, positioned at `(1.0, 2.0, 3.0)`, and give him
|
||||||
@@ -545,7 +613,7 @@ traversal. This is generally easy to do on any tree structures.
|
|||||||
|
|
||||||
// Create a `vector` representing the inventory of the Orc. Each number
|
// Create a `vector` representing the inventory of the Orc. Each number
|
||||||
// could correspond to an item that can be claimed after he is slain.
|
// could correspond to an item that can be claimed after he is slain.
|
||||||
unsigned char treasure = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
unsigned char treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
auto inventory = builder.CreateVector(treasure, 10);
|
auto inventory = builder.CreateVector(treasure, 10);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
@@ -627,6 +695,20 @@ traversal. This is generally easy to do on any tree structures.
|
|||||||
$inv = \MyGame\Sample\Monster::CreateInventoryVector($builder, $treasure);
|
$inv = \MyGame\Sample\Monster::CreateInventoryVector($builder, $treasure);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
// Serialize a name for our monster, called "Orc".
|
||||||
|
// The _str suffix indicates the source is an ascii-z string.
|
||||||
|
flatbuffers_string_ref_t name = flatbuffers_string_create_str(B, "Orc");
|
||||||
|
|
||||||
|
// Create a `vector` representing the inventory of the Orc. Each number
|
||||||
|
// could correspond to an item that can be claimed after he is slain.
|
||||||
|
uint8_t treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
|
flatbuffers_uint8_vec_ref_t inventory;
|
||||||
|
// `c_vec_len` is the convenience macro we defined earlier.
|
||||||
|
inventory = flatbuffers_uint8_vec_create(B, treasure, c_vec_len(treasure));
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
We serialized two built-in data types (`string` and `vector`) and captured
|
We serialized two built-in data types (`string` and `vector`) and captured
|
||||||
their return values. These values are offsets into the serialized data,
|
their return values. These values are offsets into the serialized data,
|
||||||
@@ -637,6 +719,10 @@ adding fields to our monster.
|
|||||||
other `vector`s), collect their offsets into a temporary data structure, and
|
other `vector`s), collect their offsets into a temporary data structure, and
|
||||||
then create an additional `vector` containing their offsets.*
|
then create an additional `vector` containing their offsets.*
|
||||||
|
|
||||||
|
If instead of creating a vector from an existing array you serialize elements
|
||||||
|
individually one by one, take care to note that this happens in reverse order,
|
||||||
|
as buffers are built back to front.
|
||||||
|
|
||||||
For example, take a look at the two `Weapon`s that we created earlier (`Sword`
|
For example, take a look at the two `Weapon`s that we created earlier (`Sword`
|
||||||
and `Axe`). These are both FlatBuffer `table`s, whose offsets we now store in
|
and `Axe`). These are both FlatBuffer `table`s, whose offsets we now store in
|
||||||
memory. Therefore we can create a FlatBuffer `vector` to contain these
|
memory. Therefore we can create a FlatBuffer `vector` to contain these
|
||||||
@@ -656,8 +742,8 @@ offsets.
|
|||||||
// Place the two weapons into an array, and pass it to the `createWeaponsVector()` method to
|
// Place the two weapons into an array, and pass it to the `createWeaponsVector()` method to
|
||||||
// create a FlatBuffer vector.
|
// create a FlatBuffer vector.
|
||||||
int[] weaps = new int[2];
|
int[] weaps = new int[2];
|
||||||
weaps[1] = sword;
|
weaps[0] = sword;
|
||||||
weaps[2] = axe;
|
weaps[1] = axe;
|
||||||
|
|
||||||
// Pass the `weaps` array into the `createWeaponsVector()` method to create a FlatBuffer vector.
|
// Pass the `weaps` array into the `createWeaponsVector()` method to create a FlatBuffer vector.
|
||||||
int weapons = Monster.createWeaponsVector(builder, weaps);
|
int weapons = Monster.createWeaponsVector(builder, weaps);
|
||||||
@@ -709,49 +795,85 @@ offsets.
|
|||||||
$weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps);
|
$weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
// We use the internal builder stack to implement a dynamic vector.
|
||||||
|
ns(Weapon_vec_start(B));
|
||||||
|
ns(Weapon_vec_push(B, sword));
|
||||||
|
ns(Weapon_vec_push(B, axe));
|
||||||
|
ns(Weapon_vec_ref_t) weapons = ns(Weapon_vec_end(B));
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
To create a `struct`, use the `Vec3` class/struct that was generated by `flatc`:
|
<div class="language-cpp">
|
||||||
|
<br>
|
||||||
|
Note there's additional convenience overloads of `CreateVector`, allowing you
|
||||||
|
to work with data that's not in a `std::vector`, or allowing you to generate
|
||||||
|
elements by calling a lambda. For the common case of `std::vector<std::string>`
|
||||||
|
there's also `CreateVectorOfStrings`.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Note that vectors of structs are serialized differently from tables, since
|
||||||
|
structs are stored in-line in the vector. For example, to create a vector
|
||||||
|
for the `path` field above:
|
||||||
|
|
||||||
<div class="language-cpp">
|
<div class="language-cpp">
|
||||||
~~~{.cpp}
|
~~~{.cpp}
|
||||||
// Create a `Vec3`, representing the Orc's position in 3-D space.
|
Vec3 points[] = { Vec3(1.0f, 2.0f, 3.0f), Vec3(4.0f, 5.0f, 6.0f) };
|
||||||
auto pos = Vec3(1.0f, 2.0f, 3.0f);
|
auto path = builder.CreateVectorOfStructs(points, 2);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-java">
|
<div class="language-java">
|
||||||
~~~{.java}
|
~~~{.java}
|
||||||
// Create a `Vec3`, representing the Orc's position in 3-D space.
|
Monster.startPathVector(fbb, 2);
|
||||||
int pos = Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f);
|
Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f);
|
||||||
|
Vec3.createVec3(builder, 4.0f, 5.0f, 6.0f);
|
||||||
|
int path = fbb.endVector();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
// Create a `Vec3`, representing the Orc's position in 3-D space.
|
Monster.StartPathVector(fbb, 2);
|
||||||
var pos = Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f);
|
Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f);
|
||||||
|
Vec3.CreateVec3(builder, 4.0f, 5.0f, 6.0f);
|
||||||
|
var path = fbb.EndVector();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-go">
|
<div class="language-go">
|
||||||
~~~{.go}
|
~~~{.go}
|
||||||
// Create a `Vec3`, representing the Orc's position in 3-D space.
|
sample.MonsterStartPathVector(builder, 2)
|
||||||
pos := sample.CreateVec3(builder, 1.0, 2.0, 3.0)
|
sample.CreateVec3(builder, 1.0, 2.0, 3.0)
|
||||||
|
sample.CreateVec3(builder, 4.0, 5.0, 6.0)
|
||||||
|
path := builder.EndVector(2)
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-python">
|
<div class="language-python">
|
||||||
~~~{.py}
|
~~~{.py}
|
||||||
# Create a `Vec3`, representing the Orc's position in 3-D space.
|
MyGame.Sample.Monster.MonsterStartPathVector(builder, 2)
|
||||||
pos = MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
|
MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
|
||||||
|
MyGame.Sample.Vec3.CreateVec3(builder, 4.0, 5.0, 6.0)
|
||||||
|
path = builder.EndVector(2)
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-javascript">
|
<div class="language-javascript">
|
||||||
~~~{.js}
|
~~~{.js}
|
||||||
// Create a `Vec3`, representing the Orc's position in 3-D space.
|
MyGame.Sample.Monster.startPathVector(builder, 2);
|
||||||
var pos = MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0);
|
MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0);
|
||||||
|
MyGame.Sample.Vec3.createVec3(builder, 4.0, 5.0, 6.0);
|
||||||
|
var path = builder.endVector();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-php">
|
<div class="language-php">
|
||||||
~~~{.js}
|
~~~{.php}
|
||||||
// Create a `Vec3`, representing the Orc's position in 3-D space.
|
\MyGame\Example\Monster::StartPathVector($builder, 2);
|
||||||
$pos = \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0);
|
\MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0);
|
||||||
|
\MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0);
|
||||||
|
$path = $builder->endVector();
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
// TBD
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -766,15 +888,16 @@ can serialize the monster itself:
|
|||||||
|
|
||||||
// Finally, create the monster using the `CreateMonster` helper function
|
// Finally, create the monster using the `CreateMonster` helper function
|
||||||
// to set all fields.
|
// to set all fields.
|
||||||
auto orc = CreateMonster(builder, &pos, mana, hp, name, inventory, Color_Red,
|
auto orc = CreateMonster(builder, Vec3(1.0f, 2.0f, 3.0f), mana, hp, name,
|
||||||
weapons, Equipment_Weapon, axe.Union());
|
inventory, Color_Red, weapons, Equipment_Weapon,
|
||||||
|
axe.Union(), path);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-java">
|
<div class="language-java">
|
||||||
~~~{.java}
|
~~~{.java}
|
||||||
// Create our monster using `startMonster()` and `endMonster()`.
|
// Create our monster using `startMonster()` and `endMonster()`.
|
||||||
Monster.startMonster(builder);
|
Monster.startMonster(builder);
|
||||||
Monster.addPos(builder, pos);
|
Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f));
|
||||||
Monster.addName(builder, name);
|
Monster.addName(builder, name);
|
||||||
Monster.addColor(builder, Color.Red);
|
Monster.addColor(builder, Color.Red);
|
||||||
Monster.addHp(builder, (short)300);
|
Monster.addHp(builder, (short)300);
|
||||||
@@ -782,6 +905,7 @@ can serialize the monster itself:
|
|||||||
Monster.addWeapons(builder, weapons);
|
Monster.addWeapons(builder, weapons);
|
||||||
Monster.addEquippedType(builder, Equipment.Weapon);
|
Monster.addEquippedType(builder, Equipment.Weapon);
|
||||||
Monster.addEquipped(builder, axe);
|
Monster.addEquipped(builder, axe);
|
||||||
|
Monster.addPath(builder, path);
|
||||||
int orc = Monster.endMonster(builder);
|
int orc = Monster.endMonster(builder);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
@@ -789,7 +913,7 @@ can serialize the monster itself:
|
|||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
// Create our monster using `StartMonster()` and `EndMonster()`.
|
// Create our monster using `StartMonster()` and `EndMonster()`.
|
||||||
Monster.StartMonster(builder);
|
Monster.StartMonster(builder);
|
||||||
Monster.AddPos(builder, pos);
|
Monster.AddPos(builder, Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f));
|
||||||
Monster.AddHp(builder, (short)300);
|
Monster.AddHp(builder, (short)300);
|
||||||
Monster.AddName(builder, name);
|
Monster.AddName(builder, name);
|
||||||
Monster.AddInventory(builder, inv);
|
Monster.AddInventory(builder, inv);
|
||||||
@@ -797,6 +921,7 @@ can serialize the monster itself:
|
|||||||
Monster.AddWeapons(builder, weapons);
|
Monster.AddWeapons(builder, weapons);
|
||||||
Monster.AddEquippedType(builder, Equipment.Weapon);
|
Monster.AddEquippedType(builder, Equipment.Weapon);
|
||||||
Monster.AddEquipped(builder, axe.Value); // Axe
|
Monster.AddEquipped(builder, axe.Value); // Axe
|
||||||
|
Monster.AddPath(builder, path);
|
||||||
var orc = Monster.EndMonster(builder);
|
var orc = Monster.EndMonster(builder);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
@@ -804,7 +929,7 @@ can serialize the monster itself:
|
|||||||
~~~{.go}
|
~~~{.go}
|
||||||
// Create our monster using `MonsterStart()` and `MonsterEnd()`.
|
// Create our monster using `MonsterStart()` and `MonsterEnd()`.
|
||||||
sample.MonsterStart(builder)
|
sample.MonsterStart(builder)
|
||||||
sample.MonsterAddPos(builder, pos)
|
sample.MonsterAddPos(builder, sample.CreateVec3(builder, 1.0, 2.0, 3.0))
|
||||||
sample.MonsterAddHp(builder, 300)
|
sample.MonsterAddHp(builder, 300)
|
||||||
sample.MonsterAddName(builder, name)
|
sample.MonsterAddName(builder, name)
|
||||||
sample.MonsterAddInventory(builder, inv)
|
sample.MonsterAddInventory(builder, inv)
|
||||||
@@ -812,6 +937,7 @@ can serialize the monster itself:
|
|||||||
sample.MonsterAddWeapons(builder, weapons)
|
sample.MonsterAddWeapons(builder, weapons)
|
||||||
sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon)
|
sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon)
|
||||||
sample.MonsterAddEquipped(builder, axe)
|
sample.MonsterAddEquipped(builder, axe)
|
||||||
|
sample.MonsterAddPath(builder, path)
|
||||||
orc := sample.MonsterEnd(builder)
|
orc := sample.MonsterEnd(builder)
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
@@ -819,7 +945,8 @@ can serialize the monster itself:
|
|||||||
~~~{.py}
|
~~~{.py}
|
||||||
# Create our monster by using `MonsterStart()` and `MonsterEnd()`.
|
# Create our monster by using `MonsterStart()` and `MonsterEnd()`.
|
||||||
MyGame.Sample.Monster.MonsterStart(builder)
|
MyGame.Sample.Monster.MonsterStart(builder)
|
||||||
MyGame.Sample.Monster.MonsterAddPos(builder, pos)
|
MyGame.Sample.Monster.MonsterAddPos(builder,
|
||||||
|
MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0))
|
||||||
MyGame.Sample.Monster.MonsterAddHp(builder, 300)
|
MyGame.Sample.Monster.MonsterAddHp(builder, 300)
|
||||||
MyGame.Sample.Monster.MonsterAddName(builder, name)
|
MyGame.Sample.Monster.MonsterAddName(builder, name)
|
||||||
MyGame.Sample.Monster.MonsterAddInventory(builder, inv)
|
MyGame.Sample.Monster.MonsterAddInventory(builder, inv)
|
||||||
@@ -829,6 +956,7 @@ can serialize the monster itself:
|
|||||||
MyGame.Sample.Monster.MonsterAddEquippedType(
|
MyGame.Sample.Monster.MonsterAddEquippedType(
|
||||||
builder, MyGame.Sample.Equipment.Equipment().Weapon)
|
builder, MyGame.Sample.Equipment.Equipment().Weapon)
|
||||||
MyGame.Sample.Monster.MonsterAddEquipped(builder, axe)
|
MyGame.Sample.Monster.MonsterAddEquipped(builder, axe)
|
||||||
|
MyGame.Sample.Monster.MonsterAddPath(builder, path)
|
||||||
orc = MyGame.Sample.Monster.MonsterEnd(builder)
|
orc = MyGame.Sample.Monster.MonsterEnd(builder)
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
@@ -836,7 +964,8 @@ can serialize the monster itself:
|
|||||||
~~~{.js}
|
~~~{.js}
|
||||||
// Create our monster by using `startMonster()` and `endMonster()`.
|
// Create our monster by using `startMonster()` and `endMonster()`.
|
||||||
MyGame.Sample.Monster.startMonster(builder);
|
MyGame.Sample.Monster.startMonster(builder);
|
||||||
MyGame.Sample.Monster.addPos(builder, pos);
|
MyGame.Sample.Monster.addPos(builder,
|
||||||
|
MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0));
|
||||||
MyGame.Sample.Monster.addHp(builder, 300);
|
MyGame.Sample.Monster.addHp(builder, 300);
|
||||||
MyGame.Sample.Monster.addColor(builder, MyGame.Sample.Color.Red)
|
MyGame.Sample.Monster.addColor(builder, MyGame.Sample.Color.Red)
|
||||||
MyGame.Sample.Monster.addName(builder, name);
|
MyGame.Sample.Monster.addName(builder, name);
|
||||||
@@ -844,6 +973,7 @@ can serialize the monster itself:
|
|||||||
MyGame.Sample.Monster.addWeapons(builder, weapons);
|
MyGame.Sample.Monster.addWeapons(builder, weapons);
|
||||||
MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon);
|
MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon);
|
||||||
MyGame.Sample.Monster.addEquipped(builder, axe);
|
MyGame.Sample.Monster.addEquipped(builder, axe);
|
||||||
|
MyGame.Sample.Monster.addPath(builder, path);
|
||||||
var orc = MyGame.Sample.Monster.endMonster(builder);
|
var orc = MyGame.Sample.Monster.endMonster(builder);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
@@ -851,7 +981,8 @@ can serialize the monster itself:
|
|||||||
~~~{.php}
|
~~~{.php}
|
||||||
// Create our monster by using `StartMonster()` and `EndMonster()`.
|
// Create our monster by using `StartMonster()` and `EndMonster()`.
|
||||||
\MyGame\Sample\Monster::StartMonster($builder);
|
\MyGame\Sample\Monster::StartMonster($builder);
|
||||||
\MyGame\Sample\Monster::AddPos($builder, $pos);
|
\MyGame\Sample\Monster::AddPos($builder,
|
||||||
|
\MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0));
|
||||||
\MyGame\Sample\Monster::AddHp($builder, 300);
|
\MyGame\Sample\Monster::AddHp($builder, 300);
|
||||||
\MyGame\Sample\Monster::AddName($builder, $name);
|
\MyGame\Sample\Monster::AddName($builder, $name);
|
||||||
\MyGame\Sample\Monster::AddInventory($builder, $inv);
|
\MyGame\Sample\Monster::AddInventory($builder, $inv);
|
||||||
@@ -859,19 +990,43 @@ can serialize the monster itself:
|
|||||||
\MyGame\Sample\Monster::AddWeapons($builder, $weapons);
|
\MyGame\Sample\Monster::AddWeapons($builder, $weapons);
|
||||||
\MyGame\Sample\Monster::AddEquippedType($builder, \MyGame\Sample\Equipment::Weapon);
|
\MyGame\Sample\Monster::AddEquippedType($builder, \MyGame\Sample\Equipment::Weapon);
|
||||||
\MyGame\Sample\Monster::AddEquipped($builder, $axe);
|
\MyGame\Sample\Monster::AddEquipped($builder, $axe);
|
||||||
|
\MyGame\Sample\Monster::AddPath($builder, $path);
|
||||||
$orc = \MyGame\Sample\Monster::EndMonster($builder);
|
$orc = \MyGame\Sample\Monster::EndMonster($builder);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
// Set his hit points to 300 and his mana to 150.
|
||||||
|
uint16_t hp = 300;
|
||||||
|
uint16_t mana = 150;
|
||||||
|
|
||||||
<div class="language-cpp">
|
// Define an equipment union. `create` calls in C has a single
|
||||||
<br>
|
// argument for unions where C++ has both a type and a data argument.
|
||||||
*Note: Since we passing `150` as the `mana` field, which happens to be the
|
ns(Equipment_union_ref_t) equipped = ns(Equipment_as_Weapon(axe));
|
||||||
|
ns(Vec3_t) pos = { 1.0f, 2.0f, 3.0f };
|
||||||
|
ns(Monster_create_as_root(B, &pos, mana, hp, name, inventory, ns(Color_Red),
|
||||||
|
weapons, equipped, path));
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Note how we create `Vec3` struct in-line in the table. Unlike tables, structs
|
||||||
|
are simple combinations of scalars that are always stored inline, just like
|
||||||
|
scalars themselves.
|
||||||
|
|
||||||
|
**Important**: Unlike structs, you should not nest tables or other objects,
|
||||||
|
which is why we created all the strings/vectors/tables that this monster refers
|
||||||
|
to before `start`. If you try to create any of them between `start` and `end`,
|
||||||
|
you will get an assert/exception/panic depending on your language.
|
||||||
|
|
||||||
|
*Note: Since we are passing `150` as the `mana` field, which happens to be the
|
||||||
default value, the field will not actually be written to the buffer, since the
|
default value, the field will not actually be written to the buffer, since the
|
||||||
default value will be returned on query anyway. This is a nice space savings,
|
default value will be returned on query anyway. This is a nice space savings,
|
||||||
especially if default values are common in your data. It also means that you do
|
especially if default values are common in your data. It also means that you do
|
||||||
not need to be worried of adding a lot of fields that are only used in a small
|
not need to be worried of adding a lot of fields that are only used in a small
|
||||||
number of instances, as it will not bloat the buffer if unused.*
|
number of instances, as it will not bloat the buffer if unused.*
|
||||||
<br><br>
|
|
||||||
|
<div class="language-cpp">
|
||||||
|
<br>
|
||||||
If you do not wish to set every field in a `table`, it may be more convenient to
|
If you do not wish to set every field in a `table`, it may be more convenient to
|
||||||
manually set each field of your monster, instead of calling `CreateMonster()`.
|
manually set each field of your monster, instead of calling `CreateMonster()`.
|
||||||
The following snippet is functionally equivalent to the above code, but provides
|
The following snippet is functionally equivalent to the above code, but provides
|
||||||
@@ -882,16 +1037,42 @@ a bit more flexibility.
|
|||||||
// manually.
|
// manually.
|
||||||
MonsterBuilder monster_builder(builder);
|
MonsterBuilder monster_builder(builder);
|
||||||
monster_builder.add_pos(&pos);
|
monster_builder.add_pos(&pos);
|
||||||
|
auto pos = Vec3(1.0f, 2.0f, 3.0f);
|
||||||
monster_builder.add_hp(hp);
|
monster_builder.add_hp(hp);
|
||||||
monster_builder.add_name(name);
|
monster_builder.add_name(name);
|
||||||
monster_builder.add_inventory(inventory);
|
monster_builder.add_inventory(inventory);
|
||||||
monster_builder.add_color(Color_Red);
|
monster_builder.add_color(Color_Red);
|
||||||
monster_builder.add_weapons(weapons);
|
monster_builder.add_weapons(weapons);
|
||||||
monster_builder.add_equipped_type(Equipment_Weapon);
|
monster_builder.add_equipped_type(Equipment_Weapon);
|
||||||
monster_builder.add_equpped(axe);
|
monster_builder.add_equpped(axe.Union());
|
||||||
auto orc = monster_builder.Finish();
|
auto orc = monster_builder.Finish();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
If you do not wish to set every field in a `table`, it may be more convenient to
|
||||||
|
manually set each field of your monster, instead of calling `create_monster_as_root()`.
|
||||||
|
The following snippet is functionally equivalent to the above code, but provides
|
||||||
|
a bit more flexibility.
|
||||||
|
<br>
|
||||||
|
~~~{.c}
|
||||||
|
// It is important to pair `start_as_root` with `end_as_root`.
|
||||||
|
ns(Monster_start_as_root(B));
|
||||||
|
ns(Monster_pos_create(B, 1.0f, 2.0f, 3.0f));
|
||||||
|
// or alternatively
|
||||||
|
//ns(Monster_pos_add(&pos);
|
||||||
|
|
||||||
|
ns(Monster_hp_add(B, hp));
|
||||||
|
// Notice that `Monser_name_add` adds a string reference unlike the
|
||||||
|
// add_str and add_strn variants.
|
||||||
|
ns(Monster_name_add(B, name));
|
||||||
|
ns(Monster_inventory_add(B, inventory));
|
||||||
|
ns(Monster_color_add(B, ns(Color_Red)));
|
||||||
|
ns(Monster_weapons_add(B, weapons));
|
||||||
|
ns(Monster_equipped_add(B, equipped));
|
||||||
|
// Complete the monster object and make it the buffer root object.
|
||||||
|
ns(Monster_end_as_root(B));
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
Before finishing the serialization, let's take a quick look at FlatBuffer
|
Before finishing the serialization, let's take a quick look at FlatBuffer
|
||||||
`union Equipped`. There are two parts to each FlatBuffer `union`. The first, is
|
`union Equipped`. There are two parts to each FlatBuffer `union`. The first, is
|
||||||
@@ -947,11 +1128,18 @@ Here is a repetition these lines, to help highlight them more clearly:
|
|||||||
\MyGame\Sample\Monster::AddEquipped($builder, $axe); // Union data
|
\MyGame\Sample\Monster::AddEquipped($builder, $axe); // Union data
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
// Add union type and data simultanously.
|
||||||
|
ns(Monster_equipped_Weapon_add(B, axe));
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
After you have created your buffer, you will have the offset to the root of the
|
After you have created your buffer, you will have the offset to the root of the
|
||||||
data in the `orc` variable, so you can finish the buffer by calling the
|
data in the `orc` variable, so you can finish the buffer by calling the
|
||||||
appropriate `finish` method.
|
appropriate `finish` method.
|
||||||
|
|
||||||
|
|
||||||
<div class="language-cpp">
|
<div class="language-cpp">
|
||||||
~~~{.cpp}
|
~~~{.cpp}
|
||||||
// Call `Finish()` to instruct the builder that this monster is complete.
|
// Call `Finish()` to instruct the builder that this monster is complete.
|
||||||
@@ -988,7 +1176,7 @@ appropriate `finish` method.
|
|||||||
<div class="language-javascript">
|
<div class="language-javascript">
|
||||||
~~~{.js}
|
~~~{.js}
|
||||||
// Call `finish()` to instruct the builder that this monster is complete.
|
// Call `finish()` to instruct the builder that this monster is complete.
|
||||||
builder.finish(orc); // You could also call `MyGame.Example.Monster.finishMonsterBuffer(builder,
|
builder.finish(orc); // You could also call `MyGame.Sample.Monster.finishMonsterBuffer(builder,
|
||||||
// orc);`.
|
// orc);`.
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
@@ -999,6 +1187,11 @@ appropriate `finish` method.
|
|||||||
// $builder, $orc);`.
|
// $builder, $orc);`.
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
// Because we used `Monster_create_as_root`, we do not need a `finish` call in C`.
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
The buffer is now ready to be stored somewhere, sent over the network, be
|
The buffer is now ready to be stored somewhere, sent over the network, be
|
||||||
compressed, or whatever you'd like to do with it. You can access the buffer
|
compressed, or whatever you'd like to do with it. You can access the buffer
|
||||||
@@ -1016,12 +1209,23 @@ like so:
|
|||||||
~~~{.java}
|
~~~{.java}
|
||||||
// This must be called after `finish()`.
|
// This must be called after `finish()`.
|
||||||
java.nio.ByteBuffer buf = builder.dataBuffer();
|
java.nio.ByteBuffer buf = builder.dataBuffer();
|
||||||
|
// The data in this ByteBuffer does NOT start at 0, but at buf.position().
|
||||||
|
// The number of bytes is buf.remaining().
|
||||||
|
|
||||||
|
// Alternatively this copies the above data out of the ByteBuffer for you:
|
||||||
|
bytes[] buf = builder.sizedByteArray();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
// This must be called after `Finish()`.
|
// This must be called after `Finish()`.
|
||||||
var buf = builder.DataBuffer; // Of type `FlatBuffers.ByteBuffer`.
|
var buf = builder.DataBuffer; // Of type `FlatBuffers.ByteBuffer`.
|
||||||
|
// The data in this ByteBuffer does NOT start at 0, but at buf.Position.
|
||||||
|
// The end of the data is marked by buf.Length, so the size is
|
||||||
|
// buf.Length - buf.Position.
|
||||||
|
|
||||||
|
// Alternatively this copies the above data out of the ByteBuffer for you:
|
||||||
|
bytes[] buf = builder.SizedByteArray();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-go">
|
<div class="language-go">
|
||||||
@@ -1039,15 +1243,46 @@ like so:
|
|||||||
<div class="language-javascript">
|
<div class="language-javascript">
|
||||||
~~~{.js}
|
~~~{.js}
|
||||||
// This must be called after `finish()`.
|
// This must be called after `finish()`.
|
||||||
var buf = builder.dataBuffer(); // Of type `flatbuffers.ByteBuffer`.
|
var buf = builder.asUint8Array(); // Of type `Uint8Array`.
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-php">
|
<div class="language-php">
|
||||||
~~~{.php}
|
~~~{.php}
|
||||||
// This must be called after `finish()`.
|
// This must be called after `finish()`.
|
||||||
$buf = $builder->dataBuffer(); // Of type `Google\FlatBuffers\ByteBuffer`
|
$buf = $builder->dataBuffer(); // Of type `Google\FlatBuffers\ByteBuffer`
|
||||||
|
// The data in this ByteBuffer does NOT start at 0, but at buf->getPosition().
|
||||||
|
// The end of the data is marked by buf->capacity(), so the size is
|
||||||
|
// buf->capacity() - buf->getPosition().
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
uint8_t *buf;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
// Allocate and extract a readable buffer from internal builder heap.
|
||||||
|
// The returned buffer must be deallocated using `free`.
|
||||||
|
// NOTE: Finalizing the buffer does NOT change the builder, it
|
||||||
|
// just creates a snapshot of the builder content.
|
||||||
|
buf = flatcc_builder_finalize_buffer(B, &size);
|
||||||
|
// use buf
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
// Optionally reset builder to reuse builder without deallocating
|
||||||
|
// internal stack and heap.
|
||||||
|
flatcc_builder_reset(B);
|
||||||
|
// build next buffer.
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// Cleanup.
|
||||||
|
flatcc_builder_clear(B);
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Now you can write the bytes to a file, send them over the network..
|
||||||
|
**Make sure your file mode (or tranfer protocol) is set to BINARY, not text.**
|
||||||
|
If you transfer a FlatBuffer in text mode, the buffer will be corrupted,
|
||||||
|
which will lead to hard to find problems when you read the buffer.
|
||||||
|
|
||||||
#### Reading Orc FlatBuffers
|
#### Reading Orc FlatBuffers
|
||||||
|
|
||||||
@@ -1055,7 +1290,7 @@ Now that we have successfully created an `Orc` FlatBuffer, the monster data can
|
|||||||
be saved, sent over a network, etc. Let's now adventure into the inverse, and
|
be saved, sent over a network, etc. Let's now adventure into the inverse, and
|
||||||
deserialize a FlatBuffer.
|
deserialize a FlatBuffer.
|
||||||
|
|
||||||
This seciton requires the same import/include, namespace, etc. requirements as
|
This section requires the same import/include, namespace, etc. requirements as
|
||||||
before:
|
before:
|
||||||
|
|
||||||
<div class="language-cpp">
|
<div class="language-cpp">
|
||||||
@@ -1134,98 +1369,109 @@ before:
|
|||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
// Only needed if we don't have `#include "monster_builder.h"`.
|
||||||
|
#include "monster_reader.h"
|
||||||
|
|
||||||
Then, assuming you have a variable containing to the bytes of data from disk,
|
#undef ns
|
||||||
network, etc., you can create a monster from this data:
|
#define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x) // Specified in the schema.
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Then, assuming you have a buffer of bytes received from disk,
|
||||||
|
network, etc., you can create start accessing the buffer like so:
|
||||||
|
|
||||||
|
**Again, make sure you read the bytes in BINARY mode, otherwise the code below
|
||||||
|
won't work**
|
||||||
|
|
||||||
<div class="language-cpp">
|
<div class="language-cpp">
|
||||||
~~~{.cpp}
|
~~~{.cpp}
|
||||||
// We can access the buffer we just made directly. Pretend this came over a
|
uint8_t *buffer_pointer = /* the data you just read */;
|
||||||
// network, was read off of disk, etc.
|
|
||||||
auto buffer_pointer = builder.GetBufferPointer();
|
|
||||||
|
|
||||||
// Deserialize the data from the buffer.
|
// Get a pointer to the root object inside the buffer.
|
||||||
auto monster = GetMonster(buffer_pointer);
|
auto monster = GetMonster(buffer_pointer);
|
||||||
|
|
||||||
// `monster` is of type`Monster *`, and points to somewhere inside the buffer.
|
// `monster` is of type `Monster *`.
|
||||||
|
|
||||||
// Note: root object pointers are NOT the same as `buffer_pointer`.
|
// Note: root object pointers are NOT the same as `buffer_pointer`.
|
||||||
|
// `GetMonster` is a convenience function that calls `GetRoot<Monster>`,
|
||||||
|
// the latter is also available for non-root types.
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-java">
|
<div class="language-java">
|
||||||
~~~{.java}
|
~~~{.java}
|
||||||
// We can access the buffer we just made directly. Pretend this came over a
|
byte[] bytes = /* the data you just read */
|
||||||
// network, was read off of disk, etc.
|
java.nio.ByteBuffer buf = java.nio.ByteBuffer.wrap(bytes);
|
||||||
java.nio.ByteBuffer buf = builder.dataBuffer();
|
|
||||||
|
|
||||||
// Deserialize the data from the buffer.
|
// Get an accessor to the root object inside the buffer.
|
||||||
Monster monster = Monster.getRootAsMonster(buf);
|
Monster monster = Monster.getRootAsMonster(buf);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
// We can access the buffer we just made directly. Pretend this came over a
|
byte[] bytes = /* the data you just read */
|
||||||
// network, was read off of disk, etc.
|
var buf = new ByteBuffer(bytes);
|
||||||
var buf = builder.DataBuffer;
|
|
||||||
|
|
||||||
// Deserialize the data from the buffer.
|
// Get an accessor to the root object inside the buffer.
|
||||||
var monster = Monster.GetRootAsMonster(buf);
|
var monster = Monster.GetRootAsMonster(buf);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-go">
|
<div class="language-go">
|
||||||
~~~{.go}
|
~~~{.go}
|
||||||
// We can access the buffer we just made directly. Pretend this came over a
|
var buf []byte = /* the data you just read */
|
||||||
// network, was read off of disk, etc.
|
|
||||||
buf := builder.FinishedBytes()
|
|
||||||
|
|
||||||
// Deserialize the data from the buffer.
|
// Get an accessor to the root object inside the buffer.
|
||||||
monster := sample.GetRootAsMonster(buf, 0)
|
monster := sample.GetRootAsMonster(buf, 0)
|
||||||
|
|
||||||
// Note: We use `0` for the offset here, since we got the data using the
|
// Note: We use `0` for the offset here, which is typical for most buffers
|
||||||
// `builder.FinishedBytes()` method. This simulates the data you would
|
// you would read. If you wanted to read from `builder.Bytes` directly, you
|
||||||
// store/receive in your FlatBuffer. If you wanted to read from the
|
// would need to pass in the offset of `builder.Head()`, as the builder
|
||||||
// `builder.Bytes` directly, you would need to pass in the offset of
|
// constructs the buffer backwards, so may not start at offset 0.
|
||||||
// `builder.Head()`, as the builder actually constructs the buffer backwards.
|
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-python">
|
<div class="language-python">
|
||||||
~~~{.py}
|
~~~{.py}
|
||||||
# We can access the buffer we just made directly. Pretend this came over a
|
buf = /* the data you just read, in an object of type "bytearray" */
|
||||||
# network, was read off of disk, etc.
|
|
||||||
buf = builder.Output()
|
|
||||||
|
|
||||||
# Deserialize the data from the buffer.
|
// Get an accessor to the root object inside the buffer.
|
||||||
monster = MyGame.Sample.Monster.Monster.GetRootAsMonster(buf, 0)
|
monster = MyGame.Sample.Monster.Monster.GetRootAsMonster(buf, 0)
|
||||||
|
|
||||||
# Note: We use `0` for the offset here, since we got the data using the
|
# Note: We use `0` for the offset here, which is typical for most buffers
|
||||||
# `builder.Output()` method. This simulates the data you would store/receive
|
# you would read. If you wanted to read from the `builder.Bytes` directly,
|
||||||
# in your FlatBuffer. If you wanted to read from the `builder.Bytes` directly,
|
|
||||||
# you would need to pass in the offset of `builder.Head()`, as the builder
|
# you would need to pass in the offset of `builder.Head()`, as the builder
|
||||||
# actually constructs the buffer backwards.
|
# constructs the buffer backwards, so may not start at offset 0.
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-javascript">
|
<div class="language-javascript">
|
||||||
~~~{.js}
|
~~~{.js}
|
||||||
// We can access the buffer we just made directly. Pretend this came over a
|
var bytes = /* the data you just read, in an object of type "Uint8Array" */
|
||||||
// network, was read off of disk, etc.
|
var buf = new flatbuffers.ByteBuffer(bytes);
|
||||||
var buf = builder.dataBuffer();
|
|
||||||
|
|
||||||
// Deserialize the data from the buffer.
|
// Get an accessor to the root object inside the buffer.
|
||||||
var monster = MyGame.Sample.Monster.getRootAsMonster(buf);
|
var monster = MyGame.Sample.Monster.getRootAsMonster(buf);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-php">
|
<div class="language-php">
|
||||||
~~~{.php}
|
~~~{.php}
|
||||||
// We can access the buffer we just made directly. Pretend this came over a
|
$bytes = /* the data you just read, in a string */
|
||||||
// network, was read off of disk, etc.
|
$buf = Google\FlatBuffers\ByteBuffer::wrap($bytes);
|
||||||
$buf = $builder->dataBuffer();
|
|
||||||
|
|
||||||
// Deserialize the data from the buffer.
|
// Get an accessor to the root object inside the buffer.
|
||||||
$monster = \MyGame\Sample\Monster::GetRootAsMonster($buf);
|
$monster = \MyGame\Sample\Monster::GetRootAsMonster($buf);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
// Note that we use the `table_t` suffix when reading a table object
|
||||||
|
// as opposed to the `ref_t` suffix used during the construction of
|
||||||
|
// the buffer.
|
||||||
|
ns(Monster_table_t) monster = ns(Monster_as_root(buffer));
|
||||||
|
|
||||||
If you look in the generated files from `flatc`, you will see it generated
|
// Note: root object pointers are NOT the same as the `buffer` pointer.
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
|
If you look in the generated files from the schema compiler, you will see it generated
|
||||||
accessors for all non-`deprecated` fields. For example:
|
accessors for all non-`deprecated` fields. For example:
|
||||||
|
|
||||||
<div class="language-cpp">
|
<div class="language-cpp">
|
||||||
@@ -1279,10 +1525,17 @@ accessors for all non-`deprecated` fields. For example:
|
|||||||
$name = monster->getName();
|
$name = monster->getName();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
uint16_t hp = ns(Monster_hp(monster));
|
||||||
|
uint16_t mana = ns(Monster_mana(monster));
|
||||||
|
flatbuffers_string_t name = ns(Monster_name(monster));
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
These should hold `300`, `150`, and `"Orc"` respectively.
|
These should hold `300`, `150`, and `"Orc"` respectively.
|
||||||
|
|
||||||
*Note: We never stored a value in `mp`, so we got the default value of `150`.*
|
*Note: The default value `150` wasn't stored in `mana`, but we are still able to retrieve it.*
|
||||||
|
|
||||||
To access sub-objects, in the case of our `pos`, which is a `Vec3`:
|
To access sub-objects, in the case of our `pos`, which is a `Vec3`:
|
||||||
|
|
||||||
@@ -1304,10 +1557,10 @@ To access sub-objects, in the case of our `pos`, which is a `Vec3`:
|
|||||||
</div>
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
var pos = monster.Pos
|
var pos = monster.Pos.Value;
|
||||||
var x = pos.X
|
var x = pos.X;
|
||||||
var y = pos.Y
|
var y = pos.Y;
|
||||||
var z = pos.Z
|
var z = pos.Z;
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-go">
|
<div class="language-go">
|
||||||
@@ -1348,10 +1601,18 @@ To access sub-objects, in the case of our `pos`, which is a `Vec3`:
|
|||||||
$z = $pos->getZ();
|
$z = $pos->getZ();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
ns(Vec3_struct_t) pos = ns(Monster_pos(monster));
|
||||||
|
float x = ns(Vec3_x(pos));
|
||||||
|
float y = ns(Vec3_y(pos));
|
||||||
|
float z = ns(Vec3_z(pos));
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
`x`, `y`, and `z` will contain `1.0`, `2.0`, and `3.0`, respectively.
|
`x`, `y`, and `z` will contain `1.0`, `2.0`, and `3.0`, respectively.
|
||||||
|
|
||||||
*Note: Had we not set `pos` during serialization, it would be `NULL`-value.*
|
*Note: Had we not set `pos` during serialization, it would be a `NULL`-value.*
|
||||||
|
|
||||||
Similarly, we can access elements of the inventory `vector` by indexing it. You
|
Similarly, we can access elements of the inventory `vector` by indexing it. You
|
||||||
can also iterate over the length of the array/vector representing the
|
can also iterate over the length of the array/vector representing the
|
||||||
@@ -1373,7 +1634,7 @@ FlatBuffers `vector`.
|
|||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
int invLength = monster.InventoryLength;
|
int invLength = monster.InventoryLength;
|
||||||
var thirdItem = monster.GetInventory(2);
|
var thirdItem = monster.Inventory(2);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-go">
|
<div class="language-go">
|
||||||
@@ -1400,6 +1661,14 @@ FlatBuffers `vector`.
|
|||||||
$third_item = $monster->getInventory(2);
|
$third_item = $monster->getInventory(2);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
// If `inv` hasn't been set, it will be null. It is valid get
|
||||||
|
// the length of null which will be 0, useful for iteration.
|
||||||
|
flatbuffers_uint8_vec_t inv = ns(Monster_inventory(monster));
|
||||||
|
size_t inv_len = flatbuffers_uint8_vec_len(inv);
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
For `vector`s of `table`s, you can access the elements like any other vector,
|
For `vector`s of `table`s, you can access the elements like any other vector,
|
||||||
except your need to handle the result as a FlatBuffer `table`:
|
except your need to handle the result as a FlatBuffer `table`:
|
||||||
@@ -1422,8 +1691,8 @@ except your need to handle the result as a FlatBuffer `table`:
|
|||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
int weaponsLength = monster.WeaponsLength;
|
int weaponsLength = monster.WeaponsLength;
|
||||||
var secondWeaponName = monster.GetWeapons(1).Name;
|
var secondWeaponName = monster.Weapons(1).Name;
|
||||||
var secondWeaponDamage = monster.GetWeapons(1).Damage;
|
var secondWeaponDamage = monster.Weapons(1).Damage;
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-go">
|
<div class="language-go">
|
||||||
@@ -1458,6 +1727,15 @@ except your need to handle the result as a FlatBuffer `table`:
|
|||||||
$second_weapon_damage = $monster->getWeapons(1)->getDamage();
|
$second_weapon_damage = $monster->getWeapons(1)->getDamage();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
ns(Weapon_vec_t) weapons = ns(Monster_weapons(monster));
|
||||||
|
size_t weapons_len = ns(Weapon_vec_len(weapons));
|
||||||
|
// We can use `const char *` instead of `flatbuffers_string_t`.
|
||||||
|
const char *second_weapon_name = ns(Weapon_name(ns(Weapon_vec_at(weapons, 1))));
|
||||||
|
uint16_t second_weapon_damage = ns(Weapon_damage(ns(Weapon_vec_at(weapons, 1))));
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
Last, we can access our `Equipped` FlatBuffer `union`. Just like when we created
|
Last, we can access our `Equipped` FlatBuffer `union`. Just like when we created
|
||||||
the `union`, we need to get both parts of the `union`: the type and the data.
|
the `union`, we need to get both parts of the `union`: the type and the data.
|
||||||
@@ -1496,8 +1774,7 @@ We can access the type to dynamically cast the data as needed (since the
|
|||||||
var unionType = monster.EquippedType;
|
var unionType = monster.EquippedType;
|
||||||
|
|
||||||
if (unionType == Equipment.Weapon) {
|
if (unionType == Equipment.Weapon) {
|
||||||
var weapon = (Weapon)monster.GetEquipped(new Weapon()); // Requires explicit cast
|
var weapon = monster.Equipped<Weapon>().Value;
|
||||||
// to `Weapon`.
|
|
||||||
|
|
||||||
var weaponName = weapon.Name; // "Axe"
|
var weaponName = weapon.Name; // "Axe"
|
||||||
var weaponDamage = weapon.Damage; // 5
|
var weaponDamage = weapon.Damage; // 5
|
||||||
@@ -1560,6 +1837,18 @@ We can access the type to dynamically cast the data as needed (since the
|
|||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
// Access union type field.
|
||||||
|
if (ns(Monster_equipped_type(monster)) == ns(Equipment_Weapon)) {
|
||||||
|
// Cast to appropriate type:
|
||||||
|
// C allows for silent void pointer assignment, so we need no explicit cast.
|
||||||
|
ns(Weapon_table_t) weapon = ns(Monster_equipped(monster));
|
||||||
|
const char *weapon_name = ns(Weapon_name(weapon)); // "Axe"
|
||||||
|
uint16_t weapon_damage = ns(Weapon_damage(weapon)); // 5
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
## Mutating FlatBuffers
|
## Mutating FlatBuffers
|
||||||
|
|
||||||
@@ -1624,6 +1913,12 @@ mutators like so:
|
|||||||
<API for mutating FlatBuffers is not yet supported in PHP.>
|
<API for mutating FlatBuffers is not yet supported in PHP.>
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
~~~{.c}
|
||||||
|
<API for in-place mutating FlatBuffers will not be supported in C
|
||||||
|
(except in-place vector sorting is possible).>
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
We use the somewhat verbose term `mutate` instead of `set` to indicate that this
|
We use the somewhat verbose term `mutate` instead of `set` to indicate that this
|
||||||
is a special use case, not to be confused with the default way of constructing
|
is a special use case, not to be confused with the default way of constructing
|
||||||
@@ -1644,6 +1939,9 @@ One way to solve this is to call `ForceDefaults` on a FlatBufferBuilder to
|
|||||||
force all fields you set to actually be written. This, of course, increases the
|
force all fields you set to actually be written. This, of course, increases the
|
||||||
size of the buffer somewhat, but this may be acceptable for a mutable buffer.
|
size of the buffer somewhat, but this may be acceptable for a mutable buffer.
|
||||||
|
|
||||||
|
If this is not sufficient, other ways of mutating FlatBuffers may be supported
|
||||||
|
in your language through an object based API (`--gen-object-api`) or reflection.
|
||||||
|
See the individual language documents for support.
|
||||||
|
|
||||||
## JSON with FlatBuffers
|
## JSON with FlatBuffers
|
||||||
|
|
||||||
@@ -1687,6 +1985,14 @@ FlatBuffer binary representation of the contents from our `.json` file.
|
|||||||
[Use in C++](@ref flatbuffers_guide_use_cpp) section of the Programmer's
|
[Use in C++](@ref flatbuffers_guide_use_cpp) section of the Programmer's
|
||||||
Guide for more information.*
|
Guide for more information.*
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
*Note: If you're working in C, the `flatcc --json` (not `flatc`)
|
||||||
|
compiler will generate schema specific high performance json parsers and
|
||||||
|
printers that you can compile and use at runtime. The `flatc` compiler (not
|
||||||
|
`flatcc`) on the other hand, is still useful for general offline json to
|
||||||
|
flatbuffer conversion from a given schema. There are no current plans
|
||||||
|
for `flatcc` to support this.*
|
||||||
|
</div>
|
||||||
|
|
||||||
## Advanced Features for Each Language
|
## Advanced Features for Each Language
|
||||||
|
|
||||||
@@ -1716,5 +2022,8 @@ For your chosen language, see:
|
|||||||
<div class="language-php">
|
<div class="language-php">
|
||||||
[Use in PHP](@ref flatbuffers_guide_use_php)
|
[Use in PHP](@ref flatbuffers_guide_use_php)
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-c">
|
||||||
|
[Use in C](@ref flatbuffers_guide_use_c)
|
||||||
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|||||||
0
docs/source/WhitePaper.md
Executable file → Normal file
0
docs/source/WhitePaper.md
Executable file → Normal file
11
docs/source/doxyfile
Executable file → Normal file
11
docs/source/doxyfile
Executable file → Normal file
@@ -750,6 +750,7 @@ INPUT = "FlatBuffers.md" \
|
|||||||
"Compiler.md" \
|
"Compiler.md" \
|
||||||
"Schemas.md" \
|
"Schemas.md" \
|
||||||
"CppUsage.md" \
|
"CppUsage.md" \
|
||||||
|
"CUsage.md" \
|
||||||
"GoUsage.md" \
|
"GoUsage.md" \
|
||||||
"JavaCsharpUsage.md" \
|
"JavaCsharpUsage.md" \
|
||||||
"JavaScriptUsage.md" \
|
"JavaScriptUsage.md" \
|
||||||
@@ -758,11 +759,13 @@ INPUT = "FlatBuffers.md" \
|
|||||||
"Support.md" \
|
"Support.md" \
|
||||||
"Benchmarks.md" \
|
"Benchmarks.md" \
|
||||||
"WhitePaper.md" \
|
"WhitePaper.md" \
|
||||||
|
"FlexBuffers.md" \
|
||||||
"Internals.md" \
|
"Internals.md" \
|
||||||
"Grammar.md" \
|
"Grammar.md" \
|
||||||
"CONTRIBUTING.md" \
|
"../../CONTRIBUTING.md" \
|
||||||
"Tutorial.md" \
|
"Tutorial.md" \
|
||||||
"GoApi.md" \
|
"GoApi.md" \
|
||||||
|
"gRPC/CppUsage.md" \
|
||||||
"groups" \
|
"groups" \
|
||||||
"../../java/com/google/flatbuffers" \
|
"../../java/com/google/flatbuffers" \
|
||||||
"../../python/flatbuffers/builder.py" \
|
"../../python/flatbuffers/builder.py" \
|
||||||
@@ -881,21 +884,21 @@ EXCLUDE_SYMBOLS =
|
|||||||
# that contain example code fragments that are included (see the \include
|
# that contain example code fragments that are included (see the \include
|
||||||
# command).
|
# command).
|
||||||
|
|
||||||
EXAMPLE_PATH = "GoApi_generated.txt"
|
EXAMPLE_PATH = "GoApi_generated.txt" "../../grpc/samples"
|
||||||
|
|
||||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
|
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
|
||||||
# *.h) to filter out the source-files in the directories. If left blank all
|
# *.h) to filter out the source-files in the directories. If left blank all
|
||||||
# files are included.
|
# files are included.
|
||||||
|
|
||||||
EXAMPLE_PATTERNS = *
|
EXAMPLE_PATTERNS = *.cpp *.h *.txt *.fbs
|
||||||
|
|
||||||
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
|
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
|
||||||
# searched for input files to be used with the \include or \dontinclude commands
|
# searched for input files to be used with the \include or \dontinclude commands
|
||||||
# irrespective of the value of the RECURSIVE tag.
|
# irrespective of the value of the RECURSIVE tag.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
EXAMPLE_RECURSIVE = NO
|
EXAMPLE_RECURSIVE = YES
|
||||||
|
|
||||||
# The IMAGE_PATH tag can be used to specify one or more files or directories
|
# The IMAGE_PATH tag can be used to specify one or more files or directories
|
||||||
# that contain images that are to be included in the documentation (see the
|
# that contain images that are to be included in the documentation (see the
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
title="Writing a schema"/>
|
title="Writing a schema"/>
|
||||||
<tab type="user" url="@ref flatbuffers_guide_use_cpp"
|
<tab type="user" url="@ref flatbuffers_guide_use_cpp"
|
||||||
title="Use in C++"/>
|
title="Use in C++"/>
|
||||||
|
<tab type="user" url="@ref flatbuffers_guide_use_c"
|
||||||
|
title="Use in C"/>
|
||||||
<tab type="user" url="@ref flatbuffers_guide_use_go"
|
<tab type="user" url="@ref flatbuffers_guide_use_go"
|
||||||
title="Use in Go"/>
|
title="Use in Go"/>
|
||||||
<tab type="user" url="@ref flatbuffers_guide_use_java_c-sharp"
|
<tab type="user" url="@ref flatbuffers_guide_use_java_c-sharp"
|
||||||
@@ -35,6 +37,12 @@
|
|||||||
title="Use in PHP"/>
|
title="Use in PHP"/>
|
||||||
<tab type="user" url="@ref flatbuffers_guide_use_python"
|
<tab type="user" url="@ref flatbuffers_guide_use_python"
|
||||||
title="Use in Python"/>
|
title="Use in Python"/>
|
||||||
|
<tab type="user" url="@ref flexbuffers"
|
||||||
|
title="Schema-less version"/>
|
||||||
|
<tab type="usergroup" url="" title="gRPC">
|
||||||
|
<tab type="user" url="@ref flatbuffers_grpc_guide_use_cpp"
|
||||||
|
title="Use in C++"/>
|
||||||
|
</tab>
|
||||||
</tab>
|
</tab>
|
||||||
<tab type="user" url="@ref flatbuffers_support"
|
<tab type="user" url="@ref flatbuffers_support"
|
||||||
title="Platform / Language / Feature support"/>
|
title="Platform / Language / Feature support"/>
|
||||||
@@ -45,7 +53,7 @@
|
|||||||
<tab type="user" url="@ref flatbuffers_internals"
|
<tab type="user" url="@ref flatbuffers_internals"
|
||||||
title="FlatBuffers internals"/>
|
title="FlatBuffers internals"/>
|
||||||
<tab type="user" url="@ref flatbuffers_grammar"
|
<tab type="user" url="@ref flatbuffers_grammar"
|
||||||
title="Grammar of the schema langauge"/>
|
title="Grammar of the schema language"/>
|
||||||
<tab type="usergroup" url="" title="API Reference">
|
<tab type="usergroup" url="" title="API Reference">
|
||||||
<tab type="modules" visible="yes" title="APIs" intro=""/>
|
<tab type="modules" visible="yes" title="APIs" intro=""/>
|
||||||
<tab type="classes" visible="yes" title="">
|
<tab type="classes" visible="yes" title="">
|
||||||
|
|||||||
29
docs/source/gRPC/CppUsage.md
Normal file
29
docs/source/gRPC/CppUsage.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
Use in C++ {#flatbuffers_grpc_guide_use_cpp}
|
||||||
|
==========
|
||||||
|
|
||||||
|
## Before you get started
|
||||||
|
|
||||||
|
Before diving into the FlatBuffers gRPC usage in C++, you should already be
|
||||||
|
familiar with the following:
|
||||||
|
|
||||||
|
- FlatBuffers as a serialization format
|
||||||
|
- [gRPC](http://www.grpc.io/docs/) usage
|
||||||
|
|
||||||
|
## Using the FlatBuffers gRPC C++ library
|
||||||
|
|
||||||
|
NOTE: The examples below are also in the `grpc/samples/greeter` directory.
|
||||||
|
|
||||||
|
We will illustrate usage with the following schema:
|
||||||
|
|
||||||
|
@include grpc/samples/greeter/greeter.fbs
|
||||||
|
|
||||||
|
When we run `flatc`, we pass in the `--grpc` option and generage an additional
|
||||||
|
`greeter.grpc.fb.h` and `greeter.grpc.fb.cc`.
|
||||||
|
|
||||||
|
Example server code looks like this:
|
||||||
|
|
||||||
|
@include grpc/samples/greeter/server.cpp
|
||||||
|
|
||||||
|
Example client code looks like this:
|
||||||
|
|
||||||
|
@include grpc/samples/greeter/client.cpp
|
||||||
@@ -110,6 +110,11 @@ func (b *Builder) WriteVtable() (n UOffsetT) {
|
|||||||
objectOffset := b.Offset()
|
objectOffset := b.Offset()
|
||||||
existingVtable := UOffsetT(0)
|
existingVtable := UOffsetT(0)
|
||||||
|
|
||||||
|
// Trim vtable of trailing zeroes.
|
||||||
|
i := len(b.vtable) - 1;
|
||||||
|
for ; i >= 0 && b.vtable[i] == 0; i-- {}
|
||||||
|
b.vtable = b.vtable[:i + 1];
|
||||||
|
|
||||||
// Search backwards through existing vtables, because similar vtables
|
// Search backwards through existing vtables, because similar vtables
|
||||||
// are likely to have been recently appended. See
|
// are likely to have been recently appended. See
|
||||||
// BenchmarkVtableDeduplication for a case in which this heuristic
|
// BenchmarkVtableDeduplication for a case in which this heuristic
|
||||||
|
|||||||
23
go/grpc.go
Normal file
23
go/grpc.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package flatbuffers
|
||||||
|
|
||||||
|
// Codec implements gRPC-go Codec which is used to encode and decode messages.
|
||||||
|
var Codec = "flatbuffers"
|
||||||
|
|
||||||
|
type FlatbuffersCodec struct{}
|
||||||
|
|
||||||
|
func (FlatbuffersCodec) Marshal(v interface{}) ([]byte, error) {
|
||||||
|
return v.(*Builder).FinishedBytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (FlatbuffersCodec) Unmarshal(data []byte, v interface{}) error {
|
||||||
|
v.(flatbuffersInit).Init(data, GetUOffsetT(data))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (FlatbuffersCodec) String() string {
|
||||||
|
return Codec
|
||||||
|
}
|
||||||
|
|
||||||
|
type flatbuffersInit interface {
|
||||||
|
Init(data []byte, i UOffsetT)
|
||||||
|
}
|
||||||
13
go/lib.go
Normal file
13
go/lib.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package flatbuffers
|
||||||
|
|
||||||
|
// FlatBuffer is the interface that represents a flatbuffer.
|
||||||
|
type FlatBuffer interface {
|
||||||
|
Table() Table
|
||||||
|
Init(buf []byte, i UOffsetT)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRootAs is a generic helper to initialize a FlatBuffer with the provided buffer bytes and its data offset.
|
||||||
|
func GetRootAs(buf []byte, offset UOffsetT, fb FlatBuffer) {
|
||||||
|
n := GetUOffsetT(buf[offset:])
|
||||||
|
fb.Init(buf, n+offset)
|
||||||
|
}
|
||||||
@@ -1,45 +1,55 @@
|
|||||||
package flatbuffers
|
package flatbuffers
|
||||||
|
|
||||||
import "unsafe"
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
const (
|
||||||
// See http://golang.org/ref/spec#Numeric_types
|
// See http://golang.org/ref/spec#Numeric_types
|
||||||
|
|
||||||
// SizeUint8 is the byte size of a uint8.
|
// SizeUint8 is the byte size of a uint8.
|
||||||
SizeUint8 = int(unsafe.Sizeof(uint8(0)))
|
SizeUint8 = 1
|
||||||
// SizeUint16 is the byte size of a uint16.
|
// SizeUint16 is the byte size of a uint16.
|
||||||
SizeUint16 = int(unsafe.Sizeof(uint16(0)))
|
SizeUint16 = 2
|
||||||
// SizeUint32 is the byte size of a uint32.
|
// SizeUint32 is the byte size of a uint32.
|
||||||
SizeUint32 = int(unsafe.Sizeof(uint32(0)))
|
SizeUint32 = 4
|
||||||
// SizeUint64 is the byte size of a uint64.
|
// SizeUint64 is the byte size of a uint64.
|
||||||
SizeUint64 = int(unsafe.Sizeof(uint64(0)))
|
SizeUint64 = 8
|
||||||
|
|
||||||
// SizeInt8 is the byte size of a int8.
|
// SizeInt8 is the byte size of a int8.
|
||||||
SizeInt8 = int(unsafe.Sizeof(int8(0)))
|
SizeInt8 = 1
|
||||||
// SizeInt16 is the byte size of a int16.
|
// SizeInt16 is the byte size of a int16.
|
||||||
SizeInt16 = int(unsafe.Sizeof(int16(0)))
|
SizeInt16 = 2
|
||||||
// SizeInt32 is the byte size of a int32.
|
// SizeInt32 is the byte size of a int32.
|
||||||
SizeInt32 = int(unsafe.Sizeof(int32(0)))
|
SizeInt32 = 4
|
||||||
// SizeInt64 is the byte size of a int64.
|
// SizeInt64 is the byte size of a int64.
|
||||||
SizeInt64 = int(unsafe.Sizeof(int64(0)))
|
SizeInt64 = 8
|
||||||
|
|
||||||
// SizeFloat32 is the byte size of a float32.
|
// SizeFloat32 is the byte size of a float32.
|
||||||
SizeFloat32 = int(unsafe.Sizeof(float32(0)))
|
SizeFloat32 = 4
|
||||||
// SizeFloat64 is the byte size of a float64.
|
// SizeFloat64 is the byte size of a float64.
|
||||||
SizeFloat64 = int(unsafe.Sizeof(float64(0)))
|
SizeFloat64 = 8
|
||||||
|
|
||||||
// SizeByte is the byte size of a byte.
|
// SizeByte is the byte size of a byte.
|
||||||
// The `byte` type is aliased (by Go definition) to uint8.
|
// The `byte` type is aliased (by Go definition) to uint8.
|
||||||
SizeByte = SizeUint8
|
SizeByte = 1
|
||||||
|
|
||||||
// SizeBool is the byte size of a bool.
|
// SizeBool is the byte size of a bool.
|
||||||
// The `bool` type is aliased (by flatbuffers convention) to uint8.
|
// The `bool` type is aliased (by flatbuffers convention) to uint8.
|
||||||
SizeBool = SizeUint8
|
SizeBool = 1
|
||||||
|
|
||||||
// SizeSOffsetT is the byte size of an SOffsetT.
|
// SizeSOffsetT is the byte size of an SOffsetT.
|
||||||
SizeSOffsetT = int(unsafe.Sizeof(SOffsetT(0)))
|
// The `SOffsetT` type is aliased (by flatbuffers convention) to int32.
|
||||||
|
SizeSOffsetT = 4
|
||||||
// SizeUOffsetT is the byte size of an UOffsetT.
|
// SizeUOffsetT is the byte size of an UOffsetT.
|
||||||
SizeUOffsetT = int(unsafe.Sizeof(UOffsetT(0)))
|
// The `UOffsetT` type is aliased (by flatbuffers convention) to uint32.
|
||||||
|
SizeUOffsetT = 4
|
||||||
// SizeVOffsetT is the byte size of an VOffsetT.
|
// SizeVOffsetT is the byte size of an VOffsetT.
|
||||||
SizeVOffsetT = int(unsafe.Sizeof(VOffsetT(0)))
|
// The `VOffsetT` type is aliased (by flatbuffers convention) to uint16.
|
||||||
|
SizeVOffsetT = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// byteSliceToString converts a []byte to string without a heap allocation.
|
||||||
|
func byteSliceToString(b []byte) string {
|
||||||
|
return *(*string)(unsafe.Pointer(&b))
|
||||||
|
}
|
||||||
215
go/table.go
215
go/table.go
@@ -10,7 +10,7 @@ type Table struct {
|
|||||||
|
|
||||||
// Offset provides access into the Table's vtable.
|
// Offset provides access into the Table's vtable.
|
||||||
//
|
//
|
||||||
// Deprecated fields are ignored by checking against the vtable's length.
|
// Fields which are deprecated are ignored by checking against the vtable's length.
|
||||||
func (t *Table) Offset(vtableOffset VOffsetT) VOffsetT {
|
func (t *Table) Offset(vtableOffset VOffsetT) VOffsetT {
|
||||||
vtable := UOffsetT(SOffsetT(t.Pos) - t.GetSOffsetT(t.Pos))
|
vtable := UOffsetT(SOffsetT(t.Pos) - t.GetSOffsetT(t.Pos))
|
||||||
if vtableOffset < t.GetVOffsetT(vtable) {
|
if vtableOffset < t.GetVOffsetT(vtable) {
|
||||||
@@ -26,7 +26,8 @@ func (t *Table) Indirect(off UOffsetT) UOffsetT {
|
|||||||
|
|
||||||
// String gets a string from data stored inside the flatbuffer.
|
// String gets a string from data stored inside the flatbuffer.
|
||||||
func (t *Table) String(off UOffsetT) string {
|
func (t *Table) String(off UOffsetT) string {
|
||||||
return string(t.ByteVector(off))
|
b := t.ByteVector(off)
|
||||||
|
return byteSliceToString(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ByteVector gets a byte slice from data stored inside the flatbuffer.
|
// ByteVector gets a byte slice from data stored inside the flatbuffer.
|
||||||
@@ -292,3 +293,213 @@ func (t *Table) GetVOffsetTSlot(slot VOffsetT, d VOffsetT) VOffsetT {
|
|||||||
}
|
}
|
||||||
return VOffsetT(off)
|
return VOffsetT(off)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MutateBool updates a bool at the given offset.
|
||||||
|
func (t *Table) MutateBool(off UOffsetT, n bool) bool {
|
||||||
|
WriteBool(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateByte updates a Byte at the given offset.
|
||||||
|
func (t *Table) MutateByte(off UOffsetT, n byte) bool {
|
||||||
|
WriteByte(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateUint8 updates a Uint8 at the given offset.
|
||||||
|
func (t *Table) MutateUint8(off UOffsetT, n uint8) bool {
|
||||||
|
WriteUint8(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateUint16 updates a Uint16 at the given offset.
|
||||||
|
func (t *Table) MutateUint16(off UOffsetT, n uint16) bool {
|
||||||
|
WriteUint16(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateUint32 updates a Uint32 at the given offset.
|
||||||
|
func (t *Table) MutateUint32(off UOffsetT, n uint32) bool {
|
||||||
|
WriteUint32(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateUint64 updates a Uint64 at the given offset.
|
||||||
|
func (t *Table) MutateUint64(off UOffsetT, n uint64) bool {
|
||||||
|
WriteUint64(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateInt8 updates a Int8 at the given offset.
|
||||||
|
func (t *Table) MutateInt8(off UOffsetT, n int8) bool {
|
||||||
|
WriteInt8(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateInt16 updates a Int16 at the given offset.
|
||||||
|
func (t *Table) MutateInt16(off UOffsetT, n int16) bool {
|
||||||
|
WriteInt16(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateInt32 updates a Int32 at the given offset.
|
||||||
|
func (t *Table) MutateInt32(off UOffsetT, n int32) bool {
|
||||||
|
WriteInt32(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateInt64 updates a Int64 at the given offset.
|
||||||
|
func (t *Table) MutateInt64(off UOffsetT, n int64) bool {
|
||||||
|
WriteInt64(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateFloat32 updates a Float32 at the given offset.
|
||||||
|
func (t *Table) MutateFloat32(off UOffsetT, n float32) bool {
|
||||||
|
WriteFloat32(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateFloat64 updates a Float64 at the given offset.
|
||||||
|
func (t *Table) MutateFloat64(off UOffsetT, n float64) bool {
|
||||||
|
WriteFloat64(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateUOffsetT updates a UOffsetT at the given offset.
|
||||||
|
func (t *Table) MutateUOffsetT(off UOffsetT, n UOffsetT) bool {
|
||||||
|
WriteUOffsetT(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateVOffsetT updates a VOffsetT at the given offset.
|
||||||
|
func (t *Table) MutateVOffsetT(off UOffsetT, n VOffsetT) bool {
|
||||||
|
WriteVOffsetT(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateSOffsetT updates a SOffsetT at the given offset.
|
||||||
|
func (t *Table) MutateSOffsetT(off UOffsetT, n SOffsetT) bool {
|
||||||
|
WriteSOffsetT(t.Bytes[off:], n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateBoolSlot updates the bool at given vtable location
|
||||||
|
func (t *Table) MutateBoolSlot(slot VOffsetT, n bool) bool {
|
||||||
|
if off := t.Offset(slot); off != 0 {
|
||||||
|
t.MutateBool(t.Pos+UOffsetT(off), n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateByteSlot updates the byte at given vtable location
|
||||||
|
func (t *Table) MutateByteSlot(slot VOffsetT, n byte) bool {
|
||||||
|
if off := t.Offset(slot); off != 0 {
|
||||||
|
t.MutateByte(t.Pos+UOffsetT(off), n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateInt8Slot updates the int8 at given vtable location
|
||||||
|
func (t *Table) MutateInt8Slot(slot VOffsetT, n int8) bool {
|
||||||
|
if off := t.Offset(slot); off != 0 {
|
||||||
|
t.MutateInt8(t.Pos+UOffsetT(off), n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateUint8Slot updates the uint8 at given vtable location
|
||||||
|
func (t *Table) MutateUint8Slot(slot VOffsetT, n uint8) bool {
|
||||||
|
if off := t.Offset(slot); off != 0 {
|
||||||
|
t.MutateUint8(t.Pos+UOffsetT(off), n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateInt16Slot updates the int16 at given vtable location
|
||||||
|
func (t *Table) MutateInt16Slot(slot VOffsetT, n int16) bool {
|
||||||
|
if off := t.Offset(slot); off != 0 {
|
||||||
|
t.MutateInt16(t.Pos+UOffsetT(off), n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateUint16Slot updates the uint16 at given vtable location
|
||||||
|
func (t *Table) MutateUint16Slot(slot VOffsetT, n uint16) bool {
|
||||||
|
if off := t.Offset(slot); off != 0 {
|
||||||
|
t.MutateUint16(t.Pos+UOffsetT(off), n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateInt32Slot updates the int32 at given vtable location
|
||||||
|
func (t *Table) MutateInt32Slot(slot VOffsetT, n int32) bool {
|
||||||
|
if off := t.Offset(slot); off != 0 {
|
||||||
|
t.MutateInt32(t.Pos+UOffsetT(off), n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateUint32Slot updates the uint32 at given vtable location
|
||||||
|
func (t *Table) MutateUint32Slot(slot VOffsetT, n uint32) bool {
|
||||||
|
if off := t.Offset(slot); off != 0 {
|
||||||
|
t.MutateUint32(t.Pos+UOffsetT(off), n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateInt64Slot updates the int64 at given vtable location
|
||||||
|
func (t *Table) MutateInt64Slot(slot VOffsetT, n int64) bool {
|
||||||
|
if off := t.Offset(slot); off != 0 {
|
||||||
|
t.MutateInt64(t.Pos+UOffsetT(off), n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateUint64Slot updates the uint64 at given vtable location
|
||||||
|
func (t *Table) MutateUint64Slot(slot VOffsetT, n uint64) bool {
|
||||||
|
if off := t.Offset(slot); off != 0 {
|
||||||
|
t.MutateUint64(t.Pos+UOffsetT(off), n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateFloat32Slot updates the float32 at given vtable location
|
||||||
|
func (t *Table) MutateFloat32Slot(slot VOffsetT, n float32) bool {
|
||||||
|
if off := t.Offset(slot); off != 0 {
|
||||||
|
t.MutateFloat32(t.Pos+UOffsetT(off), n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MutateFloat64Slot updates the float64 at given vtable location
|
||||||
|
func (t *Table) MutateFloat64Slot(slot VOffsetT, n float64) bool {
|
||||||
|
if off := t.Offset(slot); off != 0 {
|
||||||
|
t.MutateFloat64(t.Pos+UOffsetT(off), n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
11
grpc/README.md
Normal file
11
grpc/README.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
GRPC implementation and test
|
||||||
|
============================
|
||||||
|
|
||||||
|
NOTE: files in `src/` are shared with the GRPC project, and maintained there
|
||||||
|
(any changes should be submitted to GRPC instead). These files are copied
|
||||||
|
from GRPC, and work with both the Protobuf and FlatBuffers code generator.
|
||||||
|
|
||||||
|
`tests/` contains a GRPC specific test, you need to have built and installed
|
||||||
|
the GRPC libraries for this to compile. This test will build using the
|
||||||
|
`FLATBUFFERS_BUILD_GRPCTEST` option to the main FlatBuffers CMake project.
|
||||||
|
|
||||||
14
grpc/samples/greeter/Makefile
Normal file
14
grpc/samples/greeter/Makefile
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
CXXFLAGS ?= -I../../../include
|
||||||
|
LDFLAGS ?=
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: server client
|
||||||
|
|
||||||
|
greeter_generated.h: greeter.fbs
|
||||||
|
flatc --grpc --cpp $<
|
||||||
|
|
||||||
|
server: server.cpp greeter.grpc.fb.cc greeter_generated.h greeter.grpc.fb.h
|
||||||
|
g++ -std=c++11 -O2 $(CXXFLAGS) $(LDFLAGS) -lgpr -lgrpc -lgrpc++ server.cpp greeter.grpc.fb.cc -o $@
|
||||||
|
|
||||||
|
client: client.cpp greeter.grpc.fb.cc greeter_generated.h greeter.grpc.fb.h
|
||||||
|
g++ -std=c++11 -O2 $(CXXFLAGS) $(LDFLAGS) -lgpr -lgrpc -lgrpc++ client.cpp greeter.grpc.fb.cc -o $@
|
||||||
85
grpc/samples/greeter/client.cpp
Normal file
85
grpc/samples/greeter/client.cpp
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#include "greeter.grpc.fb.h"
|
||||||
|
#include "greeter_generated.h"
|
||||||
|
|
||||||
|
#include <grpc++/grpc++.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class GreeterClient {
|
||||||
|
public:
|
||||||
|
GreeterClient(std::shared_ptr<grpc::Channel> channel)
|
||||||
|
: stub_(Greeter::NewStub(channel)) {}
|
||||||
|
|
||||||
|
std::string SayHello(const std::string &name) {
|
||||||
|
flatbuffers::grpc::MessageBuilder mb;
|
||||||
|
auto name_offset = mb.CreateString(name);
|
||||||
|
auto request_offset = CreateHelloRequest(mb, name_offset);
|
||||||
|
mb.Finish(request_offset);
|
||||||
|
auto request_msg = mb.ReleaseMessage<HelloRequest>();
|
||||||
|
|
||||||
|
flatbuffers::grpc::Message<HelloReply> response_msg;
|
||||||
|
|
||||||
|
grpc::ClientContext context;
|
||||||
|
|
||||||
|
auto status = stub_->SayHello(&context, request_msg, &response_msg);
|
||||||
|
if (status.ok()) {
|
||||||
|
const HelloReply *response = response_msg.GetRoot();
|
||||||
|
return response->message()->str();
|
||||||
|
} else {
|
||||||
|
std::cerr << status.error_code() << ": " << status.error_message()
|
||||||
|
<< std::endl;
|
||||||
|
return "RPC failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SayManyHellos(const std::string &name, int num_greetings,
|
||||||
|
std::function<void(const std::string &)> callback) {
|
||||||
|
flatbuffers::grpc::MessageBuilder mb;
|
||||||
|
auto name_offset = mb.CreateString(name);
|
||||||
|
auto request_offset =
|
||||||
|
CreateManyHellosRequest(mb, name_offset, num_greetings);
|
||||||
|
mb.Finish(request_offset);
|
||||||
|
auto request_msg = mb.ReleaseMessage<ManyHellosRequest>();
|
||||||
|
|
||||||
|
flatbuffers::grpc::Message<HelloReply> response_msg;
|
||||||
|
|
||||||
|
grpc::ClientContext context;
|
||||||
|
|
||||||
|
auto stream = stub_->SayManyHellos(&context, request_msg);
|
||||||
|
while (stream->Read(&response_msg)) {
|
||||||
|
const HelloReply *response = response_msg.GetRoot();
|
||||||
|
callback(response->message()->str());
|
||||||
|
}
|
||||||
|
auto status = stream->Finish();
|
||||||
|
if (!status.ok()) {
|
||||||
|
std::cerr << status.error_code() << ": " << status.error_message()
|
||||||
|
<< std::endl;
|
||||||
|
callback("RPC failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Greeter::Stub> stub_;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
std::string server_address("localhost:50051");
|
||||||
|
|
||||||
|
auto channel =
|
||||||
|
grpc::CreateChannel(server_address, grpc::InsecureChannelCredentials());
|
||||||
|
GreeterClient greeter(channel);
|
||||||
|
|
||||||
|
std::string name("world");
|
||||||
|
|
||||||
|
std::string message = greeter.SayHello(name);
|
||||||
|
std::cerr << "Greeter received: " << message << std::endl;
|
||||||
|
|
||||||
|
int num_greetings = 10;
|
||||||
|
greeter.SayManyHellos(name, num_greetings, [](const std::string &message) {
|
||||||
|
std::cerr << "Greeter received: " << message << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
17
grpc/samples/greeter/greeter.fbs
Normal file
17
grpc/samples/greeter/greeter.fbs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
table HelloReply {
|
||||||
|
message:string;
|
||||||
|
}
|
||||||
|
|
||||||
|
table HelloRequest {
|
||||||
|
name:string;
|
||||||
|
}
|
||||||
|
|
||||||
|
table ManyHellosRequest {
|
||||||
|
name:string;
|
||||||
|
num_greetings:int;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc_service Greeter {
|
||||||
|
SayHello(HelloRequest):HelloReply;
|
||||||
|
SayManyHellos(ManyHellosRequest):HelloReply (streaming: "server");
|
||||||
|
}
|
||||||
80
grpc/samples/greeter/server.cpp
Normal file
80
grpc/samples/greeter/server.cpp
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#include "greeter.grpc.fb.h"
|
||||||
|
#include "greeter_generated.h"
|
||||||
|
|
||||||
|
#include <grpc++/grpc++.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class GreeterServiceImpl final : public Greeter::Service {
|
||||||
|
virtual grpc::Status SayHello(
|
||||||
|
grpc::ServerContext *context,
|
||||||
|
const flatbuffers::grpc::Message<HelloRequest> *request_msg,
|
||||||
|
flatbuffers::grpc::Message<HelloReply> *response_msg) override {
|
||||||
|
// flatbuffers::grpc::MessageBuilder mb_;
|
||||||
|
// We call GetRoot to "parse" the message. Verification is already
|
||||||
|
// performed by default. See the notes below for more details.
|
||||||
|
const HelloRequest *request = request_msg->GetRoot();
|
||||||
|
|
||||||
|
// Fields are retrieved as usual with FlatBuffers
|
||||||
|
const std::string &name = request->name()->str();
|
||||||
|
|
||||||
|
// `flatbuffers::grpc::MessageBuilder` is a `FlatBufferBuilder` with a
|
||||||
|
// special allocator for efficient gRPC buffer transfer, but otherwise
|
||||||
|
// usage is the same as usual.
|
||||||
|
auto msg_offset = mb_.CreateString("Hello, " + name);
|
||||||
|
auto hello_offset = CreateHelloReply(mb_, msg_offset);
|
||||||
|
mb_.Finish(hello_offset);
|
||||||
|
|
||||||
|
// The `ReleaseMessage<T>()` function detaches the message from the
|
||||||
|
// builder, so we can transfer the resopnse to gRPC while simultaneously
|
||||||
|
// detaching that memory buffer from the builer.
|
||||||
|
*response_msg = mb_.ReleaseMessage<HelloReply>();
|
||||||
|
assert(response_msg->Verify());
|
||||||
|
|
||||||
|
// Return an OK status.
|
||||||
|
return grpc::Status::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual grpc::Status SayManyHellos(
|
||||||
|
grpc::ServerContext *context,
|
||||||
|
const flatbuffers::grpc::Message<ManyHellosRequest> *request_msg,
|
||||||
|
grpc::ServerWriter<flatbuffers::grpc::Message<HelloReply>> *writer)
|
||||||
|
override {
|
||||||
|
// The streaming usage below is simply a combination of standard gRPC
|
||||||
|
// streaming with the FlatBuffers usage shown above.
|
||||||
|
const ManyHellosRequest *request = request_msg->GetRoot();
|
||||||
|
const std::string &name = request->name()->str();
|
||||||
|
int num_greetings = request->num_greetings();
|
||||||
|
|
||||||
|
for (int i = 0; i < num_greetings; i++) {
|
||||||
|
auto msg_offset = mb_.CreateString("Many hellos, " + name);
|
||||||
|
auto hello_offset = CreateHelloReply(mb_, msg_offset);
|
||||||
|
mb_.Finish(hello_offset);
|
||||||
|
writer->Write(mb_.ReleaseMessage<HelloReply>());
|
||||||
|
}
|
||||||
|
|
||||||
|
return grpc::Status::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::grpc::MessageBuilder mb_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RunServer() {
|
||||||
|
std::string server_address("0.0.0.0:50051");
|
||||||
|
GreeterServiceImpl service;
|
||||||
|
|
||||||
|
grpc::ServerBuilder builder;
|
||||||
|
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
|
||||||
|
builder.RegisterService(&service);
|
||||||
|
std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
|
||||||
|
std::cerr << "Server listening on " << server_address << std::endl;
|
||||||
|
|
||||||
|
server->Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char *argv[]) {
|
||||||
|
RunServer();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
40
grpc/src/compiler/config.h
Normal file
40
grpc/src/compiler/config.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2015, Google Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of Google Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRC_COMPILER_CONFIG_H
|
||||||
|
#define SRC_COMPILER_CONFIG_H
|
||||||
|
|
||||||
|
// This file is here only because schema_interface.h, which is copied from gRPC,
|
||||||
|
// includes it. There is nothing for Flatbuffers to configure.
|
||||||
|
|
||||||
|
#endif // SRC_COMPILER_CONFIG_H
|
||||||
1593
grpc/src/compiler/cpp_generator.cc
Normal file
1593
grpc/src/compiler/cpp_generator.cc
Normal file
File diff suppressed because it is too large
Load Diff
138
grpc/src/compiler/cpp_generator.h
Normal file
138
grpc/src/compiler/cpp_generator.h
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2015, Google Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of Google Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
|
||||||
|
#define GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
|
||||||
|
|
||||||
|
// cpp_generator.h/.cc do not directly depend on GRPC/ProtoBuf, such that they
|
||||||
|
// can be used to generate code for other serialization systems, such as
|
||||||
|
// FlatBuffers.
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "src/compiler/config.h"
|
||||||
|
#include "src/compiler/schema_interface.h"
|
||||||
|
|
||||||
|
#ifndef GRPC_CUSTOM_STRING
|
||||||
|
#include <string>
|
||||||
|
#define GRPC_CUSTOM_STRING std::string
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace grpc {
|
||||||
|
|
||||||
|
typedef GRPC_CUSTOM_STRING string;
|
||||||
|
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
namespace grpc_cpp_generator {
|
||||||
|
|
||||||
|
// Contains all the parameters that are parsed from the command line.
|
||||||
|
struct Parameters {
|
||||||
|
// Puts the service into a namespace
|
||||||
|
grpc::string services_namespace;
|
||||||
|
// Use system includes (<>) or local includes ("")
|
||||||
|
bool use_system_headers;
|
||||||
|
// Prefix to any grpc include
|
||||||
|
grpc::string grpc_search_path;
|
||||||
|
// Generate GMOCK code to facilitate unit testing.
|
||||||
|
bool generate_mock_code;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return the prologue of the generated header file.
|
||||||
|
grpc::string GetHeaderPrologue(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the includes needed for generated header file.
|
||||||
|
grpc::string GetHeaderIncludes(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the includes needed for generated source file.
|
||||||
|
grpc::string GetSourceIncludes(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the epilogue of the generated header file.
|
||||||
|
grpc::string GetHeaderEpilogue(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the prologue of the generated source file.
|
||||||
|
grpc::string GetSourcePrologue(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the services for generated header file.
|
||||||
|
grpc::string GetHeaderServices(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the services for generated source file.
|
||||||
|
grpc::string GetSourceServices(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the epilogue of the generated source file.
|
||||||
|
grpc::string GetSourceEpilogue(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the prologue of the generated mock file.
|
||||||
|
grpc::string GetMockPrologue(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the includes needed for generated mock file.
|
||||||
|
grpc::string GetMockIncludes(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the services for generated mock file.
|
||||||
|
grpc::string GetMockServices(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the epilogue of generated mock file.
|
||||||
|
grpc::string GetMockEpilogue(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the prologue of the generated mock file.
|
||||||
|
grpc::string GetMockPrologue(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the includes needed for generated mock file.
|
||||||
|
grpc::string GetMockIncludes(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the services for generated mock file.
|
||||||
|
grpc::string GetMockServices(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
// Return the epilogue of generated mock file.
|
||||||
|
grpc::string GetMockEpilogue(grpc_generator::File *file,
|
||||||
|
const Parameters ¶ms);
|
||||||
|
|
||||||
|
} // namespace grpc_cpp_generator
|
||||||
|
|
||||||
|
#endif // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
|
||||||
445
grpc/src/compiler/go_generator.cc
Normal file
445
grpc/src/compiler/go_generator.cc
Normal file
@@ -0,0 +1,445 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2015, Google Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation AN/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of Google Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <cctype>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "src/compiler/go_generator.h"
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
grpc::string as_string(T x) {
|
||||||
|
std::ostringstream out;
|
||||||
|
out << x;
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool ClientOnlyStreaming(const grpc_generator::Method *method) {
|
||||||
|
return method->ClientStreaming() && !method->ServerStreaming();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool ServerOnlyStreaming(const grpc_generator::Method *method) {
|
||||||
|
return !method->ClientStreaming() && method->ServerStreaming();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace grpc_go_generator {
|
||||||
|
|
||||||
|
// Returns string with first letter to lowerCase
|
||||||
|
grpc::string unexportName(grpc::string s) {
|
||||||
|
if (s.empty())
|
||||||
|
return s;
|
||||||
|
s[0] = static_cast<char>(std::tolower(s[0]));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns string with first letter to uppercase
|
||||||
|
grpc::string exportName(grpc::string s) {
|
||||||
|
if (s.empty())
|
||||||
|
return s;
|
||||||
|
s[0] = static_cast<char>(std::toupper(s[0]));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates imports for the service
|
||||||
|
void GenerateImports(grpc_generator::File *file, grpc_generator::Printer *printer,
|
||||||
|
std::map<grpc::string, grpc::string> vars) {
|
||||||
|
vars["filename"] = file->filename();
|
||||||
|
printer->Print("//Generated by gRPC Go plugin\n");
|
||||||
|
printer->Print("//If you make any local changes, they will be lost\n");
|
||||||
|
printer->Print(vars, "//source: $filename$\n\n");
|
||||||
|
printer->Print(vars, "package $Package$\n\n");
|
||||||
|
if (file->additional_headers() != "") {
|
||||||
|
printer->Print(file->additional_headers().c_str());
|
||||||
|
printer->Print("\n\n");
|
||||||
|
}
|
||||||
|
printer->Print("import (\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(vars, "$context$ \"golang.org/x/net/context\"\n");
|
||||||
|
printer->Print(vars, "$grpc$ \"google.golang.org/grpc\"\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print(")\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates Server method signature source
|
||||||
|
void GenerateServerMethodSignature(const grpc_generator::Method *method, grpc_generator::Printer *printer,
|
||||||
|
std::map<grpc::string, grpc::string> vars) {
|
||||||
|
vars["Method"] = exportName(method->name());
|
||||||
|
vars["Request"] = method->get_input_type_name();
|
||||||
|
vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
|
||||||
|
if (method->NoStreaming()) {
|
||||||
|
printer->Print(vars, "$Method$($context$.Context, *$Request$) (*$Response$, error)");
|
||||||
|
} else if (ServerOnlyStreaming(method)) {
|
||||||
|
printer->Print(vars, "$Method$(*$Request$, $Service$_$Method$Server) error");
|
||||||
|
} else {
|
||||||
|
printer->Print(vars, "$Method$($Service$_$Method$Server) error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateServerMethod(const grpc_generator::Method *method, grpc_generator::Printer *printer,
|
||||||
|
std::map<grpc::string, grpc::string> vars) {
|
||||||
|
vars["Method"] = exportName(method->name());
|
||||||
|
vars["Request"] = method->get_input_type_name();
|
||||||
|
vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
|
||||||
|
vars["FullMethodName"] = "/" + vars["Package"] + "." + vars["Service"] + "/" + vars["Method"];
|
||||||
|
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
||||||
|
if (method->NoStreaming()) {
|
||||||
|
printer->Print(vars, "func $Handler$(srv interface{}, ctx $context$.Context,\n\tdec func(interface{}) error, interceptor $grpc$.UnaryServerInterceptor) (interface{}, error) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(vars, "in := new($Request$)\n");
|
||||||
|
printer->Print("if err := dec(in); err != nil { return nil, err }\n");
|
||||||
|
printer->Print(vars, "if interceptor == nil { return srv.($Service$Server).$Method$(ctx, in) }\n");
|
||||||
|
printer->Print(vars, "info := &$grpc$.UnaryServerInfo{\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print("Server: srv,\n");
|
||||||
|
printer->Print(vars, "FullMethod: \"$FullMethodName$\",\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
printer->Print(vars, "handler := func(ctx $context$.Context, req interface{}) (interface{}, error) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(vars, "return srv.($Service$Server).$Method$(ctx, req.(* $Request$))\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n");
|
||||||
|
printer->Print("return interceptor(ctx, in, info, handler)\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Server";
|
||||||
|
printer->Print(vars, "func $Handler$(srv interface{}, stream $grpc$.ServerStream) error {\n");
|
||||||
|
printer->Indent();
|
||||||
|
if (ServerOnlyStreaming(method)) {
|
||||||
|
printer->Print(vars, "m := new($Request$)\n");
|
||||||
|
printer->Print(vars, "if err := stream.RecvMsg(m); err != nil { return err }\n");
|
||||||
|
printer->Print(vars, "return srv.($Service$Server).$Method$(m, &$StreamType${stream})\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(vars, "return srv.($Service$Server).$Method$(&$StreamType${stream})\n");
|
||||||
|
}
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
|
||||||
|
bool genSend = method->BidiStreaming() || ServerOnlyStreaming(method);
|
||||||
|
bool genRecv = method->BidiStreaming() || ClientOnlyStreaming(method);
|
||||||
|
bool genSendAndClose = ClientOnlyStreaming(method);
|
||||||
|
|
||||||
|
printer->Print(vars, "type $Service$_$Method$Server interface { \n");
|
||||||
|
printer->Indent();
|
||||||
|
if (genSend) {
|
||||||
|
printer->Print(vars, "Send(* $Response$) error\n");
|
||||||
|
}
|
||||||
|
if (genRecv) {
|
||||||
|
printer->Print(vars, "Recv() (* $Request$, error)\n");
|
||||||
|
}
|
||||||
|
if (genSendAndClose) {
|
||||||
|
printer->Print(vars, "SendAndClose(* $Response$) error\n");
|
||||||
|
}
|
||||||
|
printer->Print(vars, "$grpc$.ServerStream\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
|
||||||
|
printer->Print(vars, "type $StreamType$ struct {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(vars, "$grpc$.ServerStream\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
|
||||||
|
if (genSend) {
|
||||||
|
printer->Print(vars, "func (x *$StreamType$) Send(m *$Response$) error {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print("return x.ServerStream.SendMsg(m)\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
}
|
||||||
|
if (genRecv) {
|
||||||
|
printer->Print(vars, "func (x *$StreamType$) Recv() (*$Request$, error) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(vars, "m := new($Request$)\n");
|
||||||
|
printer->Print("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }\n");
|
||||||
|
printer->Print("return m, nil\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
}
|
||||||
|
if (genSendAndClose) {
|
||||||
|
printer->Print(vars, "func (x *$StreamType$) SendAndClose(m *$Response$) error {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print("return x.ServerStream.SendMsg(m)\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates Client method signature source
|
||||||
|
void GenerateClientMethodSignature(const grpc_generator::Method *method, grpc_generator::Printer *printer,
|
||||||
|
std::map<grpc::string, grpc::string> vars) {
|
||||||
|
vars["Method"] = exportName(method->name());
|
||||||
|
vars["Request"] = ", in *" + ((vars["CustomMethodIO"] == "") ? method->get_input_type_name() : vars["CustomMethodIO"]);
|
||||||
|
if (ClientOnlyStreaming(method) || method->BidiStreaming()) {
|
||||||
|
vars["Request"] = "";
|
||||||
|
}
|
||||||
|
vars["Response"] = "* " + method->get_output_type_name();
|
||||||
|
if (ClientOnlyStreaming(method) || method->BidiStreaming() || ServerOnlyStreaming(method)) {
|
||||||
|
vars["Response"] = vars["Service"] + "_" + vars["Method"] + "Client" ;
|
||||||
|
}
|
||||||
|
printer->Print(vars, "$Method$(ctx $context$.Context$Request$, \n\topts... $grpc$.CallOption) ($Response$, error)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates Client method source
|
||||||
|
void GenerateClientMethod(const grpc_generator::Method *method, grpc_generator::Printer *printer,
|
||||||
|
std::map<grpc::string, grpc::string> vars) {
|
||||||
|
printer->Print(vars, "func (c *$ServiceUnexported$Client) ");
|
||||||
|
GenerateClientMethodSignature(method, printer, vars);
|
||||||
|
printer->Print(" {\n");
|
||||||
|
printer->Indent();
|
||||||
|
vars["Method"] = exportName(method->name());
|
||||||
|
vars["Request"] = (vars["CustomMethodIO"] == "") ? method->get_input_type_name() : vars["CustomMethodIO"];
|
||||||
|
vars["Response"] = method->get_output_type_name();
|
||||||
|
vars["FullMethodName"] = "/" + vars["Package"] + "." + vars["Service"] + "/" + vars["Method"];
|
||||||
|
if (method->NoStreaming()) {
|
||||||
|
printer->Print(vars, "out := new($Response$)\n");
|
||||||
|
printer->Print(vars, "err := $grpc$.Invoke(ctx, \"$FullMethodName$\", in, out, c.cc, opts...)\n");
|
||||||
|
printer->Print("if err != nil { return nil, err }\n");
|
||||||
|
printer->Print("return out, nil\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Client";
|
||||||
|
printer->Print(vars, "stream, err := $grpc$.NewClientStream(ctx, &$MethodDesc$, c.cc, \"$FullMethodName$\", opts...)\n");
|
||||||
|
printer->Print("if err != nil { return nil, err }\n");
|
||||||
|
|
||||||
|
printer->Print(vars, "x := &$StreamType${stream}\n");
|
||||||
|
if (ServerOnlyStreaming(method)) {
|
||||||
|
printer->Print("if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }\n");
|
||||||
|
printer->Print("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }\n");
|
||||||
|
}
|
||||||
|
printer->Print("return x,nil\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
|
||||||
|
bool genSend = method->BidiStreaming() || ClientOnlyStreaming(method);
|
||||||
|
bool genRecv = method->BidiStreaming() || ServerOnlyStreaming(method);
|
||||||
|
bool genCloseAndRecv = ClientOnlyStreaming(method);
|
||||||
|
|
||||||
|
//Stream interface
|
||||||
|
printer->Print(vars, "type $Service$_$Method$Client interface {\n");
|
||||||
|
printer->Indent();
|
||||||
|
if (genSend) {
|
||||||
|
printer->Print(vars, "Send(*$Request$) error\n");
|
||||||
|
}
|
||||||
|
if (genRecv) {
|
||||||
|
printer->Print(vars, "Recv() (*$Response$, error)\n");
|
||||||
|
}
|
||||||
|
if (genCloseAndRecv) {
|
||||||
|
printer->Print(vars, "CloseAndRecv() (*$Response$, error)\n");
|
||||||
|
}
|
||||||
|
printer->Print(vars, "$grpc$.ClientStream\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
|
||||||
|
//Stream Client
|
||||||
|
printer->Print(vars, "type $StreamType$ struct{\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(vars, "$grpc$.ClientStream\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
|
||||||
|
if (genSend) {
|
||||||
|
printer->Print(vars, "func (x *$StreamType$) Send(m *$Request$) error {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print("return x.ClientStream.SendMsg(m)\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (genRecv) {
|
||||||
|
printer->Print(vars, "func (x *$StreamType$) Recv() (*$Response$, error) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(vars, "m := new($Response$)\n");
|
||||||
|
printer->Print("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }\n");
|
||||||
|
printer->Print("return m, nil\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (genCloseAndRecv) {
|
||||||
|
printer->Print(vars, "func (x *$StreamType$) CloseAndRecv() (*$Response$, error) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }\n");
|
||||||
|
printer->Print(vars, "m := new ($Response$)\n");
|
||||||
|
printer->Print("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }\n");
|
||||||
|
printer->Print("return m, nil\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates client API for the service
|
||||||
|
void GenerateService(const grpc_generator::Service *service, grpc_generator::Printer* printer,
|
||||||
|
std::map<grpc::string, grpc::string> vars) {
|
||||||
|
vars["Service"] = exportName(service->name());
|
||||||
|
// Client Interface
|
||||||
|
printer->Print(vars, "// Client API for $Service$ service\n");
|
||||||
|
printer->Print(vars, "type $Service$Client interface{\n");
|
||||||
|
printer->Indent();
|
||||||
|
for (int i = 0; i < service->method_count(); i++) {
|
||||||
|
GenerateClientMethodSignature(service->method(i).get(), printer, vars);
|
||||||
|
printer->Print("\n");
|
||||||
|
}
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
|
||||||
|
// Client structure
|
||||||
|
vars["ServiceUnexported"] = unexportName(vars["Service"]);
|
||||||
|
printer->Print(vars, "type $ServiceUnexported$Client struct {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(vars, "cc *$grpc$.ClientConn\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
|
||||||
|
// NewClient
|
||||||
|
printer->Print(vars, "func New$Service$Client(cc *$grpc$.ClientConn) $Service$Client {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(vars, "return &$ServiceUnexported$Client{cc}");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("\n}\n\n");
|
||||||
|
|
||||||
|
int unary_methods = 0, streaming_methods = 0;
|
||||||
|
vars["ServiceDesc"] = "_" + vars["Service"] + "_serviceDesc";
|
||||||
|
for (int i = 0; i < service->method_count(); i++) {
|
||||||
|
auto method = service->method(i);
|
||||||
|
if (method->NoStreaming()) {
|
||||||
|
vars["MethodDesc"] = vars["ServiceDesc"] + ".Method[" + as_string(unary_methods) + "]";
|
||||||
|
unary_methods++;
|
||||||
|
} else {
|
||||||
|
vars["MethodDesc"] = vars["ServiceDesc"] + ".Streams[" + as_string(streaming_methods) + "]";
|
||||||
|
streaming_methods++;
|
||||||
|
}
|
||||||
|
GenerateClientMethod(method.get(), printer, vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Server Interface
|
||||||
|
printer->Print(vars, "// Server API for $Service$ service\n");
|
||||||
|
printer->Print(vars, "type $Service$Server interface {\n");
|
||||||
|
printer->Indent();
|
||||||
|
for (int i = 0; i < service->method_count(); i++) {
|
||||||
|
GenerateServerMethodSignature(service->method(i).get(), printer, vars);
|
||||||
|
printer->Print("\n");
|
||||||
|
}
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
|
||||||
|
// Server registration.
|
||||||
|
printer->Print(vars, "func Register$Service$Server(s *$grpc$.Server, srv $Service$Server) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(vars, "s.RegisterService(&$ServiceDesc$, srv)\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
|
||||||
|
for (int i = 0; i < service->method_count(); i++) {
|
||||||
|
GenerateServerMethod(service->method(i).get(), printer, vars);
|
||||||
|
printer->Print("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Service Descriptor
|
||||||
|
printer->Print(vars, "var $ServiceDesc$ = $grpc$.ServiceDesc{\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(vars, "ServiceName: \"$Package$.$Service$\",\n");
|
||||||
|
printer->Print(vars, "HandlerType: (*$Service$Server)(nil),\n");
|
||||||
|
printer->Print(vars, "Methods: []$grpc$.MethodDesc{\n");
|
||||||
|
printer->Indent();
|
||||||
|
for (int i = 0; i < service->method_count(); i++) {
|
||||||
|
auto method = service->method(i);
|
||||||
|
vars["Method"] = method->name();
|
||||||
|
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
||||||
|
if (method->NoStreaming()) {
|
||||||
|
printer->Print("{\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(vars, "MethodName: \"$Method$\",\n");
|
||||||
|
printer->Print(vars, "Handler: $Handler$, \n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("},\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("},\n");
|
||||||
|
printer->Print(vars, "Streams: []$grpc$.StreamDesc{\n");
|
||||||
|
printer->Indent();
|
||||||
|
for (int i = 0; i < service->method_count(); i++) {
|
||||||
|
auto method = service->method(i);
|
||||||
|
vars["Method"] = method->name();
|
||||||
|
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
||||||
|
if (!method->NoStreaming()) {
|
||||||
|
printer->Print("{\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(vars, "StreamName: \"$Method$\",\n");
|
||||||
|
printer->Print(vars, "Handler: $Handler$, \n");
|
||||||
|
if (ClientOnlyStreaming(method.get())) {
|
||||||
|
printer->Print("ClientStreams: true,\n");
|
||||||
|
} else if (ServerOnlyStreaming(method.get())) {
|
||||||
|
printer->Print("ServerStreams: true,\n");
|
||||||
|
} else {
|
||||||
|
printer->Print("ServerStreams: true,\n");
|
||||||
|
printer->Print("ClientStreams: true,\n");
|
||||||
|
}
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("},\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("},\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Returns source for the service
|
||||||
|
grpc::string GenerateServiceSource(grpc_generator::File *file,
|
||||||
|
const grpc_generator::Service *service,
|
||||||
|
grpc_go_generator::Parameters *parameters) {
|
||||||
|
grpc::string out;
|
||||||
|
auto p = file->CreatePrinter(&out);
|
||||||
|
auto printer = p.get();
|
||||||
|
std::map<grpc::string, grpc::string> vars;
|
||||||
|
vars["Package"] = parameters->package_name;
|
||||||
|
vars["grpc"] = "grpc";
|
||||||
|
vars["context"] = "context";
|
||||||
|
GenerateImports(file, printer, vars);
|
||||||
|
if (parameters->custom_method_io_type != "") {
|
||||||
|
vars["CustomMethodIO"] = parameters->custom_method_io_type;
|
||||||
|
}
|
||||||
|
GenerateService(service, printer, vars);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}// Namespace grpc_go_generator
|
||||||
61
grpc/src/compiler/go_generator.h
Normal file
61
grpc/src/compiler/go_generator.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2015, Google Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of Google Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
|
||||||
|
#define GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
|
||||||
|
|
||||||
|
//go generator is used to generate GRPC code for serialization system, such as flatbuffers
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "src/compiler/schema_interface.h"
|
||||||
|
|
||||||
|
namespace grpc_go_generator {
|
||||||
|
|
||||||
|
struct Parameters {
|
||||||
|
//Defines the custom parameter types for methods
|
||||||
|
//eg: flatbuffers uses flatbuffers.Builder as input for the client and output for the server
|
||||||
|
grpc::string custom_method_io_type;
|
||||||
|
|
||||||
|
//Package name for the service
|
||||||
|
grpc::string package_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return the source of the generated service file.
|
||||||
|
grpc::string GenerateServiceSource(grpc_generator::File *file,
|
||||||
|
const grpc_generator::Service *service,
|
||||||
|
grpc_go_generator::Parameters *parameters);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
|
||||||
126
grpc/src/compiler/schema_interface.h
Normal file
126
grpc/src/compiler/schema_interface.h
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2015, Google Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of Google Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
|
||||||
|
#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
|
||||||
|
|
||||||
|
#include "src/compiler/config.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#ifndef GRPC_CUSTOM_STRING
|
||||||
|
#include <string>
|
||||||
|
#define GRPC_CUSTOM_STRING std::string
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace grpc {
|
||||||
|
|
||||||
|
typedef GRPC_CUSTOM_STRING string;
|
||||||
|
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
namespace grpc_generator {
|
||||||
|
|
||||||
|
// A common interface for objects having comments in the source.
|
||||||
|
// Return formatted comments to be inserted in generated code.
|
||||||
|
struct CommentHolder {
|
||||||
|
virtual ~CommentHolder() {}
|
||||||
|
virtual grpc::string GetLeadingComments(const grpc::string prefix) const = 0;
|
||||||
|
virtual grpc::string GetTrailingComments(const grpc::string prefix) const = 0;
|
||||||
|
virtual std::vector<grpc::string> GetAllComments() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// An abstract interface representing a method.
|
||||||
|
struct Method : public CommentHolder {
|
||||||
|
virtual ~Method() {}
|
||||||
|
|
||||||
|
virtual grpc::string name() const = 0;
|
||||||
|
|
||||||
|
virtual grpc::string input_type_name() const = 0;
|
||||||
|
virtual grpc::string output_type_name() const = 0;
|
||||||
|
|
||||||
|
virtual bool get_module_and_message_path_input(
|
||||||
|
grpc::string *str, grpc::string generator_file_name,
|
||||||
|
bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
|
||||||
|
virtual bool get_module_and_message_path_output(
|
||||||
|
grpc::string *str, grpc::string generator_file_name,
|
||||||
|
bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
|
||||||
|
|
||||||
|
virtual grpc::string get_input_type_name() const = 0;
|
||||||
|
virtual grpc::string get_output_type_name() const = 0;
|
||||||
|
virtual bool NoStreaming() const = 0;
|
||||||
|
virtual bool ClientStreaming() const = 0;
|
||||||
|
virtual bool ServerStreaming() const = 0;
|
||||||
|
virtual bool BidiStreaming() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// An abstract interface representing a service.
|
||||||
|
struct Service : public CommentHolder {
|
||||||
|
virtual ~Service() {}
|
||||||
|
|
||||||
|
virtual grpc::string name() const = 0;
|
||||||
|
|
||||||
|
virtual int method_count() const = 0;
|
||||||
|
virtual std::unique_ptr<const Method> method(int i) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Printer {
|
||||||
|
virtual ~Printer() {}
|
||||||
|
|
||||||
|
virtual void Print(const std::map<grpc::string, grpc::string> &vars,
|
||||||
|
const char *template_string) = 0;
|
||||||
|
virtual void Print(const char *string) = 0;
|
||||||
|
virtual void Indent() = 0;
|
||||||
|
virtual void Outdent() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// An interface that allows the source generated to be output using various
|
||||||
|
// libraries/idls/serializers.
|
||||||
|
struct File : public CommentHolder {
|
||||||
|
virtual ~File() {}
|
||||||
|
|
||||||
|
virtual grpc::string filename() const = 0;
|
||||||
|
virtual grpc::string filename_without_ext() const = 0;
|
||||||
|
virtual grpc::string package() const = 0;
|
||||||
|
virtual std::vector<grpc::string> package_parts() const = 0;
|
||||||
|
virtual grpc::string additional_headers() const = 0;
|
||||||
|
|
||||||
|
virtual int service_count() const = 0;
|
||||||
|
virtual std::unique_ptr<const Service> service(int i) const = 0;
|
||||||
|
|
||||||
|
virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
|
||||||
|
};
|
||||||
|
} // namespace grpc_generator
|
||||||
|
|
||||||
|
#endif // GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
|
||||||
93
grpc/tests/go_test.go
Normal file
93
grpc/tests/go_test.go
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"../../tests/MyGame/Example"
|
||||||
|
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type server struct{}
|
||||||
|
|
||||||
|
// test used to send and receive in grpc methods
|
||||||
|
var test = "Flatbuffers"
|
||||||
|
var addr = "0.0.0.0:50051"
|
||||||
|
|
||||||
|
// gRPC server store method
|
||||||
|
func (s *server) Store(context context.Context, in *Example.Monster) (*flatbuffers.Builder, error) {
|
||||||
|
b := flatbuffers.NewBuilder(0)
|
||||||
|
i := b.CreateString(test)
|
||||||
|
Example.StatStart(b)
|
||||||
|
Example.StatAddId(b, i)
|
||||||
|
b.Finish(Example.StatEnd(b))
|
||||||
|
return b, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// gRPC server retrieve method
|
||||||
|
func (s *server) Retrieve(context context.Context, in *Example.Stat) (*flatbuffers.Builder, error) {
|
||||||
|
b := flatbuffers.NewBuilder(0)
|
||||||
|
i := b.CreateString(test)
|
||||||
|
Example.MonsterStart(b)
|
||||||
|
Example.MonsterAddName(b, i)
|
||||||
|
b.Finish(Example.MonsterEnd(b))
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func StoreClient(c Example.MonsterStorageClient, t *testing.T) {
|
||||||
|
b := flatbuffers.NewBuilder(0)
|
||||||
|
i := b.CreateString(test)
|
||||||
|
Example.MonsterStart(b)
|
||||||
|
Example.MonsterAddName(b, i)
|
||||||
|
b.Finish(Example.MonsterEnd(b))
|
||||||
|
out, err := c.Store(context.Background(), b)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Store client failed: %v", err)
|
||||||
|
}
|
||||||
|
if string(out.Id()) != test {
|
||||||
|
t.Errorf("StoreClient failed: expected=%s, got=%s\n", test, out.Id())
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func RetrieveClient(c Example.MonsterStorageClient, t *testing.T) {
|
||||||
|
b := flatbuffers.NewBuilder(0)
|
||||||
|
i := b.CreateString(test)
|
||||||
|
Example.StatStart(b)
|
||||||
|
Example.StatAddId(b, i)
|
||||||
|
b.Finish(Example.StatEnd(b))
|
||||||
|
out, err := c.Retrieve(context.Background(), b)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Retrieve client failed: %v", err)
|
||||||
|
}
|
||||||
|
if string(out.Name()) != test {
|
||||||
|
t.Errorf("RetrieveClient failed: expected=%s, got=%s\n", test, out.Name())
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGRPC(t *testing.T) {
|
||||||
|
lis, err := net.Listen("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to listen: %v", err)
|
||||||
|
}
|
||||||
|
ser := grpc.NewServer(grpc.CustomCodec(flatbuffers.FlatbuffersCodec{}))
|
||||||
|
Example.RegisterMonsterStorageServer(ser, &server{})
|
||||||
|
go func() {
|
||||||
|
if err := ser.Serve(lis); err != nil {
|
||||||
|
t.Fatalf("Failed to serve: %v", err)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
conn, err := grpc.Dial(addr, grpc.WithInsecure(), grpc.WithCodec(flatbuffers.FlatbuffersCodec{}))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to connect: %v", err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
client := Example.NewMonsterStorageClient(conn)
|
||||||
|
StoreClient(client, t)
|
||||||
|
RetrieveClient(client, t)
|
||||||
|
}
|
||||||
163
grpc/tests/grpctest.cpp
Normal file
163
grpc/tests/grpctest.cpp
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include <grpc++/grpc++.h>
|
||||||
|
|
||||||
|
#include "monster_test_generated.h"
|
||||||
|
#include "monster_test.grpc.fb.h"
|
||||||
|
|
||||||
|
using namespace MyGame::Example;
|
||||||
|
|
||||||
|
// The callback implementation of our server, that derives from the generated
|
||||||
|
// code. It implements all rpcs specified in the FlatBuffers schema.
|
||||||
|
class ServiceImpl final : public MyGame::Example::MonsterStorage::Service {
|
||||||
|
virtual ::grpc::Status Store(::grpc::ServerContext* context,
|
||||||
|
const flatbuffers::grpc::Message<Monster> *request,
|
||||||
|
flatbuffers::grpc::Message<Stat> *response)
|
||||||
|
override {
|
||||||
|
// Create a response from the incoming request name.
|
||||||
|
fbb_.Clear();
|
||||||
|
auto stat_offset = CreateStat(fbb_, fbb_.CreateString("Hello, " +
|
||||||
|
request->GetRoot()->name()->str()));
|
||||||
|
fbb_.Finish(stat_offset);
|
||||||
|
// Transfer ownership of the message to gRPC
|
||||||
|
*response = fbb_.ReleaseMessage<Stat>();
|
||||||
|
return grpc::Status::OK;
|
||||||
|
}
|
||||||
|
virtual ::grpc::Status Retrieve(::grpc::ServerContext *context,
|
||||||
|
const flatbuffers::grpc::Message<Stat> *request,
|
||||||
|
::grpc::ServerWriter< flatbuffers::grpc::Message<Monster>>* writer)
|
||||||
|
override {
|
||||||
|
|
||||||
|
for (int i=0; i<10; i++) {
|
||||||
|
fbb_.Clear();
|
||||||
|
// Create 10 monsters for resposne.
|
||||||
|
auto monster_offset =
|
||||||
|
CreateMonster(fbb_, 0, 0, 0, fbb_.CreateString(
|
||||||
|
request->GetRoot()->id()->str() + " No." + std::to_string(i)));
|
||||||
|
fbb_.Finish(monster_offset);
|
||||||
|
|
||||||
|
flatbuffers::grpc::Message<Monster> monster = fbb_.ReleaseMessage<Monster>();
|
||||||
|
|
||||||
|
// Send monster to client using streaming.
|
||||||
|
writer->Write(monster);
|
||||||
|
}
|
||||||
|
return grpc::Status::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
flatbuffers::grpc::MessageBuilder fbb_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Track the server instance, so we can terminate it later.
|
||||||
|
grpc::Server *server_instance = nullptr;
|
||||||
|
// Mutex to protec this variable.
|
||||||
|
std::mutex wait_for_server;
|
||||||
|
std::condition_variable server_instance_cv;
|
||||||
|
|
||||||
|
// This function implements the server thread.
|
||||||
|
void RunServer() {
|
||||||
|
auto server_address = "0.0.0.0:50051";
|
||||||
|
// Callback interface we implemented above.
|
||||||
|
ServiceImpl service;
|
||||||
|
grpc::ServerBuilder builder;
|
||||||
|
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
|
||||||
|
builder.RegisterService(&service);
|
||||||
|
|
||||||
|
// Start the server. Lock to change the variable we're changing.
|
||||||
|
wait_for_server.lock();
|
||||||
|
server_instance = builder.BuildAndStart().release();
|
||||||
|
wait_for_server.unlock();
|
||||||
|
server_instance_cv.notify_one();
|
||||||
|
|
||||||
|
std::cout << "Server listening on " << server_address << std::endl;
|
||||||
|
// This will block the thread and serve requests.
|
||||||
|
server_instance->Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int /*argc*/, const char * /*argv*/[]) {
|
||||||
|
// Launch server.
|
||||||
|
std::thread server_thread(RunServer);
|
||||||
|
|
||||||
|
// wait for server to spin up.
|
||||||
|
std::unique_lock<std::mutex> lock(wait_for_server);
|
||||||
|
while (!server_instance) server_instance_cv.wait(lock);
|
||||||
|
|
||||||
|
// Now connect the client.
|
||||||
|
auto channel = grpc::CreateChannel("localhost:50051",
|
||||||
|
grpc::InsecureChannelCredentials());
|
||||||
|
auto stub = MyGame::Example::MonsterStorage::NewStub(channel);
|
||||||
|
|
||||||
|
|
||||||
|
flatbuffers::grpc::MessageBuilder fbb;
|
||||||
|
{
|
||||||
|
grpc::ClientContext context;
|
||||||
|
// Build a request with the name set.
|
||||||
|
auto monster_offset = CreateMonster(fbb, 0, 0, 0, fbb.CreateString("Fred"));
|
||||||
|
fbb.Finish(monster_offset);
|
||||||
|
auto request = fbb.ReleaseMessage<Monster>();
|
||||||
|
flatbuffers::grpc::Message<Stat> response;
|
||||||
|
|
||||||
|
// The actual RPC.
|
||||||
|
auto status = stub->Store(&context, request, &response);
|
||||||
|
|
||||||
|
if (status.ok()) {
|
||||||
|
auto resp = response.GetRoot()->id();
|
||||||
|
std::cout << "RPC response: " << resp->str() << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "RPC failed" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
grpc::ClientContext context;
|
||||||
|
fbb.Clear();
|
||||||
|
auto stat_offset = CreateStat(fbb, fbb.CreateString("Fred"));
|
||||||
|
fbb.Finish(stat_offset);
|
||||||
|
auto request = fbb.ReleaseMessage<Stat>();
|
||||||
|
|
||||||
|
flatbuffers::grpc::Message<Monster> response;
|
||||||
|
auto stream = stub->Retrieve(&context, request);
|
||||||
|
while (stream->Read(&response)) {
|
||||||
|
auto resp = response.GetRoot()->name();
|
||||||
|
std::cout << "RPC Streaming response: " << resp->str() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION
|
||||||
|
{
|
||||||
|
// Test that an invalid request errors out correctly
|
||||||
|
grpc::ClientContext context;
|
||||||
|
flatbuffers::grpc::Message<Monster> request; // simulate invalid message
|
||||||
|
flatbuffers::grpc::Message<Stat> response;
|
||||||
|
auto status = stub->Store(&context, request, &response);
|
||||||
|
// The rpc status should be INTERNAL to indicate a verification error. This
|
||||||
|
// matches the protobuf gRPC status code for an unparseable message.
|
||||||
|
assert(!status.ok());
|
||||||
|
assert(status.error_code() == ::grpc::StatusCode::INTERNAL);
|
||||||
|
assert(strcmp(status.error_message().c_str(), "Message verification failed") == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
server_instance->Shutdown();
|
||||||
|
|
||||||
|
server_thread.join();
|
||||||
|
|
||||||
|
delete server_instance;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
233
include/flatbuffers/base.h
Normal file
233
include/flatbuffers/base.h
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
#ifndef FLATBUFFERS_BASE_H_
|
||||||
|
#define FLATBUFFERS_BASE_H_
|
||||||
|
|
||||||
|
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \
|
||||||
|
defined(_MSC_VER) && defined(_DEBUG)
|
||||||
|
#define _CRTDBG_MAP_ALLOC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#ifndef ARDUINO
|
||||||
|
#include <cstdint>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \
|
||||||
|
defined(_MSC_VER) && defined(_DEBUG)
|
||||||
|
#include <crtdbg.h>
|
||||||
|
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
|
||||||
|
#define new DEBUG_NEW
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H)
|
||||||
|
#include <utility.h>
|
||||||
|
#else
|
||||||
|
#include <utility>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#ifdef _STLPORT_VERSION
|
||||||
|
#define FLATBUFFERS_CPP98_STL
|
||||||
|
#endif
|
||||||
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
|
#include <functional>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "flatbuffers/stl_emulation.h"
|
||||||
|
|
||||||
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
|
#if __cplusplus <= 199711L && \
|
||||||
|
(!defined(_MSC_VER) || _MSC_VER < 1600) && \
|
||||||
|
(!defined(__GNUC__) || \
|
||||||
|
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400))
|
||||||
|
#error A C++11 compatible compiler with support for the auto typing is \
|
||||||
|
required for FlatBuffers.
|
||||||
|
#error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__clang__) && \
|
||||||
|
defined(__GNUC__) && \
|
||||||
|
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600)
|
||||||
|
// Backwards compatability for g++ 4.4, and 4.5 which don't have the nullptr
|
||||||
|
// and constexpr keywords. Note the __clang__ check is needed, because clang
|
||||||
|
// presents itself as an older GNUC compiler.
|
||||||
|
#ifndef nullptr_t
|
||||||
|
const class nullptr_t {
|
||||||
|
public:
|
||||||
|
template<class T> inline operator T*() const { return 0; }
|
||||||
|
private:
|
||||||
|
void operator&() const;
|
||||||
|
} nullptr = {};
|
||||||
|
#endif
|
||||||
|
#ifndef constexpr
|
||||||
|
#define constexpr const
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The wire format uses a little endian encoding (since that's efficient for
|
||||||
|
// the common platforms).
|
||||||
|
#if defined(__s390x__)
|
||||||
|
#define FLATBUFFERS_LITTLEENDIAN 0
|
||||||
|
#endif // __s390x__
|
||||||
|
#if !defined(FLATBUFFERS_LITTLEENDIAN)
|
||||||
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
#define FLATBUFFERS_LITTLEENDIAN 0
|
||||||
|
#else
|
||||||
|
#define FLATBUFFERS_LITTLEENDIAN 1
|
||||||
|
#endif // __BIG_ENDIAN__
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#if defined(_M_PPC)
|
||||||
|
#define FLATBUFFERS_LITTLEENDIAN 0
|
||||||
|
#else
|
||||||
|
#define FLATBUFFERS_LITTLEENDIAN 1
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#error Unable to determine endianness, define FLATBUFFERS_LITTLEENDIAN.
|
||||||
|
#endif
|
||||||
|
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
|
||||||
|
|
||||||
|
#define FLATBUFFERS_VERSION_MAJOR 1
|
||||||
|
#define FLATBUFFERS_VERSION_MINOR 8
|
||||||
|
#define FLATBUFFERS_VERSION_REVISION 0
|
||||||
|
#define FLATBUFFERS_STRING_EXPAND(X) #X
|
||||||
|
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
|
||||||
|
|
||||||
|
#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \
|
||||||
|
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407))
|
||||||
|
#define FLATBUFFERS_FINAL_CLASS final
|
||||||
|
#define FLATBUFFERS_OVERRIDE override
|
||||||
|
#else
|
||||||
|
#define FLATBUFFERS_FINAL_CLASS
|
||||||
|
#define FLATBUFFERS_OVERRIDE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \
|
||||||
|
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406))
|
||||||
|
#define FLATBUFFERS_CONSTEXPR constexpr
|
||||||
|
#else
|
||||||
|
#define FLATBUFFERS_CONSTEXPR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46 || \
|
||||||
|
defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026
|
||||||
|
#define FLATBUFFERS_NOEXCEPT noexcept
|
||||||
|
#else
|
||||||
|
#define FLATBUFFERS_NOEXCEPT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to
|
||||||
|
// private, so be sure to put it at the end or reset access mode explicitly.
|
||||||
|
#if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \
|
||||||
|
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404))
|
||||||
|
#define FLATBUFFERS_DELETE_FUNC(func) func = delete;
|
||||||
|
#else
|
||||||
|
#define FLATBUFFERS_DELETE_FUNC(func) private: func;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4127) // C4127: conditional expression is constant
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
/// @file
|
||||||
|
namespace flatbuffers {
|
||||||
|
|
||||||
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
|
// Our default offset / size type, 32bit on purpose on 64bit systems.
|
||||||
|
// Also, using a consistent offset type maintains compatibility of serialized
|
||||||
|
// offset values between 32bit and 64bit systems.
|
||||||
|
typedef uint32_t uoffset_t;
|
||||||
|
|
||||||
|
// Signed offsets for references that can go in both directions.
|
||||||
|
typedef int32_t soffset_t;
|
||||||
|
|
||||||
|
// Offset/index used in v-tables, can be changed to uint8_t in
|
||||||
|
// format forks to save a bit of space if desired.
|
||||||
|
typedef uint16_t voffset_t;
|
||||||
|
|
||||||
|
typedef uintmax_t largest_scalar_t;
|
||||||
|
|
||||||
|
// In 32bits, this evaluates to 2GB - 1
|
||||||
|
#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(soffset_t) * 8 - 1)) - 1)
|
||||||
|
|
||||||
|
// We support aligning the contents of buffers up to this size.
|
||||||
|
#define FLATBUFFERS_MAX_ALIGNMENT 16
|
||||||
|
|
||||||
|
template<typename T> T EndianSwap(T t) {
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define FLATBUFFERS_BYTESWAP16 _byteswap_ushort
|
||||||
|
#define FLATBUFFERS_BYTESWAP32 _byteswap_ulong
|
||||||
|
#define FLATBUFFERS_BYTESWAP64 _byteswap_uint64
|
||||||
|
#else
|
||||||
|
#if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__)
|
||||||
|
// __builtin_bswap16 was missing prior to GCC 4.8.
|
||||||
|
#define FLATBUFFERS_BYTESWAP16(x) \
|
||||||
|
static_cast<uint16_t>(__builtin_bswap32(static_cast<uint32_t>(x) << 16))
|
||||||
|
#else
|
||||||
|
#define FLATBUFFERS_BYTESWAP16 __builtin_bswap16
|
||||||
|
#endif
|
||||||
|
#define FLATBUFFERS_BYTESWAP32 __builtin_bswap32
|
||||||
|
#define FLATBUFFERS_BYTESWAP64 __builtin_bswap64
|
||||||
|
#endif
|
||||||
|
if (sizeof(T) == 1) { // Compile-time if-then's.
|
||||||
|
return t;
|
||||||
|
} else if (sizeof(T) == 2) {
|
||||||
|
union { T t; uint16_t i; } u;
|
||||||
|
u.t = t;
|
||||||
|
u.i = FLATBUFFERS_BYTESWAP16(u.i);
|
||||||
|
return u.t;
|
||||||
|
} else if (sizeof(T) == 4) {
|
||||||
|
union { T t; uint32_t i; } u;
|
||||||
|
u.t = t;
|
||||||
|
u.i = FLATBUFFERS_BYTESWAP32(u.i);
|
||||||
|
return u.t;
|
||||||
|
} else if (sizeof(T) == 8) {
|
||||||
|
union { T t; uint64_t i; } u;
|
||||||
|
u.t = t;
|
||||||
|
u.i = FLATBUFFERS_BYTESWAP64(u.i);
|
||||||
|
return u.t;
|
||||||
|
} else {
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T> T EndianScalar(T t) {
|
||||||
|
#if FLATBUFFERS_LITTLEENDIAN
|
||||||
|
return t;
|
||||||
|
#else
|
||||||
|
return EndianSwap(t);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> T ReadScalar(const void *p) {
|
||||||
|
return EndianScalar(*reinterpret_cast<const T *>(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> void WriteScalar(void *p, T t) {
|
||||||
|
*reinterpret_cast<T *>(p) = EndianScalar(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Computes how many bytes you'd have to pad to be able to write an
|
||||||
|
// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in
|
||||||
|
// memory).
|
||||||
|
inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
|
||||||
|
return ((~buf_size) + 1) & (scalar_size - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace flatbuffers
|
||||||
|
#endif // FLATBUFFERS_BASE_H_
|
||||||
137
include/flatbuffers/code_generators.h
Normal file
137
include/flatbuffers/code_generators.h
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_CODE_GENERATORS_H_
|
||||||
|
#define FLATBUFFERS_CODE_GENERATORS_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <sstream>
|
||||||
|
#include "flatbuffers/idl.h"
|
||||||
|
|
||||||
|
namespace flatbuffers {
|
||||||
|
|
||||||
|
// Utility class to assist in generating code through use of text templates.
|
||||||
|
//
|
||||||
|
// Example code:
|
||||||
|
// CodeWriter code;
|
||||||
|
// code.SetValue("NAME", "Foo");
|
||||||
|
// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
|
||||||
|
// code.SetValue("NAME", "Bar");
|
||||||
|
// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
|
||||||
|
// std::cout << code.ToString() << std::endl;
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// void Foo() { printf("%s", "Foo"); }
|
||||||
|
// void Bar() { printf("%s", "Bar"); }
|
||||||
|
class CodeWriter {
|
||||||
|
public:
|
||||||
|
CodeWriter() {}
|
||||||
|
|
||||||
|
// Clears the current "written" code.
|
||||||
|
void Clear() {
|
||||||
|
stream_.str("");
|
||||||
|
stream_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Associates a key with a value. All subsequent calls to operator+=, where
|
||||||
|
// the specified key is contained in {{ and }} delimiters will be replaced by
|
||||||
|
// the given value.
|
||||||
|
void SetValue(const std::string& key, const std::string& value) {
|
||||||
|
value_map_[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Appends the given text to the generated code as well as a newline
|
||||||
|
// character. Any text within {{ and }} delimeters is replaced by values
|
||||||
|
// previously stored in the CodeWriter by calling SetValue above. The newline
|
||||||
|
// will be suppressed if the text ends with the \\ character.
|
||||||
|
void operator+=(std::string text);
|
||||||
|
|
||||||
|
// Returns the current contents of the CodeWriter as a std::string.
|
||||||
|
std::string ToString() const { return stream_.str(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<std::string, std::string> value_map_;
|
||||||
|
std::stringstream stream_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BaseGenerator {
|
||||||
|
public:
|
||||||
|
virtual bool generate() = 0;
|
||||||
|
|
||||||
|
static std::string NamespaceDir(const Parser &parser,
|
||||||
|
const std::string &path,
|
||||||
|
const Namespace &ns);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BaseGenerator(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name,
|
||||||
|
const std::string qualifying_start,
|
||||||
|
const std::string qualifying_separator)
|
||||||
|
: parser_(parser),
|
||||||
|
path_(path),
|
||||||
|
file_name_(file_name),
|
||||||
|
qualifying_start_(qualifying_start),
|
||||||
|
qualifying_separator_(qualifying_separator) {}
|
||||||
|
virtual ~BaseGenerator() {}
|
||||||
|
|
||||||
|
// No copy/assign.
|
||||||
|
BaseGenerator &operator=(const BaseGenerator &);
|
||||||
|
BaseGenerator(const BaseGenerator &);
|
||||||
|
|
||||||
|
std::string NamespaceDir(const Namespace &ns) const;
|
||||||
|
|
||||||
|
static const char *FlatBuffersGeneratedWarning();
|
||||||
|
|
||||||
|
static std::string FullNamespace(const char *separator, const Namespace &ns);
|
||||||
|
|
||||||
|
static std::string LastNamespacePart(const Namespace &ns);
|
||||||
|
|
||||||
|
// tracks the current namespace for early exit in WrapInNameSpace
|
||||||
|
// c++, java and csharp returns a different namespace from
|
||||||
|
// the following default (no early exit, always fully qualify),
|
||||||
|
// which works for js and php
|
||||||
|
virtual const Namespace *CurrentNameSpace() const { return nullptr; }
|
||||||
|
|
||||||
|
// Ensure that a type is prefixed with its namespace whenever it is used
|
||||||
|
// outside of its namespace.
|
||||||
|
std::string WrapInNameSpace(const Namespace *ns,
|
||||||
|
const std::string &name) const;
|
||||||
|
|
||||||
|
std::string WrapInNameSpace(const Definition &def) const;
|
||||||
|
|
||||||
|
std::string GetNameSpace(const Definition &def) const;
|
||||||
|
|
||||||
|
const Parser &parser_;
|
||||||
|
const std::string &path_;
|
||||||
|
const std::string &file_name_;
|
||||||
|
const std::string qualifying_start_;
|
||||||
|
const std::string qualifying_separator_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CommentConfig {
|
||||||
|
const char *first_line;
|
||||||
|
const char *content_line_prefix;
|
||||||
|
const char *last_line;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void GenComment(const std::vector<std::string> &dc,
|
||||||
|
std::string *code_ptr,
|
||||||
|
const CommentConfig *config,
|
||||||
|
const char *prefix = "");
|
||||||
|
|
||||||
|
} // namespace flatbuffers
|
||||||
|
|
||||||
|
#endif // FLATBUFFERS_CODE_GENERATORS_H_
|
||||||
File diff suppressed because it is too large
Load Diff
97
include/flatbuffers/flatc.h
Normal file
97
include/flatbuffers/flatc.h
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "flatbuffers/flatbuffers.h"
|
||||||
|
#include "flatbuffers/idl.h"
|
||||||
|
#include "flatbuffers/util.h"
|
||||||
|
#include <functional>
|
||||||
|
#include <limits>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifndef FLATC_H_
|
||||||
|
#define FLATC_H_
|
||||||
|
|
||||||
|
namespace flatbuffers {
|
||||||
|
|
||||||
|
class FlatCompiler {
|
||||||
|
public:
|
||||||
|
// Output generator for the various programming languages and formats we
|
||||||
|
// support.
|
||||||
|
struct Generator {
|
||||||
|
typedef bool (*GenerateFn)(const flatbuffers::Parser &parser,
|
||||||
|
const std::string &path,
|
||||||
|
const std::string &file_name);
|
||||||
|
typedef std::string (*MakeRuleFn)(const flatbuffers::Parser &parser,
|
||||||
|
const std::string &path,
|
||||||
|
const std::string &file_name);
|
||||||
|
|
||||||
|
GenerateFn generate;
|
||||||
|
const char *generator_opt_short;
|
||||||
|
const char *generator_opt_long;
|
||||||
|
const char *lang_name;
|
||||||
|
bool schema_only;
|
||||||
|
GenerateFn generateGRPC;
|
||||||
|
flatbuffers::IDLOptions::Language lang;
|
||||||
|
const char *generator_help;
|
||||||
|
MakeRuleFn make_rule;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*WarnFn)(const FlatCompiler *flatc,
|
||||||
|
const std::string &warn,
|
||||||
|
bool show_exe_name);
|
||||||
|
|
||||||
|
typedef void (*ErrorFn)(const FlatCompiler *flatc,
|
||||||
|
const std::string &err,
|
||||||
|
bool usage, bool show_exe_name);
|
||||||
|
|
||||||
|
// Parameters required to initialize the FlatCompiler.
|
||||||
|
struct InitParams {
|
||||||
|
InitParams()
|
||||||
|
: generators(nullptr),
|
||||||
|
num_generators(0),
|
||||||
|
warn_fn(nullptr),
|
||||||
|
error_fn(nullptr) {}
|
||||||
|
|
||||||
|
const Generator* generators;
|
||||||
|
size_t num_generators;
|
||||||
|
WarnFn warn_fn;
|
||||||
|
ErrorFn error_fn;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit FlatCompiler(const InitParams& params) : params_(params) {}
|
||||||
|
|
||||||
|
int Compile(int argc, const char** argv);
|
||||||
|
|
||||||
|
std::string GetUsageString(const char* program_name) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ParseFile(flatbuffers::Parser &parser,
|
||||||
|
const std::string &filename,
|
||||||
|
const std::string &contents,
|
||||||
|
std::vector<const char *> &include_directories) const;
|
||||||
|
|
||||||
|
void Warn(const std::string &warn, bool show_exe_name = true) const;
|
||||||
|
|
||||||
|
void Error(const std::string &err, bool usage = true,
|
||||||
|
bool show_exe_name = true) const;
|
||||||
|
|
||||||
|
InitParams params_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace flatbuffers
|
||||||
|
|
||||||
|
#endif // FLATC_H_
|
||||||
1498
include/flatbuffers/flexbuffers.h
Normal file
1498
include/flatbuffers/flexbuffers.h
Normal file
File diff suppressed because it is too large
Load Diff
255
include/flatbuffers/grpc.h
Normal file
255
include/flatbuffers/grpc.h
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_GRPC_H_
|
||||||
|
#define FLATBUFFERS_GRPC_H_
|
||||||
|
|
||||||
|
// Helper functionality to glue FlatBuffers and GRPC.
|
||||||
|
|
||||||
|
#include "flatbuffers/flatbuffers.h"
|
||||||
|
#include "grpc++/support/byte_buffer.h"
|
||||||
|
#include "grpc/byte_buffer_reader.h"
|
||||||
|
|
||||||
|
namespace flatbuffers {
|
||||||
|
namespace grpc {
|
||||||
|
|
||||||
|
// Message is a typed wrapper around a buffer that manages the underlying
|
||||||
|
// `grpc_slice` and also provides flatbuffers-specific helpers such as `Verify`
|
||||||
|
// and `GetRoot`. Since it is backed by a `grpc_slice`, the underlying buffer
|
||||||
|
// is refcounted and ownership is be managed automatically.
|
||||||
|
template <class T>
|
||||||
|
class Message {
|
||||||
|
public:
|
||||||
|
Message() : slice_(grpc_empty_slice()) {}
|
||||||
|
|
||||||
|
Message(grpc_slice slice, bool add_ref)
|
||||||
|
: slice_(add_ref ? grpc_slice_ref(slice) : slice) {}
|
||||||
|
|
||||||
|
Message &operator=(const Message &other) = delete;
|
||||||
|
|
||||||
|
Message(Message &&other) : slice_(other.slice_) {
|
||||||
|
other.slice_ = grpc_empty_slice();
|
||||||
|
}
|
||||||
|
|
||||||
|
Message(const Message &other) = delete;
|
||||||
|
|
||||||
|
Message &operator=(Message &&other) {
|
||||||
|
grpc_slice_unref(slice_);
|
||||||
|
slice_ = other.slice_;
|
||||||
|
other.slice_ = grpc_empty_slice();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Message() { grpc_slice_unref(slice_); }
|
||||||
|
|
||||||
|
const uint8_t *mutable_data() const { return GRPC_SLICE_START_PTR(slice_); }
|
||||||
|
|
||||||
|
const uint8_t *data() const { return GRPC_SLICE_START_PTR(slice_); }
|
||||||
|
|
||||||
|
size_t size() const { return GRPC_SLICE_LENGTH(slice_); }
|
||||||
|
|
||||||
|
bool Verify() const {
|
||||||
|
Verifier verifier(data(), size());
|
||||||
|
return verifier.VerifyBuffer<T>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
T *GetMutableRoot() { return flatbuffers::GetMutableRoot<T>(mutable_data()); }
|
||||||
|
|
||||||
|
const T *GetRoot() const { return flatbuffers::GetRoot<T>(data()); }
|
||||||
|
|
||||||
|
// This is only intended for serializer use, or if you know what you're doing
|
||||||
|
const grpc_slice &BorrowSlice() const { return slice_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
grpc_slice slice_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MessageBuilder;
|
||||||
|
|
||||||
|
// SliceAllocator is a gRPC-specific allocator that uses the `grpc_slice`
|
||||||
|
// refcounted slices to manage memory ownership. This makes it easy and
|
||||||
|
// efficient to transfer buffers to gRPC.
|
||||||
|
class SliceAllocator : public Allocator {
|
||||||
|
public:
|
||||||
|
SliceAllocator() : slice_(grpc_empty_slice()) {}
|
||||||
|
|
||||||
|
SliceAllocator(const SliceAllocator &other) = delete;
|
||||||
|
SliceAllocator &operator=(const SliceAllocator &other) = delete;
|
||||||
|
|
||||||
|
virtual ~SliceAllocator() { grpc_slice_unref(slice_); }
|
||||||
|
|
||||||
|
virtual uint8_t *allocate(size_t size) override {
|
||||||
|
assert(GRPC_SLICE_IS_EMPTY(slice_));
|
||||||
|
slice_ = grpc_slice_malloc(size);
|
||||||
|
return GRPC_SLICE_START_PTR(slice_);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void deallocate(uint8_t *p, size_t size) override {
|
||||||
|
assert(p == GRPC_SLICE_START_PTR(slice_));
|
||||||
|
assert(size == GRPC_SLICE_LENGTH(slice_));
|
||||||
|
grpc_slice_unref(slice_);
|
||||||
|
slice_ = grpc_empty_slice();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual uint8_t *reallocate_downward(uint8_t *old_p, size_t old_size,
|
||||||
|
size_t new_size) override {
|
||||||
|
assert(old_p == GRPC_SLICE_START_PTR(slice_));
|
||||||
|
assert(old_size == GRPC_SLICE_LENGTH(slice_));
|
||||||
|
assert(new_size > old_size);
|
||||||
|
grpc_slice old_slice = slice_;
|
||||||
|
grpc_slice new_slice = grpc_slice_malloc(new_size);
|
||||||
|
uint8_t *new_p = GRPC_SLICE_START_PTR(new_slice);
|
||||||
|
memcpy(new_p + (new_size - old_size), old_p, old_size);
|
||||||
|
slice_ = new_slice;
|
||||||
|
grpc_slice_unref(old_slice);
|
||||||
|
return new_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
grpc_slice &get_slice(uint8_t *p, size_t size) {
|
||||||
|
assert(p == GRPC_SLICE_START_PTR(slice_));
|
||||||
|
assert(size == GRPC_SLICE_LENGTH(slice_));
|
||||||
|
return slice_;
|
||||||
|
}
|
||||||
|
|
||||||
|
grpc_slice slice_;
|
||||||
|
|
||||||
|
friend class MessageBuilder;
|
||||||
|
};
|
||||||
|
|
||||||
|
// SliceAllocatorMember is a hack to ensure that the MessageBuilder's
|
||||||
|
// slice_allocator_ member is constructed before the FlatBufferBuilder, since
|
||||||
|
// the allocator is used in the FlatBufferBuilder ctor.
|
||||||
|
namespace detail {
|
||||||
|
struct SliceAllocatorMember {
|
||||||
|
SliceAllocator slice_allocator_;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageBuilder is a gRPC-specific FlatBufferBuilder that uses SliceAllocator
|
||||||
|
// to allocate gRPC buffers.
|
||||||
|
class MessageBuilder : private detail::SliceAllocatorMember,
|
||||||
|
public FlatBufferBuilder {
|
||||||
|
public:
|
||||||
|
explicit MessageBuilder(uoffset_t initial_size = 1024)
|
||||||
|
: FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
|
||||||
|
|
||||||
|
MessageBuilder(const MessageBuilder &other) = delete;
|
||||||
|
MessageBuilder &operator=(const MessageBuilder &other) = delete;
|
||||||
|
|
||||||
|
~MessageBuilder() {}
|
||||||
|
|
||||||
|
// GetMessage extracts the subslice of the buffer corresponding to the
|
||||||
|
// flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer
|
||||||
|
// ownership.
|
||||||
|
template <class T>
|
||||||
|
Message<T> GetMessage() {
|
||||||
|
auto buf_data = buf_.buf(); // pointer to memory
|
||||||
|
auto buf_size = buf_.capacity(); // size of memory
|
||||||
|
auto msg_data = buf_.data(); // pointer to msg
|
||||||
|
auto msg_size = buf_.size(); // size of msg
|
||||||
|
// Do some sanity checks on data/size
|
||||||
|
assert(msg_data);
|
||||||
|
assert(msg_size);
|
||||||
|
assert(msg_data >= buf_data);
|
||||||
|
assert(msg_data + msg_size <= buf_data + buf_size);
|
||||||
|
// Calculate offsets from the buffer start
|
||||||
|
auto begin = msg_data - buf_data;
|
||||||
|
auto end = begin + msg_size;
|
||||||
|
// Get the slice we are working with (no refcount change)
|
||||||
|
grpc_slice slice = slice_allocator_.get_slice(buf_data, buf_size);
|
||||||
|
// Extract a subslice of the existing slice (increment refcount)
|
||||||
|
grpc_slice subslice = grpc_slice_sub(slice, begin, end);
|
||||||
|
// Wrap the subslice in a `Message<T>`, but don't increment refcount
|
||||||
|
Message<T> msg(subslice, false);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Message<T> ReleaseMessage() {
|
||||||
|
Message<T> msg = GetMessage<T>();
|
||||||
|
Reset();
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// SliceAllocator slice_allocator_; // part of SliceAllocatorMember
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace grpc
|
||||||
|
} // namespace flatbuffers
|
||||||
|
|
||||||
|
namespace grpc {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class SerializationTraits<flatbuffers::grpc::Message<T>> {
|
||||||
|
public:
|
||||||
|
static grpc::Status Serialize(const flatbuffers::grpc::Message<T> &msg,
|
||||||
|
grpc_byte_buffer **buffer, bool *own_buffer) {
|
||||||
|
// We are passed in a `Message<T>`, which is a wrapper around a
|
||||||
|
// `grpc_slice`. We extract it here using `BorrowSlice()`. The const cast
|
||||||
|
// is necesary because the `grpc_raw_byte_buffer_create` func expects
|
||||||
|
// non-const slices in order to increment their refcounts.
|
||||||
|
grpc_slice *slice = const_cast<grpc_slice *>(&msg.BorrowSlice());
|
||||||
|
// Now use `grpc_raw_byte_buffer_create` to package the single slice into a
|
||||||
|
// `grpc_byte_buffer`, incrementing the refcount in the process.
|
||||||
|
*buffer = grpc_raw_byte_buffer_create(slice, 1);
|
||||||
|
*own_buffer = true;
|
||||||
|
return grpc::Status::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deserialize by pulling the
|
||||||
|
static grpc::Status Deserialize(grpc_byte_buffer *buffer,
|
||||||
|
flatbuffers::grpc::Message<T> *msg) {
|
||||||
|
if (!buffer) {
|
||||||
|
return ::grpc::Status(::grpc::StatusCode::INTERNAL, "No payload");
|
||||||
|
}
|
||||||
|
// Check if this is a single uncompressed slice.
|
||||||
|
if ((buffer->type == GRPC_BB_RAW) &&
|
||||||
|
(buffer->data.raw.compression == GRPC_COMPRESS_NONE) &&
|
||||||
|
(buffer->data.raw.slice_buffer.count == 1)) {
|
||||||
|
// If it is, then we can reference the `grpc_slice` directly.
|
||||||
|
grpc_slice slice = buffer->data.raw.slice_buffer.slices[0];
|
||||||
|
// We wrap a `Message<T>` around the slice, incrementing the refcount.
|
||||||
|
*msg = flatbuffers::grpc::Message<T>(slice, true);
|
||||||
|
} else {
|
||||||
|
// Otherwise, we need to use `grpc_byte_buffer_reader_readall` to read
|
||||||
|
// `buffer` into a single contiguous `grpc_slice`. The gRPC reader gives
|
||||||
|
// us back a new slice with the refcount already incremented.
|
||||||
|
grpc_byte_buffer_reader reader;
|
||||||
|
grpc_byte_buffer_reader_init(&reader, buffer);
|
||||||
|
grpc_slice slice = grpc_byte_buffer_reader_readall(&reader);
|
||||||
|
grpc_byte_buffer_reader_destroy(&reader);
|
||||||
|
// We wrap a `Message<T>` around the slice, but dont increment refcount
|
||||||
|
*msg = flatbuffers::grpc::Message<T>(slice, false);
|
||||||
|
}
|
||||||
|
grpc_byte_buffer_destroy(buffer);
|
||||||
|
#if FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION
|
||||||
|
return ::grpc::Status::OK;
|
||||||
|
#else
|
||||||
|
if (msg->Verify()) {
|
||||||
|
return ::grpc::Status::OK;
|
||||||
|
} else {
|
||||||
|
return ::grpc::Status(::grpc::StatusCode::INTERNAL,
|
||||||
|
"Message verification failed");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace grpc;
|
||||||
|
|
||||||
|
#endif // FLATBUFFERS_GRPC_H_
|
||||||
@@ -18,14 +18,18 @@
|
|||||||
#define FLATBUFFERS_IDL_H_
|
#define FLATBUFFERS_IDL_H_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
|
#include "flatbuffers/base.h"
|
||||||
#include "flatbuffers/flatbuffers.h"
|
#include "flatbuffers/flatbuffers.h"
|
||||||
#include "flatbuffers/hash.h"
|
#include "flatbuffers/hash.h"
|
||||||
#include "flatbuffers/reflection.h"
|
#include "flatbuffers/reflection.h"
|
||||||
|
#include "flatbuffers/flexbuffers.h"
|
||||||
|
|
||||||
|
#if !defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
#include <functional>
|
||||||
|
#endif // !defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
|
||||||
// This file defines the data types representing a parsed IDL (Interface
|
// This file defines the data types representing a parsed IDL (Interface
|
||||||
// Definition Language) / schema file.
|
// Definition Language) / schema file.
|
||||||
@@ -103,6 +107,9 @@ inline bool IsInteger(BaseType t) { return t >= BASE_TYPE_UTYPE &&
|
|||||||
t <= BASE_TYPE_ULONG; }
|
t <= BASE_TYPE_ULONG; }
|
||||||
inline bool IsFloat (BaseType t) { return t == BASE_TYPE_FLOAT ||
|
inline bool IsFloat (BaseType t) { return t == BASE_TYPE_FLOAT ||
|
||||||
t == BASE_TYPE_DOUBLE; }
|
t == BASE_TYPE_DOUBLE; }
|
||||||
|
inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG ||
|
||||||
|
t == BASE_TYPE_ULONG; }
|
||||||
|
inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; }
|
||||||
|
|
||||||
extern const char *const kTypeNames[];
|
extern const char *const kTypeNames[];
|
||||||
extern const char kTypeSizes[];
|
extern const char kTypeSizes[];
|
||||||
@@ -113,6 +120,7 @@ inline size_t SizeOf(BaseType t) {
|
|||||||
|
|
||||||
struct StructDef;
|
struct StructDef;
|
||||||
struct EnumDef;
|
struct EnumDef;
|
||||||
|
class Parser;
|
||||||
|
|
||||||
// Represents any type in the IDL, which is a combination of the BaseType
|
// Represents any type in the IDL, which is a combination of the BaseType
|
||||||
// and additional information for vectors/structs_.
|
// and additional information for vectors/structs_.
|
||||||
@@ -161,7 +169,7 @@ template<typename T> class SymbolTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Add(const std::string &name, T *e) {
|
bool Add(const std::string &name, T *e) {
|
||||||
vec.emplace_back(e);
|
vector_emplace_back(&vec, e);
|
||||||
auto it = dict.find(name);
|
auto it = dict.find(name);
|
||||||
if (it != dict.end()) return true;
|
if (it != dict.end()) return true;
|
||||||
dict[name] = e;
|
dict[name] = e;
|
||||||
@@ -184,16 +192,15 @@ template<typename T> class SymbolTable {
|
|||||||
return it == dict.end() ? nullptr : it->second;
|
return it == dict.end() ? nullptr : it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
std::map<std::string, T *> dict; // quick lookup
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
std::map<std::string, T *> dict; // quick lookup
|
||||||
std::vector<T *> vec; // Used to iterate in order of insertion
|
std::vector<T *> vec; // Used to iterate in order of insertion
|
||||||
};
|
};
|
||||||
|
|
||||||
// A name space, as set in the schema.
|
// A name space, as set in the schema.
|
||||||
struct Namespace {
|
struct Namespace {
|
||||||
std::vector<std::string> components;
|
Namespace() : from_table(0) {}
|
||||||
|
|
||||||
|
|
||||||
// Given a (potentally unqualified) name, return the "fully qualified" name
|
// Given a (potentally unqualified) name, return the "fully qualified" name
|
||||||
// which has a full namespaced descriptor.
|
// which has a full namespaced descriptor.
|
||||||
@@ -201,12 +208,20 @@ struct Namespace {
|
|||||||
// the current namespace has.
|
// the current namespace has.
|
||||||
std::string GetFullyQualifiedName(const std::string &name,
|
std::string GetFullyQualifiedName(const std::string &name,
|
||||||
size_t max_components = 1000) const;
|
size_t max_components = 1000) const;
|
||||||
|
|
||||||
|
std::vector<std::string> components;
|
||||||
|
size_t from_table; // Part of the namespace corresponds to a message/table.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base class for all definition types (fields, structs_, enums_).
|
// Base class for all definition types (fields, structs_, enums_).
|
||||||
struct Definition {
|
struct Definition {
|
||||||
Definition() : generated(false), defined_namespace(nullptr),
|
Definition() : generated(false), defined_namespace(nullptr),
|
||||||
serialized_location(0), index(-1) {}
|
serialized_location(0), index(-1), refcount(1) {}
|
||||||
|
|
||||||
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<
|
||||||
|
reflection::KeyValue>>>
|
||||||
|
SerializeAttributes(FlatBufferBuilder *builder,
|
||||||
|
const Parser &parser) const;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string file;
|
std::string file;
|
||||||
@@ -218,19 +233,26 @@ struct Definition {
|
|||||||
// For use with Serialize()
|
// For use with Serialize()
|
||||||
uoffset_t serialized_location;
|
uoffset_t serialized_location;
|
||||||
int index; // Inside the vector it is stored.
|
int index; // Inside the vector it is stored.
|
||||||
|
int refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FieldDef : public Definition {
|
struct FieldDef : public Definition {
|
||||||
FieldDef() : deprecated(false), required(false), key(false), padding(0) {}
|
FieldDef() : deprecated(false), required(false), key(false),
|
||||||
|
native_inline(false), flexbuffer(false), nested_flatbuffer(NULL),
|
||||||
|
padding(0) {}
|
||||||
|
|
||||||
Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id)
|
Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id,
|
||||||
const;
|
const Parser &parser) const;
|
||||||
|
|
||||||
Value value;
|
Value value;
|
||||||
bool deprecated; // Field is allowed to be present in old data, but can't be
|
bool deprecated; // Field is allowed to be present in old data, but can't be.
|
||||||
// written in new data nor accessed in new code.
|
// written in new data nor accessed in new code.
|
||||||
bool required; // Field must always be present.
|
bool required; // Field must always be present.
|
||||||
bool key; // Field functions as a key for creating sorted vectors.
|
bool key; // Field functions as a key for creating sorted vectors.
|
||||||
|
bool native_inline; // Field will be defined inline (instead of as a pointer)
|
||||||
|
// for native tables if field is a struct.
|
||||||
|
bool flexbuffer; // This field contains FlexBuffer data.
|
||||||
|
StructDef *nested_flatbuffer; // This field contains nested FlatBuffer data.
|
||||||
size_t padding; // Bytes to always pad after this field.
|
size_t padding; // Bytes to always pad after this field.
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -250,15 +272,19 @@ struct StructDef : public Definition {
|
|||||||
if (fields.vec.size()) fields.vec.back()->padding = padding;
|
if (fields.vec.size()) fields.vec.back()->padding = padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
Offset<reflection::Object> Serialize(FlatBufferBuilder *builder) const;
|
Offset<reflection::Object> Serialize(FlatBufferBuilder *builder,
|
||||||
|
const Parser &parser) const;
|
||||||
|
|
||||||
SymbolTable<FieldDef> fields;
|
SymbolTable<FieldDef> fields;
|
||||||
|
|
||||||
bool fixed; // If it's struct, not a table.
|
bool fixed; // If it's struct, not a table.
|
||||||
bool predecl; // If it's used before it was defined.
|
bool predecl; // If it's used before it was defined.
|
||||||
bool sortbysize; // Whether fields come in the declaration or size order.
|
bool sortbysize; // Whether fields come in the declaration or size order.
|
||||||
bool has_key; // It has a key field.
|
bool has_key; // It has a key field.
|
||||||
size_t minalign; // What the whole object needs to be aligned to.
|
size_t minalign; // What the whole object needs to be aligned to.
|
||||||
size_t bytesize; // Size if fixed.
|
size_t bytesize; // Size if fixed.
|
||||||
|
|
||||||
|
flatbuffers::unique_ptr<std::string> original_location;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool IsStruct(const Type &type) {
|
inline bool IsStruct(const Type &type) {
|
||||||
@@ -275,18 +301,18 @@ inline size_t InlineAlignment(const Type &type) {
|
|||||||
|
|
||||||
struct EnumVal {
|
struct EnumVal {
|
||||||
EnumVal(const std::string &_name, int64_t _val)
|
EnumVal(const std::string &_name, int64_t _val)
|
||||||
: name(_name), value(_val), struct_def(nullptr) {}
|
: name(_name), value(_val) {}
|
||||||
|
|
||||||
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder) const;
|
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder) const;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<std::string> doc_comment;
|
std::vector<std::string> doc_comment;
|
||||||
int64_t value;
|
int64_t value;
|
||||||
StructDef *struct_def; // only set if this is a union
|
Type union_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EnumDef : public Definition {
|
struct EnumDef : public Definition {
|
||||||
EnumDef() : is_union(false) {}
|
EnumDef() : is_union(false), uses_type_aliases(false) {}
|
||||||
|
|
||||||
EnumVal *ReverseLookup(int enum_idx, bool skip_union_default = true) {
|
EnumVal *ReverseLookup(int enum_idx, bool skip_union_default = true) {
|
||||||
for (auto it = vals.vec.begin() + static_cast<int>(is_union &&
|
for (auto it = vals.vec.begin() + static_cast<int>(is_union &&
|
||||||
@@ -299,17 +325,38 @@ struct EnumDef : public Definition {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder) const;
|
Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder,
|
||||||
|
const Parser &parser) const;
|
||||||
|
|
||||||
SymbolTable<EnumVal> vals;
|
SymbolTable<EnumVal> vals;
|
||||||
bool is_union;
|
bool is_union;
|
||||||
|
bool uses_type_aliases;
|
||||||
Type underlying_type;
|
Type underlying_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool EqualByName(const Type &a, const Type &b) {
|
||||||
|
return a.base_type == b.base_type && a.element == b.element &&
|
||||||
|
(a.struct_def == b.struct_def ||
|
||||||
|
a.struct_def->name == b.struct_def->name) &&
|
||||||
|
(a.enum_def == b.enum_def ||
|
||||||
|
a.enum_def->name == b.enum_def->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RPCCall {
|
||||||
|
std::string name;
|
||||||
|
SymbolTable<Value> attributes;
|
||||||
|
StructDef *request, *response;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ServiceDef : public Definition {
|
||||||
|
SymbolTable<RPCCall> calls;
|
||||||
|
};
|
||||||
|
|
||||||
// Container of options that may apply to any of the source/text generators.
|
// Container of options that may apply to any of the source/text generators.
|
||||||
struct IDLOptions {
|
struct IDLOptions {
|
||||||
bool strict_json;
|
bool strict_json;
|
||||||
bool skip_js_exports;
|
bool skip_js_exports;
|
||||||
|
bool use_goog_js_export_format;
|
||||||
bool output_default_scalars_in_json;
|
bool output_default_scalars_in_json;
|
||||||
int indent_step;
|
int indent_step;
|
||||||
bool output_enum_identifiers;
|
bool output_enum_identifiers;
|
||||||
@@ -321,15 +368,54 @@ struct IDLOptions {
|
|||||||
bool proto_mode;
|
bool proto_mode;
|
||||||
bool generate_all;
|
bool generate_all;
|
||||||
bool skip_unexpected_fields_in_json;
|
bool skip_unexpected_fields_in_json;
|
||||||
|
bool generate_name_strings;
|
||||||
|
bool generate_object_based_api;
|
||||||
|
std::string cpp_object_api_pointer_type;
|
||||||
|
std::string cpp_object_api_string_type;
|
||||||
|
bool gen_nullable;
|
||||||
|
std::string object_prefix;
|
||||||
|
std::string object_suffix;
|
||||||
|
bool union_value_namespacing;
|
||||||
|
bool allow_non_utf8;
|
||||||
|
std::string include_prefix;
|
||||||
|
bool keep_include_path;
|
||||||
|
bool binary_schema_comments;
|
||||||
|
bool skip_flatbuffers_import;
|
||||||
|
std::string go_import;
|
||||||
|
std::string go_namespace;
|
||||||
|
bool reexport_ts_modules;
|
||||||
|
bool protobuf_ascii_alike;
|
||||||
|
|
||||||
// Possible options for the more general generator below.
|
// Possible options for the more general generator below.
|
||||||
enum Language { kJava, kCSharp, kGo, kMAX };
|
enum Language {
|
||||||
|
kJava = 1 << 0,
|
||||||
|
kCSharp = 1 << 1,
|
||||||
|
kGo = 1 << 2,
|
||||||
|
kCpp = 1 << 3,
|
||||||
|
kJs = 1 << 4,
|
||||||
|
kPython = 1 << 5,
|
||||||
|
kPhp = 1 << 6,
|
||||||
|
kJson = 1 << 7,
|
||||||
|
kBinary = 1 << 8,
|
||||||
|
kTs = 1 << 9,
|
||||||
|
kJsonSchema = 1 << 10,
|
||||||
|
kMAX
|
||||||
|
};
|
||||||
|
|
||||||
Language lang;
|
Language lang;
|
||||||
|
|
||||||
|
enum MiniReflect { kNone, kTypes, kTypesAndNames };
|
||||||
|
|
||||||
|
MiniReflect mini_reflect;
|
||||||
|
|
||||||
|
// The corresponding language bit will be set if a language is included
|
||||||
|
// for code generation.
|
||||||
|
unsigned long lang_to_generate;
|
||||||
|
|
||||||
IDLOptions()
|
IDLOptions()
|
||||||
: strict_json(false),
|
: strict_json(false),
|
||||||
skip_js_exports(false),
|
skip_js_exports(false),
|
||||||
|
use_goog_js_export_format(false),
|
||||||
output_default_scalars_in_json(false),
|
output_default_scalars_in_json(false),
|
||||||
indent_step(2),
|
indent_step(2),
|
||||||
output_enum_identifiers(true), prefixed_enums(true), scoped_enums(false),
|
output_enum_identifiers(true), prefixed_enums(true), scoped_enums(false),
|
||||||
@@ -339,7 +425,34 @@ struct IDLOptions {
|
|||||||
proto_mode(false),
|
proto_mode(false),
|
||||||
generate_all(false),
|
generate_all(false),
|
||||||
skip_unexpected_fields_in_json(false),
|
skip_unexpected_fields_in_json(false),
|
||||||
lang(IDLOptions::kJava) {}
|
generate_name_strings(false),
|
||||||
|
generate_object_based_api(false),
|
||||||
|
cpp_object_api_pointer_type("std::unique_ptr"),
|
||||||
|
gen_nullable(false),
|
||||||
|
object_suffix("T"),
|
||||||
|
union_value_namespacing(true),
|
||||||
|
allow_non_utf8(false),
|
||||||
|
keep_include_path(false),
|
||||||
|
binary_schema_comments(false),
|
||||||
|
skip_flatbuffers_import(false),
|
||||||
|
reexport_ts_modules(true),
|
||||||
|
protobuf_ascii_alike(false),
|
||||||
|
lang(IDLOptions::kJava),
|
||||||
|
mini_reflect(IDLOptions::kNone),
|
||||||
|
lang_to_generate(0) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This encapsulates where the parser is in the current source file.
|
||||||
|
struct ParserState {
|
||||||
|
ParserState() : cursor_(nullptr), line_(1), token_(-1) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char *cursor_;
|
||||||
|
int line_; // the current line being parsed
|
||||||
|
int token_;
|
||||||
|
|
||||||
|
std::string attribute_;
|
||||||
|
std::vector<std::string> doc_comment_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A way to make error propagation less error prone by requiring values to be
|
// A way to make error propagation less error prone by requiring values to be
|
||||||
@@ -383,27 +496,39 @@ class CheckedError {
|
|||||||
#define FLATBUFFERS_CHECKED_ERROR CheckedError
|
#define FLATBUFFERS_CHECKED_ERROR CheckedError
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Parser {
|
class Parser : public ParserState {
|
||||||
public:
|
public:
|
||||||
explicit Parser(const IDLOptions &options = IDLOptions())
|
explicit Parser(const IDLOptions &options = IDLOptions())
|
||||||
: root_struct_def_(nullptr),
|
: current_namespace_(nullptr),
|
||||||
|
empty_namespace_(nullptr),
|
||||||
|
root_struct_def_(nullptr),
|
||||||
opts(options),
|
opts(options),
|
||||||
|
uses_flexbuffers_(false),
|
||||||
source_(nullptr),
|
source_(nullptr),
|
||||||
cursor_(nullptr),
|
|
||||||
line_(1),
|
|
||||||
anonymous_counter(0) {
|
anonymous_counter(0) {
|
||||||
// Just in case none are declared:
|
// Start out with the empty namespace being current.
|
||||||
namespaces_.push_back(new Namespace());
|
empty_namespace_ = new Namespace();
|
||||||
known_attributes_.insert("deprecated");
|
namespaces_.push_back(empty_namespace_);
|
||||||
known_attributes_.insert("required");
|
current_namespace_ = empty_namespace_;
|
||||||
known_attributes_.insert("key");
|
known_attributes_["deprecated"] = true;
|
||||||
known_attributes_.insert("hash");
|
known_attributes_["required"] = true;
|
||||||
known_attributes_.insert("id");
|
known_attributes_["key"] = true;
|
||||||
known_attributes_.insert("force_align");
|
known_attributes_["hash"] = true;
|
||||||
known_attributes_.insert("bit_flags");
|
known_attributes_["id"] = true;
|
||||||
known_attributes_.insert("original_order");
|
known_attributes_["force_align"] = true;
|
||||||
known_attributes_.insert("nested_flatbuffer");
|
known_attributes_["bit_flags"] = true;
|
||||||
known_attributes_.insert("csharp_partial");
|
known_attributes_["original_order"] = true;
|
||||||
|
known_attributes_["nested_flatbuffer"] = true;
|
||||||
|
known_attributes_["csharp_partial"] = true;
|
||||||
|
known_attributes_["streaming"] = true;
|
||||||
|
known_attributes_["idempotent"] = true;
|
||||||
|
known_attributes_["cpp_type"] = true;
|
||||||
|
known_attributes_["cpp_ptr_type"] = true;
|
||||||
|
known_attributes_["cpp_str_type"] = true;
|
||||||
|
known_attributes_["native_inline"] = true;
|
||||||
|
known_attributes_["native_type"] = true;
|
||||||
|
known_attributes_["native_default"] = true;
|
||||||
|
known_attributes_["flexbuffer"] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Parser() {
|
~Parser() {
|
||||||
@@ -421,6 +546,8 @@ class Parser {
|
|||||||
// directory.
|
// directory.
|
||||||
// If the source was loaded from a file and isn't an include file,
|
// If the source was loaded from a file and isn't an include file,
|
||||||
// supply its name in source_filename.
|
// supply its name in source_filename.
|
||||||
|
// All paths specified in this call must be in posix format, if you accept
|
||||||
|
// paths from user input, please call PosixPath on them first.
|
||||||
bool Parse(const char *_source, const char **include_paths = nullptr,
|
bool Parse(const char *_source, const char **include_paths = nullptr,
|
||||||
const char *source_filename = nullptr);
|
const char *source_filename = nullptr);
|
||||||
|
|
||||||
@@ -439,14 +566,28 @@ class Parser {
|
|||||||
// See reflection/reflection.fbs
|
// See reflection/reflection.fbs
|
||||||
void Serialize();
|
void Serialize();
|
||||||
|
|
||||||
FLATBUFFERS_CHECKED_ERROR CheckBitsFit(int64_t val, size_t bits);
|
// Checks that the schema represented by this parser is a safe evolution
|
||||||
|
// of the schema provided. Returns non-empty error on any problems.
|
||||||
|
std::string ConformTo(const Parser &base);
|
||||||
|
|
||||||
|
// Similar to Parse(), but now only accepts JSON to be parsed into a
|
||||||
|
// FlexBuffer.
|
||||||
|
bool ParseFlexBuffer(const char *source, const char *source_filename,
|
||||||
|
flexbuffers::Builder *builder);
|
||||||
|
|
||||||
|
FLATBUFFERS_CHECKED_ERROR CheckInRange(int64_t val, int64_t min, int64_t max);
|
||||||
|
|
||||||
|
StructDef *LookupStruct(const std::string &id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Message(const std::string &msg);
|
||||||
|
void Warning(const std::string &msg);
|
||||||
FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
|
FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, int64_t *val);
|
FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val);
|
||||||
FLATBUFFERS_CHECKED_ERROR Next();
|
FLATBUFFERS_CHECKED_ERROR Next();
|
||||||
FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark();
|
FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark();
|
||||||
bool Is(int t);
|
bool Is(int t);
|
||||||
|
bool IsIdent(const char *id);
|
||||||
FLATBUFFERS_CHECKED_ERROR Expect(int t);
|
FLATBUFFERS_CHECKED_ERROR Expect(int t);
|
||||||
std::string TokenToStringId(int t);
|
std::string TokenToStringId(int t);
|
||||||
EnumDef *LookupEnum(const std::string &id);
|
EnumDef *LookupEnum(const std::string &id);
|
||||||
@@ -458,19 +599,48 @@ private:
|
|||||||
const std::string &name, const Type &type,
|
const std::string &name, const Type &type,
|
||||||
FieldDef **dest);
|
FieldDef **dest);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseField(StructDef &struct_def);
|
FLATBUFFERS_CHECKED_ERROR ParseField(StructDef &struct_def);
|
||||||
|
FLATBUFFERS_CHECKED_ERROR ParseString(Value &val);
|
||||||
|
FLATBUFFERS_CHECKED_ERROR ParseComma();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field,
|
FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field,
|
||||||
size_t parent_fieldn);
|
size_t parent_fieldn,
|
||||||
|
const StructDef *parent_struct_def);
|
||||||
|
#if defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
typedef CheckedError (*ParseTableDelimitersBody)(
|
||||||
|
const std::string &name, size_t &fieldn, const StructDef *struct_def,
|
||||||
|
void *state);
|
||||||
|
#else
|
||||||
|
typedef std::function<CheckedError(const std::string&, size_t&,
|
||||||
|
const StructDef*, void*)>
|
||||||
|
ParseTableDelimitersBody;
|
||||||
|
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn,
|
||||||
|
const StructDef *struct_def,
|
||||||
|
ParseTableDelimitersBody body,
|
||||||
|
void *state);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def,
|
FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def,
|
||||||
std::string *value, uoffset_t *ovalue);
|
std::string *value, uoffset_t *ovalue);
|
||||||
void SerializeStruct(const StructDef &struct_def, const Value &val);
|
void SerializeStruct(const StructDef &struct_def, const Value &val);
|
||||||
void AddVector(bool sortbysize, int count);
|
void AddVector(bool sortbysize, int count);
|
||||||
|
#if defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
typedef CheckedError (*ParseVectorDelimitersBody)(size_t &count,
|
||||||
|
void *state);
|
||||||
|
#else
|
||||||
|
typedef std::function<CheckedError(size_t&, void*)>
|
||||||
|
ParseVectorDelimitersBody;
|
||||||
|
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(
|
||||||
|
size_t &count, ParseVectorDelimitersBody body, void *state);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue);
|
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseMetaData(Definition &def);
|
FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(Value &val, FieldDef *field,
|
||||||
|
size_t fieldn,
|
||||||
|
const StructDef *parent_struct_def);
|
||||||
|
FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
|
||||||
FLATBUFFERS_CHECKED_ERROR TryTypedValue(int dtoken, bool check, Value &e,
|
FLATBUFFERS_CHECKED_ERROR TryTypedValue(int dtoken, bool check, Value &e,
|
||||||
BaseType req, bool *destmatch);
|
BaseType req, bool *destmatch);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field);
|
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field);
|
||||||
|
FLATBUFFERS_CHECKED_ERROR TokenError();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseSingleValue(Value &e);
|
FLATBUFFERS_CHECKED_ERROR ParseSingleValue(Value &e);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseIntegerFromString(Type &type, int64_t *result);
|
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(Type &type, int64_t *result);
|
||||||
StructDef *LookupCreateStruct(const std::string &name,
|
StructDef *LookupCreateStruct(const std::string &name,
|
||||||
bool create_if_new = true,
|
bool create_if_new = true,
|
||||||
bool definition = false);
|
bool definition = false);
|
||||||
@@ -479,6 +649,7 @@ private:
|
|||||||
FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name,
|
FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name,
|
||||||
StructDef **dest);
|
StructDef **dest);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseDecl();
|
FLATBUFFERS_CHECKED_ERROR ParseDecl();
|
||||||
|
FLATBUFFERS_CHECKED_ERROR ParseService();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def,
|
FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def,
|
||||||
bool isextend, bool inside_oneof);
|
bool isextend, bool inside_oneof);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoOption();
|
FLATBUFFERS_CHECKED_ERROR ParseProtoOption();
|
||||||
@@ -487,21 +658,32 @@ private:
|
|||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent();
|
FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type);
|
FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type);
|
||||||
FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue();
|
FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue();
|
||||||
FLATBUFFERS_CHECKED_ERROR SkipJsonObject();
|
FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder);
|
||||||
FLATBUFFERS_CHECKED_ERROR SkipJsonArray();
|
FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
|
||||||
FLATBUFFERS_CHECKED_ERROR SkipJsonString();
|
const char *source_filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
|
FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source,
|
||||||
const char **include_paths,
|
const char **include_paths,
|
||||||
const char *source_filename);
|
const char *source_filename);
|
||||||
|
FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
|
||||||
|
const char **include_paths,
|
||||||
|
const char *source_filename,
|
||||||
|
const char *include_filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef*> &fields,
|
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef*> &fields,
|
||||||
StructDef *struct_def,
|
StructDef *struct_def,
|
||||||
const char *suffix,
|
const char *suffix,
|
||||||
BaseType baseType);
|
BaseType baseType);
|
||||||
|
|
||||||
|
bool SupportsVectorOfUnions() const;
|
||||||
|
Namespace *UniqueNamespace(Namespace *ns);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
SymbolTable<Type> types_;
|
||||||
SymbolTable<StructDef> structs_;
|
SymbolTable<StructDef> structs_;
|
||||||
SymbolTable<EnumDef> enums_;
|
SymbolTable<EnumDef> enums_;
|
||||||
|
SymbolTable<ServiceDef> services_;
|
||||||
std::vector<Namespace *> namespaces_;
|
std::vector<Namespace *> namespaces_;
|
||||||
|
Namespace *current_namespace_;
|
||||||
|
Namespace *empty_namespace_;
|
||||||
std::string error_; // User readable error_ if Parse() == false
|
std::string error_; // User readable error_ if Parse() == false
|
||||||
|
|
||||||
FlatBufferBuilder builder_; // any data contained in the file
|
FlatBufferBuilder builder_; // any data contained in the file
|
||||||
@@ -509,24 +691,22 @@ private:
|
|||||||
std::string file_identifier_;
|
std::string file_identifier_;
|
||||||
std::string file_extension_;
|
std::string file_extension_;
|
||||||
|
|
||||||
std::map<std::string, bool> included_files_;
|
std::map<std::string, std::string> included_files_;
|
||||||
std::map<std::string, std::set<std::string>> files_included_per_file_;
|
std::map<std::string, std::set<std::string>> files_included_per_file_;
|
||||||
|
std::vector<std::string> native_included_files_;
|
||||||
|
|
||||||
|
std::map<std::string, bool> known_attributes_;
|
||||||
|
|
||||||
IDLOptions opts;
|
IDLOptions opts;
|
||||||
|
bool uses_flexbuffers_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *source_, *cursor_;
|
const char *source_;
|
||||||
int line_; // the current line being parsed
|
|
||||||
int token_;
|
|
||||||
std::string file_being_parsed_;
|
std::string file_being_parsed_;
|
||||||
|
|
||||||
std::string attribute_;
|
|
||||||
std::vector<std::string> doc_comment_;
|
|
||||||
|
|
||||||
std::vector<std::pair<Value, FieldDef *>> field_stack_;
|
std::vector<std::pair<Value, FieldDef *>> field_stack_;
|
||||||
|
|
||||||
std::set<std::string> known_attributes_;
|
|
||||||
|
|
||||||
int anonymous_counter;
|
int anonymous_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -534,20 +714,15 @@ private:
|
|||||||
|
|
||||||
extern std::string MakeCamel(const std::string &in, bool first = true);
|
extern std::string MakeCamel(const std::string &in, bool first = true);
|
||||||
|
|
||||||
struct CommentConfig;
|
|
||||||
|
|
||||||
extern void GenComment(const std::vector<std::string> &dc,
|
|
||||||
std::string *code_ptr,
|
|
||||||
const CommentConfig *config,
|
|
||||||
const char *prefix = "");
|
|
||||||
|
|
||||||
// Generate text (JSON) from a given FlatBuffer, and a given Parser
|
// Generate text (JSON) from a given FlatBuffer, and a given Parser
|
||||||
// object that has been populated with the corresponding schema.
|
// object that has been populated with the corresponding schema.
|
||||||
// If ident_step is 0, no indentation will be generated. Additionally,
|
// If ident_step is 0, no indentation will be generated. Additionally,
|
||||||
// if it is less than 0, no linefeeds will be generated either.
|
// if it is less than 0, no linefeeds will be generated either.
|
||||||
// See idl_gen_text.cpp.
|
// See idl_gen_text.cpp.
|
||||||
// strict_json adds "quotes" around field names if true.
|
// strict_json adds "quotes" around field names if true.
|
||||||
extern void GenerateText(const Parser &parser,
|
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
|
||||||
|
// byte arrays in String values), returns false.
|
||||||
|
extern bool GenerateText(const Parser &parser,
|
||||||
const void *flatbuffer,
|
const void *flatbuffer,
|
||||||
std::string *text);
|
std::string *text);
|
||||||
extern bool GenerateTextFile(const Parser &parser,
|
extern bool GenerateTextFile(const Parser &parser,
|
||||||
@@ -569,7 +744,7 @@ extern bool GenerateCPP(const Parser &parser,
|
|||||||
const std::string &path,
|
const std::string &path,
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate JavaScript code from the definitions in the Parser object.
|
// Generate JavaScript or TypeScript code from the definitions in the Parser object.
|
||||||
// See idl_gen_js.
|
// See idl_gen_js.
|
||||||
extern std::string GenerateJS(const Parser &parser);
|
extern std::string GenerateJS(const Parser &parser);
|
||||||
extern bool GenerateJS(const Parser &parser,
|
extern bool GenerateJS(const Parser &parser,
|
||||||
@@ -591,8 +766,8 @@ extern bool GenerateJava(const Parser &parser,
|
|||||||
// Generate Php code from the definitions in the Parser object.
|
// Generate Php code from the definitions in the Parser object.
|
||||||
// See idl_gen_php.
|
// See idl_gen_php.
|
||||||
extern bool GeneratePhp(const Parser &parser,
|
extern bool GeneratePhp(const Parser &parser,
|
||||||
const std::string &path,
|
const std::string &path,
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate Python files from the definitions in the Parser object.
|
// Generate Python files from the definitions in the Parser object.
|
||||||
// See idl_gen_python.cpp.
|
// See idl_gen_python.cpp.
|
||||||
@@ -600,6 +775,12 @@ extern bool GeneratePython(const Parser &parser,
|
|||||||
const std::string &path,
|
const std::string &path,
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
|
// Generate Json schema file
|
||||||
|
// See idl_gen_json_schema.cpp.
|
||||||
|
extern bool GenerateJsonSchema(const Parser &parser,
|
||||||
|
const std::string &path,
|
||||||
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate C# files from the definitions in the Parser object.
|
// Generate C# files from the definitions in the Parser object.
|
||||||
// See idl_gen_csharp.cpp.
|
// See idl_gen_csharp.cpp.
|
||||||
extern bool GenerateCSharp(const Parser &parser,
|
extern bool GenerateCSharp(const Parser &parser,
|
||||||
@@ -620,7 +801,7 @@ extern bool GenerateFBS(const Parser &parser,
|
|||||||
const std::string &path,
|
const std::string &path,
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate a make rule for the generated JavaScript code.
|
// Generate a make rule for the generated JavaScript or TypeScript code.
|
||||||
// See idl_gen_js.cpp.
|
// See idl_gen_js.cpp.
|
||||||
extern std::string JSMakeRule(const Parser &parser,
|
extern std::string JSMakeRule(const Parser &parser,
|
||||||
const std::string &path,
|
const std::string &path,
|
||||||
@@ -650,7 +831,18 @@ extern std::string BinaryMakeRule(const Parser &parser,
|
|||||||
const std::string &path,
|
const std::string &path,
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
|
// Generate GRPC Cpp interfaces.
|
||||||
|
// See idl_gen_grpc.cpp.
|
||||||
|
bool GenerateCppGRPC(const Parser &parser,
|
||||||
|
const std::string &path,
|
||||||
|
const std::string &file_name);
|
||||||
|
|
||||||
|
// Generate GRPC Go interfaces.
|
||||||
|
// See idl_gen_grpc.cpp.
|
||||||
|
bool GenerateGoGRPC(const Parser &parser,
|
||||||
|
const std::string &path,
|
||||||
|
const std::string &file_name);
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|
||||||
#endif // FLATBUFFERS_IDL_H_
|
#endif // FLATBUFFERS_IDL_H_
|
||||||
|
|
||||||
|
|||||||
352
include/flatbuffers/minireflect.h
Normal file
352
include/flatbuffers/minireflect.h
Normal file
@@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_MINIREFLECT_H_
|
||||||
|
#define FLATBUFFERS_MINIREFLECT_H_
|
||||||
|
|
||||||
|
#include "flatbuffers/flatbuffers.h"
|
||||||
|
#include "flatbuffers/util.h"
|
||||||
|
|
||||||
|
namespace flatbuffers {
|
||||||
|
|
||||||
|
// Utilities that can be used with the "mini reflection" tables present
|
||||||
|
// in generated code with --reflect-types (only types) or --reflect-names
|
||||||
|
// (also names).
|
||||||
|
// This allows basic reflection functionality such as pretty-printing
|
||||||
|
// that does not require the use of the schema parser or loading of binary
|
||||||
|
// schema files at runtime (reflection.h).
|
||||||
|
|
||||||
|
// For any of the functions below that take `const TypeTable *`, you pass
|
||||||
|
// `FooTypeTable()` if the type of the root is `Foo`.
|
||||||
|
|
||||||
|
// First, a generic iterator that can be used by multiple algorithms.
|
||||||
|
|
||||||
|
struct IterationVisitor {
|
||||||
|
// These mark the scope of a table or struct.
|
||||||
|
virtual void StartSequence() {}
|
||||||
|
virtual void EndSequence() {}
|
||||||
|
// Called for each field regardless of wether it is present or not.
|
||||||
|
// If not present, val == nullptr. set_idx is the index of all set fields.
|
||||||
|
virtual void Field(size_t /*field_idx*/, size_t /*set_idx*/,
|
||||||
|
ElementaryType /*type*/, bool /*is_vector*/,
|
||||||
|
const TypeTable * /*type_table*/, const char * /*name*/,
|
||||||
|
const uint8_t * /*val*/) {}
|
||||||
|
// Called for a value that is actually present, after a field, or as part
|
||||||
|
// of a vector.
|
||||||
|
virtual void UType(uint8_t, const char *) {}
|
||||||
|
virtual void Bool(bool) {}
|
||||||
|
virtual void Char(int8_t, const char *) {}
|
||||||
|
virtual void UChar(uint8_t, const char *) {}
|
||||||
|
virtual void Short(int16_t, const char *) {}
|
||||||
|
virtual void UShort(uint16_t, const char *) {}
|
||||||
|
virtual void Int(int32_t, const char *) {}
|
||||||
|
virtual void UInt(uint32_t, const char *) {}
|
||||||
|
virtual void Long(int64_t) {}
|
||||||
|
virtual void ULong(uint64_t) {}
|
||||||
|
virtual void Float(float) {}
|
||||||
|
virtual void Double(double) {}
|
||||||
|
virtual void String(const String *) {}
|
||||||
|
virtual void Unknown(const uint8_t *) {} // From a future version.
|
||||||
|
// These mark the scope of a vector.
|
||||||
|
virtual void StartVector() {}
|
||||||
|
virtual void EndVector() {}
|
||||||
|
virtual void Element(size_t /*i*/, ElementaryType /*type*/,
|
||||||
|
const TypeTable * /*type_table*/,
|
||||||
|
const uint8_t * /*val*/)
|
||||||
|
{}
|
||||||
|
virtual ~IterationVisitor() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
|
||||||
|
switch (type) {
|
||||||
|
case ET_UTYPE:
|
||||||
|
case ET_BOOL:
|
||||||
|
case ET_CHAR:
|
||||||
|
case ET_UCHAR:
|
||||||
|
return 1;
|
||||||
|
case ET_SHORT:
|
||||||
|
case ET_USHORT:
|
||||||
|
return 2;
|
||||||
|
case ET_INT:
|
||||||
|
case ET_UINT:
|
||||||
|
case ET_FLOAT:
|
||||||
|
case ET_STRING:
|
||||||
|
return 4;
|
||||||
|
case ET_LONG:
|
||||||
|
case ET_ULONG:
|
||||||
|
case ET_DOUBLE:
|
||||||
|
return 8;
|
||||||
|
case ET_SEQUENCE:
|
||||||
|
switch (type_table->st) {
|
||||||
|
case ST_TABLE:
|
||||||
|
case ST_UNION:
|
||||||
|
return 4;
|
||||||
|
case ST_STRUCT:
|
||||||
|
return type_table->values[type_table->num_elems];
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t LookupEnum(int32_t enum_val, const int32_t *values,
|
||||||
|
size_t num_values) {
|
||||||
|
if (!values) return enum_val;
|
||||||
|
for (size_t i = 0; i < num_values; i++) {
|
||||||
|
if (enum_val == values[i]) return static_cast<int32_t>(i);
|
||||||
|
}
|
||||||
|
return -1; // Unknown enum value.
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> const char *EnumName(T tval, const TypeTable *type_table) {
|
||||||
|
if (!type_table || !type_table->names) return nullptr;
|
||||||
|
auto i = LookupEnum(static_cast<int32_t>(tval), type_table->values,
|
||||||
|
type_table->num_elems);
|
||||||
|
if (i >= 0 && i < static_cast<int32_t>(type_table->num_elems)) {
|
||||||
|
return type_table->names[i];
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
||||||
|
IterationVisitor *visitor);
|
||||||
|
|
||||||
|
inline void IterateValue(ElementaryType type, const uint8_t *val,
|
||||||
|
const TypeTable *type_table,
|
||||||
|
const uint8_t *prev_val,
|
||||||
|
soffset_t vector_index,
|
||||||
|
IterationVisitor *visitor) {
|
||||||
|
switch (type) {
|
||||||
|
case ET_UTYPE: {
|
||||||
|
auto tval = *reinterpret_cast<const uint8_t *>(val);
|
||||||
|
visitor->UType(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_BOOL: {
|
||||||
|
visitor->Bool(*reinterpret_cast<const uint8_t *>(val) != 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_CHAR: {
|
||||||
|
auto tval = *reinterpret_cast<const int8_t *>(val);
|
||||||
|
visitor->Char(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_UCHAR: {
|
||||||
|
auto tval = *reinterpret_cast<const uint8_t *>(val);
|
||||||
|
visitor->UChar(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_SHORT: {
|
||||||
|
auto tval = *reinterpret_cast<const int16_t *>(val);
|
||||||
|
visitor->Short(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_USHORT: {
|
||||||
|
auto tval = *reinterpret_cast<const uint16_t *>(val);
|
||||||
|
visitor->UShort(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_INT: {
|
||||||
|
auto tval = *reinterpret_cast<const int32_t *>(val);
|
||||||
|
visitor->Int(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_UINT: {
|
||||||
|
auto tval = *reinterpret_cast<const uint32_t *>(val);
|
||||||
|
visitor->UInt(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_LONG: {
|
||||||
|
visitor->Long(*reinterpret_cast<const int64_t *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_ULONG: {
|
||||||
|
visitor->ULong(*reinterpret_cast<const uint64_t *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_FLOAT: {
|
||||||
|
visitor->Float(*reinterpret_cast<const float *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_DOUBLE: {
|
||||||
|
visitor->Double(*reinterpret_cast<const double *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_STRING: {
|
||||||
|
val += ReadScalar<uoffset_t>(val);
|
||||||
|
visitor->String(reinterpret_cast<const String *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_SEQUENCE: {
|
||||||
|
switch (type_table->st) {
|
||||||
|
case ST_TABLE:
|
||||||
|
val += ReadScalar<uoffset_t>(val);
|
||||||
|
IterateObject(val, type_table, visitor);
|
||||||
|
break;
|
||||||
|
case ST_STRUCT:
|
||||||
|
IterateObject(val, type_table, visitor);
|
||||||
|
break;
|
||||||
|
case ST_UNION: {
|
||||||
|
val += ReadScalar<uoffset_t>(val);
|
||||||
|
assert(prev_val);
|
||||||
|
auto union_type = *prev_val; // Always a uint8_t.
|
||||||
|
if (vector_index >= 0) {
|
||||||
|
auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(prev_val);
|
||||||
|
union_type = type_vec->Get(static_cast<uoffset_t>(vector_index));
|
||||||
|
}
|
||||||
|
auto type_code_idx = LookupEnum(union_type, type_table->values,
|
||||||
|
type_table->num_elems);
|
||||||
|
if (type_code_idx >= 0 && type_code_idx <
|
||||||
|
static_cast<int32_t>(type_table->num_elems)) {
|
||||||
|
auto type_code = type_table->type_codes[type_code_idx];
|
||||||
|
switch (type_code.base_type) {
|
||||||
|
case ET_SEQUENCE: {
|
||||||
|
auto ref = type_table->type_refs[type_code.sequence_ref]();
|
||||||
|
IterateObject(val, ref, visitor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_STRING:
|
||||||
|
visitor->String(reinterpret_cast<const String *>(val));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
visitor->Unknown(val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
visitor->Unknown(val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ST_ENUM:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
visitor->Unknown(val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
||||||
|
IterationVisitor *visitor) {
|
||||||
|
visitor->StartSequence();
|
||||||
|
const uint8_t *prev_val = nullptr;
|
||||||
|
size_t set_idx = 0;
|
||||||
|
for (size_t i = 0; i < type_table->num_elems; i++) {
|
||||||
|
auto type_code = type_table->type_codes[i];
|
||||||
|
auto type = static_cast<ElementaryType>(type_code.base_type);
|
||||||
|
auto is_vector = type_code.is_vector != 0;
|
||||||
|
auto ref_idx = type_code.sequence_ref;
|
||||||
|
const TypeTable *ref = nullptr;
|
||||||
|
if (ref_idx >= 0) {
|
||||||
|
ref = type_table->type_refs[ref_idx]();
|
||||||
|
}
|
||||||
|
auto name = type_table->names ? type_table->names[i] : nullptr;
|
||||||
|
const uint8_t *val = nullptr;
|
||||||
|
if (type_table->st == ST_TABLE) {
|
||||||
|
val = reinterpret_cast<const Table *>(obj)->GetAddressOf(
|
||||||
|
FieldIndexToOffset(static_cast<voffset_t>(i)));
|
||||||
|
} else {
|
||||||
|
val = obj + type_table->values[i];
|
||||||
|
}
|
||||||
|
visitor->Field(i, set_idx, type, is_vector, ref, name, val);
|
||||||
|
if (val) {
|
||||||
|
set_idx++;
|
||||||
|
if (is_vector) {
|
||||||
|
val += ReadScalar<uoffset_t>(val);
|
||||||
|
auto vec = reinterpret_cast<const Vector<uint8_t> *>(val);
|
||||||
|
visitor->StartVector();
|
||||||
|
auto elem_ptr = vec->Data();
|
||||||
|
for (size_t j = 0; j < vec->size(); j++) {
|
||||||
|
visitor->Element(j, type, ref, elem_ptr);
|
||||||
|
IterateValue(type, elem_ptr, ref, prev_val, static_cast<soffset_t>(j),
|
||||||
|
visitor);
|
||||||
|
elem_ptr += InlineSize(type, ref);
|
||||||
|
}
|
||||||
|
visitor->EndVector();
|
||||||
|
} else {
|
||||||
|
IterateValue(type, val, ref, prev_val, -1, visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev_val = val;
|
||||||
|
}
|
||||||
|
visitor->EndSequence();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void IterateFlatBuffer(const uint8_t *buffer,
|
||||||
|
const TypeTable *type_table,
|
||||||
|
IterationVisitor *callback) {
|
||||||
|
IterateObject(GetRoot<uint8_t>(buffer), type_table, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outputting a Flatbuffer to a string. Tries to conform as close to JSON /
|
||||||
|
// the output generated by idl_gen_text.cpp.
|
||||||
|
|
||||||
|
struct ToStringVisitor : public IterationVisitor {
|
||||||
|
std::string s;
|
||||||
|
void StartSequence() { s += "{ "; }
|
||||||
|
void EndSequence() { s += " }"; }
|
||||||
|
void Field(size_t /*field_idx*/, size_t set_idx, ElementaryType /*type*/,
|
||||||
|
bool /*is_vector*/, const TypeTable * /*type_table*/,
|
||||||
|
const char *name, const uint8_t *val) {
|
||||||
|
if (!val) return;
|
||||||
|
if (set_idx) s += ", ";
|
||||||
|
if (name) { s += name; s += ": "; }
|
||||||
|
}
|
||||||
|
template<typename T> void Named(T x, const char *name) {
|
||||||
|
if (name) s+= name;
|
||||||
|
else s+= NumToString(x);
|
||||||
|
}
|
||||||
|
void UType(uint8_t x, const char *name) { Named(x, name); }
|
||||||
|
void Bool(bool x) { s+= x ? "true" : "false"; }
|
||||||
|
void Char(int8_t x, const char *name) { Named(x, name); }
|
||||||
|
void UChar(uint8_t x, const char *name) { Named(x, name); }
|
||||||
|
void Short(int16_t x, const char *name) { Named(x, name); }
|
||||||
|
void UShort(uint16_t x, const char *name) { Named(x, name); }
|
||||||
|
void Int(int32_t x, const char *name) { Named(x, name); }
|
||||||
|
void UInt(uint32_t x, const char *name) { Named(x, name); }
|
||||||
|
void Long(int64_t x) { s+= NumToString(x); }
|
||||||
|
void ULong(uint64_t x) { s+= NumToString(x); }
|
||||||
|
void Float(float x) { s+= NumToString(x); }
|
||||||
|
void Double(double x) { s+= NumToString(x); }
|
||||||
|
void String(const struct String *str) {
|
||||||
|
EscapeString(str->c_str(), str->size(), &s, true);
|
||||||
|
}
|
||||||
|
void Unknown(const uint8_t *) { s += "(?)"; }
|
||||||
|
void StartVector() { s += "[ "; }
|
||||||
|
void EndVector() { s += " ]"; }
|
||||||
|
void Element(size_t i, ElementaryType /*type*/,
|
||||||
|
const TypeTable * /*type_table*/, const uint8_t * /*val*/) {
|
||||||
|
if (i) s += ", ";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::string FlatBufferToString(const uint8_t *buffer,
|
||||||
|
const TypeTable *type_table) {
|
||||||
|
ToStringVisitor tostring_visitor;
|
||||||
|
IterateFlatBuffer(buffer, type_table, &tostring_visitor);
|
||||||
|
return tostring_visitor.s;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace flatbuffers
|
||||||
|
|
||||||
|
#endif // FLATBUFFERS_MINIREFLECT_H_
|
||||||
@@ -30,6 +30,15 @@ namespace flatbuffers {
|
|||||||
|
|
||||||
// ------------------------- GETTERS -------------------------
|
// ------------------------- GETTERS -------------------------
|
||||||
|
|
||||||
|
inline bool IsScalar (reflection::BaseType t) { return t >= reflection::UType &&
|
||||||
|
t <= reflection::Double; }
|
||||||
|
inline bool IsInteger(reflection::BaseType t) { return t >= reflection::UType &&
|
||||||
|
t <= reflection::ULong; }
|
||||||
|
inline bool IsFloat (reflection::BaseType t) { return t == reflection::Float ||
|
||||||
|
t == reflection::Double; }
|
||||||
|
inline bool IsLong (reflection::BaseType t) { return t == reflection::Long ||
|
||||||
|
t == reflection::ULong; }
|
||||||
|
|
||||||
// Size of a basic type, don't use with structs.
|
// Size of a basic type, don't use with structs.
|
||||||
inline size_t GetTypeSize(reflection::BaseType base_type) {
|
inline size_t GetTypeSize(reflection::BaseType base_type) {
|
||||||
// This needs to correspond to the BaseType enum.
|
// This needs to correspond to the BaseType enum.
|
||||||
@@ -58,6 +67,18 @@ inline const Table *GetAnyRoot(const uint8_t *flatbuf) {
|
|||||||
return GetRoot<Table>(flatbuf);
|
return GetRoot<Table>(flatbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get a field's default, if you know it's an integer, and its exact type.
|
||||||
|
template<typename T> T GetFieldDefaultI(const reflection::Field &field) {
|
||||||
|
assert(sizeof(T) == GetTypeSize(field.type()->base_type()));
|
||||||
|
return static_cast<T>(field.default_integer());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a field's default, if you know it's floating point and its exact type.
|
||||||
|
template<typename T> T GetFieldDefaultF(const reflection::Field &field) {
|
||||||
|
assert(sizeof(T) == GetTypeSize(field.type()->base_type()));
|
||||||
|
return static_cast<T>(field.default_real());
|
||||||
|
}
|
||||||
|
|
||||||
// Get a field, if you know it's an integer, and its exact type.
|
// Get a field, if you know it's an integer, and its exact type.
|
||||||
template<typename T> T GetFieldI(const Table &table,
|
template<typename T> T GetFieldI(const Table &table,
|
||||||
const reflection::Field &field) {
|
const reflection::Field &field) {
|
||||||
@@ -105,6 +126,22 @@ inline Table *GetFieldT(const Table &table,
|
|||||||
return table.GetPointer<Table *>(field.offset());
|
return table.GetPointer<Table *>(field.offset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get a field, if you know it's a struct.
|
||||||
|
inline const Struct *GetFieldStruct(const Table &table,
|
||||||
|
const reflection::Field &field) {
|
||||||
|
// TODO: This does NOT check if the field is a table or struct, but we'd need
|
||||||
|
// access to the schema to check the is_struct flag.
|
||||||
|
assert(field.type()->base_type() == reflection::Obj);
|
||||||
|
return table.GetStruct<const Struct *>(field.offset());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a structure's field, if you know it's a struct.
|
||||||
|
inline const Struct *GetFieldStruct(const Struct &structure,
|
||||||
|
const reflection::Field &field) {
|
||||||
|
assert(field.type()->base_type() == reflection::Obj);
|
||||||
|
return structure.GetStruct<const Struct *>(field.offset());
|
||||||
|
}
|
||||||
|
|
||||||
// Raw helper functions used below: get any value in memory as a 64bit int, a
|
// Raw helper functions used below: get any value in memory as a 64bit int, a
|
||||||
// double or a string.
|
// double or a string.
|
||||||
// All scalars get static_cast to an int64_t, strings use strtoull, every other
|
// All scalars get static_cast to an int64_t, strings use strtoull, every other
|
||||||
@@ -226,8 +263,19 @@ template<typename T> T *GetAnyFieldAddressOf(const Struct &st,
|
|||||||
// Set any scalar field, if you know its exact type.
|
// Set any scalar field, if you know its exact type.
|
||||||
template<typename T> bool SetField(Table *table, const reflection::Field &field,
|
template<typename T> bool SetField(Table *table, const reflection::Field &field,
|
||||||
T val) {
|
T val) {
|
||||||
assert(sizeof(T) == GetTypeSize(field.type()->base_type()));
|
reflection::BaseType type = field.type()->base_type();
|
||||||
return table->SetField(field.offset(), val);
|
if (!IsScalar(type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
assert(sizeof(T) == GetTypeSize(type));
|
||||||
|
T def;
|
||||||
|
if (IsInteger(type)) {
|
||||||
|
def = GetFieldDefaultI<T>(field);
|
||||||
|
} else {
|
||||||
|
assert(IsFloat(type));
|
||||||
|
def = GetFieldDefaultF<T>(field);
|
||||||
|
}
|
||||||
|
return table->SetField(field.offset(), val, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Raw helper functions used below: set any value in memory as a 64bit int, a
|
// Raw helper functions used below: set any value in memory as a 64bit int, a
|
||||||
@@ -242,7 +290,7 @@ void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val);
|
|||||||
inline bool SetAnyFieldI(Table *table, const reflection::Field &field,
|
inline bool SetAnyFieldI(Table *table, const reflection::Field &field,
|
||||||
int64_t val) {
|
int64_t val) {
|
||||||
auto field_ptr = table->GetAddressOf(field.offset());
|
auto field_ptr = table->GetAddressOf(field.offset());
|
||||||
if (!field_ptr) return false;
|
if (!field_ptr) return val == GetFieldDefaultI<int64_t>(field);
|
||||||
SetAnyValueI(field.type()->base_type(), field_ptr, val);
|
SetAnyValueI(field.type()->base_type(), field_ptr, val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -251,7 +299,7 @@ inline bool SetAnyFieldI(Table *table, const reflection::Field &field,
|
|||||||
inline bool SetAnyFieldF(Table *table, const reflection::Field &field,
|
inline bool SetAnyFieldF(Table *table, const reflection::Field &field,
|
||||||
double val) {
|
double val) {
|
||||||
auto field_ptr = table->GetAddressOf(field.offset());
|
auto field_ptr = table->GetAddressOf(field.offset());
|
||||||
if (!field_ptr) return false;
|
if (!field_ptr) return val == GetFieldDefaultF<double>(field);
|
||||||
SetAnyValueF(field.type()->base_type(), field_ptr, val);
|
SetAnyValueF(field.type()->base_type(), field_ptr, val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -313,12 +361,13 @@ template<typename T, typename U> class pointer_inside_vector {
|
|||||||
public:
|
public:
|
||||||
pointer_inside_vector(T *ptr, std::vector<U> &vec)
|
pointer_inside_vector(T *ptr, std::vector<U> &vec)
|
||||||
: offset_(reinterpret_cast<uint8_t *>(ptr) -
|
: offset_(reinterpret_cast<uint8_t *>(ptr) -
|
||||||
reinterpret_cast<uint8_t *>(vec.data())),
|
reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec))),
|
||||||
vec_(vec) {}
|
vec_(vec) {}
|
||||||
|
|
||||||
T *operator*() const {
|
T *operator*() const {
|
||||||
return reinterpret_cast<T *>(
|
return reinterpret_cast<T *>(
|
||||||
reinterpret_cast<uint8_t *>(vec_.data()) + offset_);
|
reinterpret_cast<uint8_t *>(
|
||||||
|
flatbuffers::vector_data(vec_)) + offset_);
|
||||||
}
|
}
|
||||||
T *operator->() const {
|
T *operator->() const {
|
||||||
return operator*();
|
return operator*();
|
||||||
@@ -335,6 +384,8 @@ template<typename T, typename U> pointer_inside_vector<T, U> piv(T *ptr,
|
|||||||
return pointer_inside_vector<T, U>(ptr, vec);
|
return pointer_inside_vector<T, U>(ptr, vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const char *UnionTypeFieldSuffix() { return "_type"; }
|
||||||
|
|
||||||
// Helper to figure out the actual table type a union refers to.
|
// Helper to figure out the actual table type a union refers to.
|
||||||
inline const reflection::Object &GetUnionType(
|
inline const reflection::Object &GetUnionType(
|
||||||
const reflection::Schema &schema, const reflection::Object &parent,
|
const reflection::Schema &schema, const reflection::Object &parent,
|
||||||
@@ -342,7 +393,7 @@ inline const reflection::Object &GetUnionType(
|
|||||||
auto enumdef = schema.enums()->Get(unionfield.type()->index());
|
auto enumdef = schema.enums()->Get(unionfield.type()->index());
|
||||||
// TODO: this is clumsy and slow, but no other way to find it?
|
// TODO: this is clumsy and slow, but no other way to find it?
|
||||||
auto type_field = parent.fields()->LookupByKey(
|
auto type_field = parent.fields()->LookupByKey(
|
||||||
(unionfield.name()->str() + "_type").c_str());
|
(unionfield.name()->str() + UnionTypeFieldSuffix()).c_str());
|
||||||
assert(type_field);
|
assert(type_field);
|
||||||
auto union_type = GetFieldI<uint8_t>(table, *type_field);
|
auto union_type = GetFieldI<uint8_t>(table, *type_field);
|
||||||
auto enumval = enumdef->values()->LookupByKey(union_type);
|
auto enumval = enumdef->values()->LookupByKey(union_type);
|
||||||
@@ -381,7 +432,7 @@ void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
|
|||||||
// Set new elements to "val".
|
// Set new elements to "val".
|
||||||
for (int i = 0; i < delta_elem; i++) {
|
for (int i = 0; i < delta_elem; i++) {
|
||||||
auto loc = newelems + i * sizeof(T);
|
auto loc = newelems + i * sizeof(T);
|
||||||
auto is_scalar = std::is_scalar<T>::value;
|
auto is_scalar = flatbuffers::is_scalar<T>::value;
|
||||||
if (is_scalar) {
|
if (is_scalar) {
|
||||||
WriteScalar(loc, val);
|
WriteScalar(loc, val);
|
||||||
} else { // struct
|
} else { // struct
|
||||||
@@ -415,12 +466,23 @@ inline bool SetFieldT(Table *table, const reflection::Field &field,
|
|||||||
// above resizing functionality has introduced garbage in a buffer you want
|
// above resizing functionality has introduced garbage in a buffer you want
|
||||||
// to remove.
|
// to remove.
|
||||||
// Note: this does not deal with DAGs correctly. If the table passed forms a
|
// Note: this does not deal with DAGs correctly. If the table passed forms a
|
||||||
// DAG, the copy will be a tree instead (with duplicates).
|
// DAG, the copy will be a tree instead (with duplicates). Strings can be
|
||||||
|
// shared however, by passing true for use_string_pooling.
|
||||||
|
|
||||||
Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
||||||
const reflection::Schema &schema,
|
const reflection::Schema &schema,
|
||||||
const reflection::Object &objectdef,
|
const reflection::Object &objectdef,
|
||||||
const Table &table);
|
const Table &table,
|
||||||
|
bool use_string_pooling = false);
|
||||||
|
|
||||||
|
// Verifies the provided flatbuffer using reflection.
|
||||||
|
// root should point to the root type for this flatbuffer.
|
||||||
|
// buf should point to the start of flatbuffer data.
|
||||||
|
// length specifies the size of the flatbuffer data.
|
||||||
|
bool Verify(const reflection::Schema &schema,
|
||||||
|
const reflection::Object &root,
|
||||||
|
const uint8_t *buf,
|
||||||
|
size_t length);
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
131
include/flatbuffers/registry.h
Normal file
131
include/flatbuffers/registry.h
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_REGISTRY_H_
|
||||||
|
#define FLATBUFFERS_REGISTRY_H_
|
||||||
|
|
||||||
|
#include "flatbuffers/idl.h"
|
||||||
|
|
||||||
|
namespace flatbuffers {
|
||||||
|
|
||||||
|
// Convenience class to easily parse or generate text for arbitrary FlatBuffers.
|
||||||
|
// Simply pre-populate it with all schema filenames that may be in use, and
|
||||||
|
// This class will look them up using the file_identifier declared in the
|
||||||
|
// schema.
|
||||||
|
class Registry {
|
||||||
|
public:
|
||||||
|
// Call this for all schemas that may be in use. The identifier has
|
||||||
|
// a function in the generated code, e.g. MonsterIdentifier().
|
||||||
|
void Register(const char *file_identifier, const char *schema_path) {
|
||||||
|
Schema schema;
|
||||||
|
schema.path_ = schema_path;
|
||||||
|
schemas_[file_identifier] = schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate text from an arbitrary FlatBuffer by looking up its
|
||||||
|
// file_identifier in the registry.
|
||||||
|
bool FlatBufferToText(const uint8_t *flatbuf, size_t len,
|
||||||
|
std::string *dest) {
|
||||||
|
// Get the identifier out of the buffer.
|
||||||
|
// If the buffer is truncated, exit.
|
||||||
|
if (len < sizeof(uoffset_t) +
|
||||||
|
FlatBufferBuilder::kFileIdentifierLength) {
|
||||||
|
lasterror_ = "buffer truncated";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string ident(reinterpret_cast<const char *>(flatbuf) +
|
||||||
|
sizeof(uoffset_t),
|
||||||
|
FlatBufferBuilder::kFileIdentifierLength);
|
||||||
|
// Load and parse the schema.
|
||||||
|
Parser parser;
|
||||||
|
if (!LoadSchema(ident, &parser)) return false;
|
||||||
|
// Now we're ready to generate text.
|
||||||
|
if (!GenerateText(parser, flatbuf, dest)) {
|
||||||
|
lasterror_ = "unable to generate text for FlatBuffer binary";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts a binary buffer to text using one of the schemas in the registry,
|
||||||
|
// use the file_identifier to indicate which.
|
||||||
|
// If DetachedBuffer::data() is null then parsing failed.
|
||||||
|
DetachedBuffer TextToFlatBuffer(const char *text,
|
||||||
|
const char *file_identifier) {
|
||||||
|
// Load and parse the schema.
|
||||||
|
Parser parser;
|
||||||
|
if (!LoadSchema(file_identifier, &parser)) return DetachedBuffer();
|
||||||
|
// Parse the text.
|
||||||
|
if (!parser.Parse(text)) {
|
||||||
|
lasterror_ = parser.error_;
|
||||||
|
return DetachedBuffer();
|
||||||
|
}
|
||||||
|
// We have a valid FlatBuffer. Detach it from the builder and return.
|
||||||
|
return parser.builder_.ReleaseBufferPointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify any parsing / output options used by the other functions.
|
||||||
|
void SetOptions(const IDLOptions &opts) { opts_ = opts; }
|
||||||
|
|
||||||
|
// If schemas used contain include statements, call this function for every
|
||||||
|
// directory the parser should search them for.
|
||||||
|
void AddIncludeDirectory(const char *path) {
|
||||||
|
include_paths_.push_back(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a human readable error if any of the above functions fail.
|
||||||
|
const std::string &GetLastError() { return lasterror_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool LoadSchema(const std::string &ident, Parser *parser) {
|
||||||
|
// Find the schema, if not, exit.
|
||||||
|
auto it = schemas_.find(ident);
|
||||||
|
if (it == schemas_.end()) {
|
||||||
|
// Don't attach the identifier, since it may not be human readable.
|
||||||
|
lasterror_ = "identifier for this buffer not in the registry";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto &schema = it->second;
|
||||||
|
// Load the schema from disk. If not, exit.
|
||||||
|
std::string schematext;
|
||||||
|
if (!LoadFile(schema.path_.c_str(), false, &schematext)) {
|
||||||
|
lasterror_ = "could not load schema: " + schema.path_;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Parse schema.
|
||||||
|
parser->opts = opts_;
|
||||||
|
if (!parser->Parse(schematext.c_str(), vector_data(include_paths_),
|
||||||
|
schema.path_.c_str())) {
|
||||||
|
lasterror_ = parser->error_;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Schema {
|
||||||
|
std::string path_;
|
||||||
|
// TODO(wvo) optionally cache schema file or parsed schema here.
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string lasterror_;
|
||||||
|
IDLOptions opts_;
|
||||||
|
std::vector<const char *> include_paths_;
|
||||||
|
std::map<std::string, Schema> schemas_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace flatbuffers
|
||||||
|
|
||||||
|
#endif // FLATBUFFERS_REGISTRY_H_
|
||||||
222
include/flatbuffers/stl_emulation.h
Normal file
222
include/flatbuffers/stl_emulation.h
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_STL_EMULATION_H_
|
||||||
|
#define FLATBUFFERS_STL_EMULATION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#if defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
#define FLATBUFFERS_CPP98_STL
|
||||||
|
#endif // defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
|
||||||
|
#if defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
#include <cctype>
|
||||||
|
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
|
||||||
|
// This header provides backwards compatibility for C++98 STLs like stlport.
|
||||||
|
namespace flatbuffers {
|
||||||
|
|
||||||
|
// Retrieve ::back() from a string in a way that is compatible with pre C++11
|
||||||
|
// STLs (e.g stlport).
|
||||||
|
inline char string_back(const std::string &value) {
|
||||||
|
return value[value.length() - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method that retrieves ::data() from a vector in a way that is
|
||||||
|
// compatible with pre C++11 STLs (e.g stlport).
|
||||||
|
template <typename T> inline T *vector_data(std::vector<T> &vector) {
|
||||||
|
// In some debug environments, operator[] does bounds checking, so &vector[0]
|
||||||
|
// can't be used.
|
||||||
|
return &(*vector.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> inline const T *vector_data(
|
||||||
|
const std::vector<T> &vector) {
|
||||||
|
return &(*vector.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename V>
|
||||||
|
inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
|
||||||
|
#if defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
vector->push_back(data);
|
||||||
|
#else
|
||||||
|
vector->emplace_back(std::forward<V>(data));
|
||||||
|
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
|
#if !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
|
||||||
|
template <typename T>
|
||||||
|
using numeric_limits = std::numeric_limits<T>;
|
||||||
|
#else
|
||||||
|
template <typename T> class numeric_limits :
|
||||||
|
public std::numeric_limits<T> {};
|
||||||
|
#endif // !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
|
||||||
|
#else
|
||||||
|
template <typename T> class numeric_limits :
|
||||||
|
public std::numeric_limits<T> {};
|
||||||
|
|
||||||
|
template <> class numeric_limits<unsigned long long> {
|
||||||
|
public:
|
||||||
|
static unsigned long long min() { return 0ULL; }
|
||||||
|
static unsigned long long max() { return ~0ULL; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> class numeric_limits<long long> {
|
||||||
|
public:
|
||||||
|
static long long min() {
|
||||||
|
return static_cast<long long>(1ULL << ((sizeof(long long) << 3) - 1));
|
||||||
|
}
|
||||||
|
static long long max() {
|
||||||
|
return static_cast<long long>(
|
||||||
|
(1ULL << ((sizeof(long long) << 3) - 1)) - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif // FLATBUFFERS_CPP98_STL
|
||||||
|
|
||||||
|
#if !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
|
||||||
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
|
template <typename T> using is_scalar = std::is_scalar<T>;
|
||||||
|
template <typename T, typename U> using is_same = std::is_same<T,U>;
|
||||||
|
template <typename T> using is_floating_point = std::is_floating_point<T>;
|
||||||
|
template <typename T> using is_unsigned = std::is_unsigned<T>;
|
||||||
|
#else
|
||||||
|
// Map C++ TR1 templates defined by stlport.
|
||||||
|
template <typename T> using is_scalar = std::tr1::is_scalar<T>;
|
||||||
|
template <typename T, typename U> using is_same = std::tr1::is_same<T,U>;
|
||||||
|
template <typename T> using is_floating_point =
|
||||||
|
std::tr1::is_floating_point<T>;
|
||||||
|
template <typename T> using is_unsigned = std::tr1::is_unsigned<T>;
|
||||||
|
#endif // !FLATBUFFERS_CPP98_STL
|
||||||
|
#else
|
||||||
|
// MSVC 2010 doesn't support C++11 aliases.
|
||||||
|
template <typename T> struct is_scalar : public std::is_scalar<T> {};
|
||||||
|
template <typename T, typename U> struct is_same : public std::is_same<T,U> {};
|
||||||
|
template <typename T> struct is_floating_point :
|
||||||
|
public std::is_floating_point<T> {};
|
||||||
|
template <typename T> struct is_unsigned : public std::is_unsigned<T> {};
|
||||||
|
#endif // !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
|
#if !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
|
||||||
|
template <class T> using unique_ptr = std::unique_ptr<T>;
|
||||||
|
#else
|
||||||
|
// MSVC 2010 doesn't support C++11 aliases.
|
||||||
|
// We're manually "aliasing" the class here as we want to bring unique_ptr
|
||||||
|
// into the flatbuffers namespace. We have unique_ptr in the flatbuffers
|
||||||
|
// namespace we have a completely independent implemenation (see below)
|
||||||
|
// for C++98 STL implementations.
|
||||||
|
template <class T> class unique_ptr : public std::unique_ptr<T> {
|
||||||
|
public:
|
||||||
|
unique_ptr() {}
|
||||||
|
explicit unique_ptr(T* p) : std::unique_ptr<T>(p) {}
|
||||||
|
unique_ptr(std::unique_ptr<T>&& u) { *this = std::move(u); }
|
||||||
|
unique_ptr(unique_ptr&& u) { *this = std::move(u); }
|
||||||
|
unique_ptr& operator=(std::unique_ptr<T>&& u) {
|
||||||
|
std::unique_ptr<T>::reset(u.release());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
unique_ptr& operator=(unique_ptr&& u) {
|
||||||
|
std::unique_ptr<T>::reset(u.release());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
unique_ptr& operator=(T* p) {
|
||||||
|
return std::unique_ptr<T>::operator=(p);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif // !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
|
||||||
|
#else
|
||||||
|
// Very limited implementation of unique_ptr.
|
||||||
|
// This is provided simply to allow the C++ code generated from the default
|
||||||
|
// settings to function in C++98 environments with no modifications.
|
||||||
|
template <class T> class unique_ptr {
|
||||||
|
public:
|
||||||
|
typedef T element_type;
|
||||||
|
|
||||||
|
unique_ptr() : ptr_(nullptr) {}
|
||||||
|
explicit unique_ptr(T* p) : ptr_(p) {}
|
||||||
|
unique_ptr(unique_ptr&& u) : ptr_(nullptr) { reset(u.release()); }
|
||||||
|
unique_ptr(const unique_ptr& u) : ptr_(nullptr) {
|
||||||
|
reset(const_cast<unique_ptr*>(&u)->release());
|
||||||
|
}
|
||||||
|
~unique_ptr() { reset(); }
|
||||||
|
|
||||||
|
unique_ptr& operator=(const unique_ptr& u) {
|
||||||
|
reset(const_cast<unique_ptr*>(&u)->release());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr& operator=(unique_ptr&& u) {
|
||||||
|
reset(u.release());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr& operator=(T* p) {
|
||||||
|
reset(p);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& operator*() const { return *ptr_; }
|
||||||
|
T* operator->() const { return ptr_; }
|
||||||
|
T* get() const noexcept { return ptr_; }
|
||||||
|
explicit operator bool() const { return ptr_ != nullptr; }
|
||||||
|
|
||||||
|
// modifiers
|
||||||
|
T* release() {
|
||||||
|
T* value = ptr_;
|
||||||
|
ptr_ = nullptr;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(T* p = nullptr) {
|
||||||
|
T* value = ptr_;
|
||||||
|
ptr_ = p;
|
||||||
|
if (value) delete value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(unique_ptr& u) {
|
||||||
|
T* temp_ptr = ptr_;
|
||||||
|
ptr_ = u.ptr_;
|
||||||
|
u.ptr_ = temp_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* ptr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T> bool operator==(const unique_ptr<T>& x,
|
||||||
|
const unique_ptr<T>& y) {
|
||||||
|
return x.get() == y.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class D> bool operator==(const unique_ptr<T>& x,
|
||||||
|
const D* y) {
|
||||||
|
return static_cast<D*>(x.get()) == y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) {
|
||||||
|
return reinterpret_cast<intptr_t>(x.get()) == y;
|
||||||
|
}
|
||||||
|
#endif // !FLATBUFFERS_CPP98_STL
|
||||||
|
|
||||||
|
} // namespace flatbuffers
|
||||||
|
|
||||||
|
#endif // FLATBUFFERS_STL_EMULATION_H_
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -34,11 +35,13 @@
|
|||||||
#include <winbase.h>
|
#include <winbase.h>
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#else
|
#else
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "flatbuffers/base.h"
|
||||||
|
|
||||||
#include "flatbuffers/flatbuffers.h"
|
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
@@ -57,6 +60,20 @@ template<> inline std::string NumToString<signed char>(signed char t) {
|
|||||||
template<> inline std::string NumToString<unsigned char>(unsigned char t) {
|
template<> inline std::string NumToString<unsigned char>(unsigned char t) {
|
||||||
return NumToString(static_cast<int>(t));
|
return NumToString(static_cast<int>(t));
|
||||||
}
|
}
|
||||||
|
#if defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
template <> inline std::string NumToString<long long>(long long t) {
|
||||||
|
char buf[21]; // (log((1 << 63) - 1) / log(10)) + 2
|
||||||
|
snprintf(buf, sizeof(buf), "%lld", t);
|
||||||
|
return std::string(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> inline std::string NumToString<unsigned long long>(
|
||||||
|
unsigned long long t) {
|
||||||
|
char buf[22]; // (log((1 << 63) - 1) / log(10)) + 1
|
||||||
|
snprintf(buf, sizeof(buf), "%llu", t);
|
||||||
|
return std::string(buf);
|
||||||
|
}
|
||||||
|
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
|
||||||
// Special versions for floats/doubles.
|
// Special versions for floats/doubles.
|
||||||
template<> inline std::string NumToString<double>(double t) {
|
template<> inline std::string NumToString<double>(double t) {
|
||||||
@@ -69,9 +86,8 @@ template<> inline std::string NumToString<double>(double t) {
|
|||||||
// Sadly, std::fixed turns "1" into "1.00000", so here we undo that.
|
// Sadly, std::fixed turns "1" into "1.00000", so here we undo that.
|
||||||
auto p = s.find_last_not_of('0');
|
auto p = s.find_last_not_of('0');
|
||||||
if (p != std::string::npos) {
|
if (p != std::string::npos) {
|
||||||
s.resize(p + 1); // Strip trailing zeroes.
|
// Strip trailing zeroes. If it is a whole number, keep one zero.
|
||||||
if (s[s.size() - 1] == '.')
|
s.resize(p + (s[p] == '.' ? 2 : 1));
|
||||||
s.erase(s.size() - 1, 1); // Strip '.' if a whole number.
|
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@@ -93,50 +109,46 @@ inline std::string IntToStringHex(int i, int xdigits) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Portable implementation of strtoll().
|
// Portable implementation of strtoll().
|
||||||
inline int64_t StringToInt(const char *str, int base = 10) {
|
inline int64_t StringToInt(const char *str, char **endptr = nullptr,
|
||||||
|
int base = 10) {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
return _strtoi64(str, nullptr, base);
|
return _strtoi64(str, endptr, base);
|
||||||
#else
|
#else
|
||||||
return strtoll(str, nullptr, base);
|
return strtoll(str, endptr, base);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Portable implementation of strtoull().
|
// Portable implementation of strtoull().
|
||||||
inline int64_t StringToUInt(const char *str, int base = 10) {
|
inline uint64_t StringToUInt(const char *str, char **endptr = nullptr,
|
||||||
|
int base = 10) {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
return _strtoui64(str, nullptr, base);
|
return _strtoui64(str, endptr, base);
|
||||||
#else
|
#else
|
||||||
return strtoull(str, nullptr, base);
|
return strtoull(str, endptr, base);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef bool (*LoadFileFunction)(const char *filename, bool binary,
|
||||||
|
std::string *dest);
|
||||||
|
typedef bool (*FileExistsFunction)(const char *filename);
|
||||||
|
|
||||||
|
LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function);
|
||||||
|
|
||||||
|
FileExistsFunction SetFileExistsFunction(FileExistsFunction
|
||||||
|
file_exists_function);
|
||||||
|
|
||||||
|
|
||||||
// Check if file "name" exists.
|
// Check if file "name" exists.
|
||||||
inline bool FileExists(const char *name) {
|
bool FileExists(const char *name);
|
||||||
std::ifstream ifs(name);
|
|
||||||
return ifs.good();
|
// Check if "name" exists and it is also a directory.
|
||||||
}
|
bool DirExists(const char *name);
|
||||||
|
|
||||||
// Load file "name" into "buf" returning true if successful
|
// Load file "name" into "buf" returning true if successful
|
||||||
// false otherwise. If "binary" is false data is read
|
// false otherwise. If "binary" is false data is read
|
||||||
// using ifstream's text mode, otherwise data is read with
|
// using ifstream's text mode, otherwise data is read with
|
||||||
// no transcoding.
|
// no transcoding.
|
||||||
inline bool LoadFile(const char *name, bool binary, std::string *buf) {
|
bool LoadFile(const char *name, bool binary, std::string *buf);
|
||||||
std::ifstream ifs(name, binary ? std::ifstream::binary : std::ifstream::in);
|
|
||||||
if (!ifs.is_open()) return false;
|
|
||||||
if (binary) {
|
|
||||||
// The fastest way to read a file into a string.
|
|
||||||
ifs.seekg(0, std::ios::end);
|
|
||||||
(*buf).resize(static_cast<size_t>(ifs.tellg()));
|
|
||||||
ifs.seekg(0, std::ios::beg);
|
|
||||||
ifs.read(&(*buf)[0], (*buf).size());
|
|
||||||
} else {
|
|
||||||
// This is slower, but works correctly on all platforms for text files.
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << ifs.rdbuf();
|
|
||||||
*buf = oss.str();
|
|
||||||
}
|
|
||||||
return !ifs.bad();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save data "buf" of length "len" bytes into a file
|
// Save data "buf" of length "len" bytes into a file
|
||||||
// "name" returning true if successful, false otherwise.
|
// "name" returning true if successful, false otherwise.
|
||||||
@@ -159,16 +171,20 @@ inline bool SaveFile(const char *name, const std::string &buf, bool binary) {
|
|||||||
return SaveFile(name, buf.c_str(), buf.size(), binary);
|
return SaveFile(name, buf.c_str(), buf.size(), binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Functionality for minimalistic portable path handling:
|
// Functionality for minimalistic portable path handling.
|
||||||
|
|
||||||
static const char kPosixPathSeparator = '/';
|
// The functions below behave correctly regardless of whether posix ('/') or
|
||||||
#ifdef _WIN32
|
// Windows ('/' or '\\') separators are used.
|
||||||
static const char kPathSeparator = '\\';
|
|
||||||
|
// Any new separators inserted are always posix.
|
||||||
|
|
||||||
|
// We internally store paths in posix format ('/'). Paths supplied
|
||||||
|
// by the user should go through PosixPath to ensure correct behavior
|
||||||
|
// on Windows when paths are string-compared.
|
||||||
|
|
||||||
|
static const char kPathSeparator = '/';
|
||||||
|
static const char kPathSeparatorWindows = '\\';
|
||||||
static const char *PathSeparatorSet = "\\/"; // Intentionally no ':'
|
static const char *PathSeparatorSet = "\\/"; // Intentionally no ':'
|
||||||
#else
|
|
||||||
static const char kPathSeparator = kPosixPathSeparator;
|
|
||||||
static const char *PathSeparatorSet = "/";
|
|
||||||
#endif // _WIN32
|
|
||||||
|
|
||||||
// Returns the path with the extension, if any, removed.
|
// Returns the path with the extension, if any, removed.
|
||||||
inline std::string StripExtension(const std::string &filepath) {
|
inline std::string StripExtension(const std::string &filepath) {
|
||||||
@@ -199,13 +215,25 @@ inline std::string StripFileName(const std::string &filepath) {
|
|||||||
inline std::string ConCatPathFileName(const std::string &path,
|
inline std::string ConCatPathFileName(const std::string &path,
|
||||||
const std::string &filename) {
|
const std::string &filename) {
|
||||||
std::string filepath = path;
|
std::string filepath = path;
|
||||||
if (path.length() && path[path.size() - 1] != kPathSeparator &&
|
if (filepath.length()) {
|
||||||
path[path.size() - 1] != kPosixPathSeparator)
|
char filepath_last_character = string_back(filepath);
|
||||||
filepath += kPathSeparator;
|
if (filepath_last_character == kPathSeparatorWindows) {
|
||||||
|
filepath_last_character = kPathSeparator;
|
||||||
|
} else if (filepath_last_character != kPathSeparator) {
|
||||||
|
filepath += kPathSeparator;
|
||||||
|
}
|
||||||
|
}
|
||||||
filepath += filename;
|
filepath += filename;
|
||||||
return filepath;
|
return filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replaces any '\\' separators with '/'
|
||||||
|
inline std::string PosixPath(const char *path) {
|
||||||
|
std::string p = path;
|
||||||
|
std::replace(p.begin(), p.end(), '\\', '/');
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
// This function ensure a directory exists, by recursively
|
// This function ensure a directory exists, by recursively
|
||||||
// creating dirs for any parts of the path that don't exist yet.
|
// creating dirs for any parts of the path that don't exist yet.
|
||||||
inline void EnsureDirExists(const std::string &filepath) {
|
inline void EnsureDirExists(const std::string &filepath) {
|
||||||
@@ -280,6 +308,10 @@ inline int FromUTF8(const char **in) {
|
|||||||
}
|
}
|
||||||
if ((**in << len) & 0x80) return -1; // Bit after leading 1's must be 0.
|
if ((**in << len) & 0x80) return -1; // Bit after leading 1's must be 0.
|
||||||
if (!len) return *(*in)++;
|
if (!len) return *(*in)++;
|
||||||
|
// UTF-8 encoded values with a length are between 2 and 4 bytes.
|
||||||
|
if (len < 2 || len > 4) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
// Grab initial bits of the code.
|
// Grab initial bits of the code.
|
||||||
int ucc = *(*in)++ & ((1 << (7 - len)) - 1);
|
int ucc = *(*in)++ & ((1 << (7 - len)) - 1);
|
||||||
for (int i = 0; i < len - 1; i++) {
|
for (int i = 0; i < len - 1; i++) {
|
||||||
@@ -287,6 +319,32 @@ inline int FromUTF8(const char **in) {
|
|||||||
ucc <<= 6;
|
ucc <<= 6;
|
||||||
ucc |= *(*in)++ & 0x3F; // Grab 6 more bits of the code.
|
ucc |= *(*in)++ & 0x3F; // Grab 6 more bits of the code.
|
||||||
}
|
}
|
||||||
|
// UTF-8 cannot encode values between 0xD800 and 0xDFFF (reserved for
|
||||||
|
// UTF-16 surrogate pairs).
|
||||||
|
if (ucc >= 0xD800 && ucc <= 0xDFFF) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// UTF-8 must represent code points in their shortest possible encoding.
|
||||||
|
switch (len) {
|
||||||
|
case 2:
|
||||||
|
// Two bytes of UTF-8 can represent code points from U+0080 to U+07FF.
|
||||||
|
if (ucc < 0x0080 || ucc > 0x07FF) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// Three bytes of UTF-8 can represent code points from U+0800 to U+FFFF.
|
||||||
|
if (ucc < 0x0800 || ucc > 0xFFFF) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
// Four bytes of UTF-8 can represent code points from U+10000 to U+10FFFF.
|
||||||
|
if (ucc < 0x10000 || ucc > 0x10FFFF) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
return ucc;
|
return ucc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,6 +375,72 @@ inline std::string WordWrap(const std::string in, size_t max_length,
|
|||||||
return wrapped;
|
return wrapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool EscapeString(const char *s, size_t length, std::string *_text,
|
||||||
|
bool allow_non_utf8) {
|
||||||
|
std::string &text = *_text;
|
||||||
|
text += "\"";
|
||||||
|
for (uoffset_t i = 0; i < length; i++) {
|
||||||
|
char c = s[i];
|
||||||
|
switch (c) {
|
||||||
|
case '\n': text += "\\n"; break;
|
||||||
|
case '\t': text += "\\t"; break;
|
||||||
|
case '\r': text += "\\r"; break;
|
||||||
|
case '\b': text += "\\b"; break;
|
||||||
|
case '\f': text += "\\f"; break;
|
||||||
|
case '\"': text += "\\\""; break;
|
||||||
|
case '\\': text += "\\\\"; break;
|
||||||
|
default:
|
||||||
|
if (c >= ' ' && c <= '~') {
|
||||||
|
text += c;
|
||||||
|
} else {
|
||||||
|
// Not printable ASCII data. Let's see if it's valid UTF-8 first:
|
||||||
|
const char *utf8 = s + i;
|
||||||
|
int ucc = FromUTF8(&utf8);
|
||||||
|
if (ucc < 0) {
|
||||||
|
if (allow_non_utf8) {
|
||||||
|
text += "\\x";
|
||||||
|
text += IntToStringHex(static_cast<uint8_t>(c), 2);
|
||||||
|
} else {
|
||||||
|
// There are two cases here:
|
||||||
|
//
|
||||||
|
// 1) We reached here by parsing an IDL file. In that case,
|
||||||
|
// we previously checked for non-UTF-8, so we shouldn't reach
|
||||||
|
// here.
|
||||||
|
//
|
||||||
|
// 2) We reached here by someone calling GenerateText()
|
||||||
|
// on a previously-serialized flatbuffer. The data might have
|
||||||
|
// non-UTF-8 Strings, or might be corrupt.
|
||||||
|
//
|
||||||
|
// In both cases, we have to give up and inform the caller
|
||||||
|
// they have no JSON.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ucc <= 0xFFFF) {
|
||||||
|
// Parses as Unicode within JSON's \uXXXX range, so use that.
|
||||||
|
text += "\\u";
|
||||||
|
text += IntToStringHex(ucc, 4);
|
||||||
|
} else if (ucc <= 0x10FFFF) {
|
||||||
|
// Encode Unicode SMP values to a surrogate pair using two \u escapes.
|
||||||
|
uint32_t base = ucc - 0x10000;
|
||||||
|
auto high_surrogate = (base >> 10) + 0xD800;
|
||||||
|
auto low_surrogate = (base & 0x03FF) + 0xDC00;
|
||||||
|
text += "\\u";
|
||||||
|
text += IntToStringHex(high_surrogate, 4);
|
||||||
|
text += "\\u";
|
||||||
|
text += IntToStringHex(low_surrogate, 4);
|
||||||
|
}
|
||||||
|
// Skip past characters recognized.
|
||||||
|
i = static_cast<uoffset_t>(utf8 - s - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
text += "\"";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|
||||||
#endif // FLATBUFFERS_UTIL_H_
|
#endif // FLATBUFFERS_UTIL_H_
|
||||||
|
|||||||
@@ -23,10 +23,18 @@ package com.google.flatbuffers;
|
|||||||
*/
|
*/
|
||||||
public class Constants {
|
public class Constants {
|
||||||
// Java doesn't seem to have these.
|
// Java doesn't seem to have these.
|
||||||
|
/** The number of bytes in an `byte`. */
|
||||||
|
static final int SIZEOF_BYTE = 1;
|
||||||
/** The number of bytes in a `short`. */
|
/** The number of bytes in a `short`. */
|
||||||
static final int SIZEOF_SHORT = 2;
|
static final int SIZEOF_SHORT = 2;
|
||||||
/** The number of bytes in an `int`. */
|
/** The number of bytes in an `int`. */
|
||||||
static final int SIZEOF_INT = 4;
|
static final int SIZEOF_INT = 4;
|
||||||
|
/** The number of bytes in an `float`. */
|
||||||
|
static final int SIZEOF_FLOAT = 4;
|
||||||
|
/** The number of bytes in an `long`. */
|
||||||
|
static final int SIZEOF_LONG = 8;
|
||||||
|
/** The number of bytes in an `double`. */
|
||||||
|
static final int SIZEOF_DOUBLE = 8;
|
||||||
/** The number of bytes in a file identifier. */
|
/** The number of bytes in a file identifier. */
|
||||||
static final int FILE_IDENTIFIER_LENGTH = 4;
|
static final int FILE_IDENTIFIER_LENGTH = 4;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,14 @@
|
|||||||
package com.google.flatbuffers;
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
import static com.google.flatbuffers.Constants.*;
|
import static com.google.flatbuffers.Constants.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.*;
|
||||||
|
import java.nio.charset.CharacterCodingException;
|
||||||
|
import java.nio.charset.CharsetEncoder;
|
||||||
|
import java.nio.charset.CoderResult;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
/// @file
|
/// @file
|
||||||
@@ -28,8 +33,7 @@ import java.nio.charset.Charset;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that helps you build a FlatBuffer. See the section
|
* Class that helps you build a FlatBuffer. See the section
|
||||||
* @ref flatbuffers_guide_use_java_c-sharp "Use in Java/C#" in the
|
* "Use in Java/C#" in the main FlatBuffers documentation.
|
||||||
* main FlatBuffers documentation.
|
|
||||||
*/
|
*/
|
||||||
public class FlatBufferBuilder {
|
public class FlatBufferBuilder {
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
@@ -46,26 +50,53 @@ public class FlatBufferBuilder {
|
|||||||
int num_vtables = 0; // Number of entries in `vtables` in use.
|
int num_vtables = 0; // Number of entries in `vtables` in use.
|
||||||
int vector_num_elems = 0; // For the current vector being built.
|
int vector_num_elems = 0; // For the current vector being built.
|
||||||
boolean force_defaults = false; // False omits default values from the serialized data.
|
boolean force_defaults = false; // False omits default values from the serialized data.
|
||||||
|
CharsetEncoder encoder = utf8charset.newEncoder();
|
||||||
|
ByteBuffer dst;
|
||||||
|
ByteBufferFactory bb_factory; // Factory for allocating the internal buffer
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start with a buffer of size `initial_size`, then grow as required.
|
||||||
|
*
|
||||||
|
* @param initial_size The initial size of the internal buffer to use.
|
||||||
|
* @param bb_factory The factory to be used for allocating the internal buffer
|
||||||
|
*/
|
||||||
|
public FlatBufferBuilder(int initial_size, ByteBufferFactory bb_factory) {
|
||||||
|
if (initial_size <= 0) initial_size = 1;
|
||||||
|
space = initial_size;
|
||||||
|
this.bb_factory = bb_factory;
|
||||||
|
bb = bb_factory.newByteBuffer(initial_size);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start with a buffer of size `initial_size`, then grow as required.
|
* Start with a buffer of size `initial_size`, then grow as required.
|
||||||
*
|
*
|
||||||
* @param initial_size The initial size of the internal buffer to use.
|
* @param initial_size The initial size of the internal buffer to use.
|
||||||
*/
|
*/
|
||||||
public FlatBufferBuilder(int initial_size) {
|
public FlatBufferBuilder(int initial_size) {
|
||||||
if (initial_size <= 0) initial_size = 1;
|
this(initial_size, new HeapByteBufferFactory());
|
||||||
space = initial_size;
|
|
||||||
bb = newByteBuffer(initial_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start with a buffer of 1KiB, then grow as required.
|
* Start with a buffer of 1KiB, then grow as required.
|
||||||
*/
|
*/
|
||||||
public FlatBufferBuilder() {
|
public FlatBufferBuilder() {
|
||||||
this(1024);
|
this(1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alternative constructor allowing reuse of {@link ByteBuffer}s. The builder
|
||||||
|
* can still grow the buffer as necessary. User classes should make sure
|
||||||
|
* to call {@link #dataBuffer()} to obtain the resulting encoded message.
|
||||||
|
*
|
||||||
|
* @param existing_bb The byte buffer to reuse.
|
||||||
|
* @param bb_factory The factory to be used for allocating a new internal buffer if
|
||||||
|
* the existing buffer needs to grow
|
||||||
|
*/
|
||||||
|
public FlatBufferBuilder(ByteBuffer existing_bb, ByteBufferFactory bb_factory) {
|
||||||
|
init(existing_bb, bb_factory);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alternative constructor allowing reuse of {@link ByteBuffer}s. The builder
|
* Alternative constructor allowing reuse of {@link ByteBuffer}s. The builder
|
||||||
* can still grow the buffer as necessary. User classes should make sure
|
* can still grow the buffer as necessary. User classes should make sure
|
||||||
@@ -74,7 +105,7 @@ public class FlatBufferBuilder {
|
|||||||
* @param existing_bb The byte buffer to reuse.
|
* @param existing_bb The byte buffer to reuse.
|
||||||
*/
|
*/
|
||||||
public FlatBufferBuilder(ByteBuffer existing_bb) {
|
public FlatBufferBuilder(ByteBuffer existing_bb) {
|
||||||
init(existing_bb);
|
init(existing_bb, new HeapByteBufferFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,9 +114,12 @@ public class FlatBufferBuilder {
|
|||||||
* objects that have been allocated for temporary storage.
|
* objects that have been allocated for temporary storage.
|
||||||
*
|
*
|
||||||
* @param existing_bb The byte buffer to reuse.
|
* @param existing_bb The byte buffer to reuse.
|
||||||
|
* @param bb_factory The factory to be used for allocating a new internal buffer if
|
||||||
|
* the existing buffer needs to grow
|
||||||
* @return Returns `this`.
|
* @return Returns `this`.
|
||||||
*/
|
*/
|
||||||
public FlatBufferBuilder init(ByteBuffer existing_bb){
|
public FlatBufferBuilder init(ByteBuffer existing_bb, ByteBufferFactory bb_factory){
|
||||||
|
this.bb_factory = bb_factory;
|
||||||
bb = existing_bb;
|
bb = existing_bb;
|
||||||
bb.clear();
|
bb.clear();
|
||||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
@@ -100,17 +134,53 @@ public class FlatBufferBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
|
||||||
/**
|
/**
|
||||||
* Create a `ByteBuffer` with a given capacity.
|
* An interface that provides a user of the FlatBufferBuilder class the ability to specify
|
||||||
|
* the method in which the internal buffer gets allocated. This allows for alternatives
|
||||||
|
* to the default behavior, which is to allocate memory for a new byte-array
|
||||||
|
* backed `ByteBuffer` array inside the JVM.
|
||||||
*
|
*
|
||||||
* @param capacity The size of the `ByteBuffer` to allocate.
|
* The FlatBufferBuilder class contains the HeapByteBufferFactory class to
|
||||||
* @return Returns the new `ByteBuffer` that was allocated.
|
* preserve the default behavior in the event that the user does not provide
|
||||||
|
* their own implementation of this interface.
|
||||||
*/
|
*/
|
||||||
static ByteBuffer newByteBuffer(int capacity) {
|
public interface ByteBufferFactory {
|
||||||
ByteBuffer newbb = ByteBuffer.allocate(capacity);
|
/**
|
||||||
newbb.order(ByteOrder.LITTLE_ENDIAN);
|
* Create a `ByteBuffer` with a given capacity.
|
||||||
return newbb;
|
*
|
||||||
|
* @param capacity The size of the `ByteBuffer` to allocate.
|
||||||
|
* @return Returns the new `ByteBuffer` that was allocated.
|
||||||
|
*/
|
||||||
|
ByteBuffer newByteBuffer(int capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of the ByteBufferFactory interface that is used when
|
||||||
|
* one is not provided by the user.
|
||||||
|
*
|
||||||
|
* Allocate memory for a new byte-array backed `ByteBuffer` array inside the JVM.
|
||||||
|
*/
|
||||||
|
public static final class HeapByteBufferFactory implements ByteBufferFactory {
|
||||||
|
@Override
|
||||||
|
public ByteBuffer newByteBuffer(int capacity) {
|
||||||
|
return ByteBuffer.allocate(capacity).order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the FlatBufferBuilder by purging all data that it holds.
|
||||||
|
*/
|
||||||
|
public void clear(){
|
||||||
|
space = bb.capacity();
|
||||||
|
bb.clear();
|
||||||
|
minalign = 1;
|
||||||
|
while(vtable_in_use > 0) vtable[--vtable_in_use] = 0;
|
||||||
|
vtable_in_use = 0;
|
||||||
|
nested = false;
|
||||||
|
finished = false;
|
||||||
|
object_start = 0;
|
||||||
|
num_vtables = 0;
|
||||||
|
vector_num_elems = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,16 +188,17 @@ public class FlatBufferBuilder {
|
|||||||
* end of the new buffer (since we build the buffer backwards).
|
* end of the new buffer (since we build the buffer backwards).
|
||||||
*
|
*
|
||||||
* @param bb The current buffer with the existing data.
|
* @param bb The current buffer with the existing data.
|
||||||
|
* @param bb_factory The factory to be used for allocating the new internal buffer
|
||||||
* @return A new byte buffer with the old data copied copied to it. The data is
|
* @return A new byte buffer with the old data copied copied to it. The data is
|
||||||
* located at the end of the buffer.
|
* located at the end of the buffer.
|
||||||
*/
|
*/
|
||||||
static ByteBuffer growByteBuffer(ByteBuffer bb) {
|
static ByteBuffer growByteBuffer(ByteBuffer bb, ByteBufferFactory bb_factory) {
|
||||||
int old_buf_size = bb.capacity();
|
int old_buf_size = bb.capacity();
|
||||||
if ((old_buf_size & 0xC0000000) != 0) // Ensure we don't grow beyond what fits in an int.
|
if ((old_buf_size & 0xC0000000) != 0) // Ensure we don't grow beyond what fits in an int.
|
||||||
throw new AssertionError("FlatBuffers: cannot grow buffer beyond 2 gigabytes.");
|
throw new AssertionError("FlatBuffers: cannot grow buffer beyond 2 gigabytes.");
|
||||||
int new_buf_size = old_buf_size << 1;
|
int new_buf_size = old_buf_size << 1;
|
||||||
bb.position(0);
|
bb.position(0);
|
||||||
ByteBuffer nbb = newByteBuffer(new_buf_size);
|
ByteBuffer nbb = bb_factory.newByteBuffer(new_buf_size);
|
||||||
nbb.position(new_buf_size - old_buf_size);
|
nbb.position(new_buf_size - old_buf_size);
|
||||||
nbb.put(bb);
|
nbb.put(bb);
|
||||||
return nbb;
|
return nbb;
|
||||||
@@ -170,7 +241,7 @@ public class FlatBufferBuilder {
|
|||||||
// Reallocate the buffer if needed.
|
// Reallocate the buffer if needed.
|
||||||
while (space < align_size + size + additional_bytes) {
|
while (space < align_size + size + additional_bytes) {
|
||||||
int old_buf_size = bb.capacity();
|
int old_buf_size = bb.capacity();
|
||||||
bb = growByteBuffer(bb);
|
bb = growByteBuffer(bb, bb_factory);
|
||||||
space += bb.capacity() - old_buf_size;
|
space += bb.capacity() - old_buf_size;
|
||||||
}
|
}
|
||||||
pad(align_size);
|
pad(align_size);
|
||||||
@@ -182,7 +253,7 @@ public class FlatBufferBuilder {
|
|||||||
*
|
*
|
||||||
* @param x A `boolean` to put into the buffer.
|
* @param x A `boolean` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void putBoolean(boolean x) { bb.put (space -= 1, (byte)(x ? 1 : 0)); }
|
public void putBoolean(boolean x) { bb.put (space -= Constants.SIZEOF_BYTE, (byte)(x ? 1 : 0)); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a `byte` to the buffer, backwards from the current location. Doesn't align nor
|
* Add a `byte` to the buffer, backwards from the current location. Doesn't align nor
|
||||||
@@ -190,7 +261,7 @@ public class FlatBufferBuilder {
|
|||||||
*
|
*
|
||||||
* @param x A `byte` to put into the buffer.
|
* @param x A `byte` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void putByte (byte x) { bb.put (space -= 1, x); }
|
public void putByte (byte x) { bb.put (space -= Constants.SIZEOF_BYTE, x); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a `short` to the buffer, backwards from the current location. Doesn't align nor
|
* Add a `short` to the buffer, backwards from the current location. Doesn't align nor
|
||||||
@@ -198,7 +269,7 @@ public class FlatBufferBuilder {
|
|||||||
*
|
*
|
||||||
* @param x A `short` to put into the buffer.
|
* @param x A `short` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void putShort (short x) { bb.putShort (space -= 2, x); }
|
public void putShort (short x) { bb.putShort (space -= Constants.SIZEOF_SHORT, x); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an `int` to the buffer, backwards from the current location. Doesn't align nor
|
* Add an `int` to the buffer, backwards from the current location. Doesn't align nor
|
||||||
@@ -206,7 +277,7 @@ public class FlatBufferBuilder {
|
|||||||
*
|
*
|
||||||
* @param x An `int` to put into the buffer.
|
* @param x An `int` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void putInt (int x) { bb.putInt (space -= 4, x); }
|
public void putInt (int x) { bb.putInt (space -= Constants.SIZEOF_INT, x); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a `long` to the buffer, backwards from the current location. Doesn't align nor
|
* Add a `long` to the buffer, backwards from the current location. Doesn't align nor
|
||||||
@@ -214,7 +285,7 @@ public class FlatBufferBuilder {
|
|||||||
*
|
*
|
||||||
* @param x A `long` to put into the buffer.
|
* @param x A `long` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void putLong (long x) { bb.putLong (space -= 8, x); }
|
public void putLong (long x) { bb.putLong (space -= Constants.SIZEOF_LONG, x); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a `float` to the buffer, backwards from the current location. Doesn't align nor
|
* Add a `float` to the buffer, backwards from the current location. Doesn't align nor
|
||||||
@@ -222,7 +293,7 @@ public class FlatBufferBuilder {
|
|||||||
*
|
*
|
||||||
* @param x A `float` to put into the buffer.
|
* @param x A `float` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void putFloat (float x) { bb.putFloat (space -= 4, x); }
|
public void putFloat (float x) { bb.putFloat (space -= Constants.SIZEOF_FLOAT, x); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a `double` to the buffer, backwards from the current location. Doesn't align nor
|
* Add a `double` to the buffer, backwards from the current location. Doesn't align nor
|
||||||
@@ -230,7 +301,7 @@ public class FlatBufferBuilder {
|
|||||||
*
|
*
|
||||||
* @param x A `double` to put into the buffer.
|
* @param x A `double` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void putDouble (double x) { bb.putDouble(space -= 8, x); }
|
public void putDouble (double x) { bb.putDouble(space -= Constants.SIZEOF_DOUBLE, x); }
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -238,49 +309,49 @@ public class FlatBufferBuilder {
|
|||||||
*
|
*
|
||||||
* @param x A `boolean` to put into the buffer.
|
* @param x A `boolean` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void addBoolean(boolean x) { prep(1, 0); putBoolean(x); }
|
public void addBoolean(boolean x) { prep(Constants.SIZEOF_BYTE, 0); putBoolean(x); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a `byte` to the buffer, properly aligned, and grows the buffer (if necessary).
|
* Add a `byte` to the buffer, properly aligned, and grows the buffer (if necessary).
|
||||||
*
|
*
|
||||||
* @param x A `byte` to put into the buffer.
|
* @param x A `byte` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void addByte (byte x) { prep(1, 0); putByte (x); }
|
public void addByte (byte x) { prep(Constants.SIZEOF_BYTE, 0); putByte (x); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a `short` to the buffer, properly aligned, and grows the buffer (if necessary).
|
* Add a `short` to the buffer, properly aligned, and grows the buffer (if necessary).
|
||||||
*
|
*
|
||||||
* @param x A `short` to put into the buffer.
|
* @param x A `short` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void addShort (short x) { prep(2, 0); putShort (x); }
|
public void addShort (short x) { prep(Constants.SIZEOF_SHORT, 0); putShort (x); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an `int` to the buffer, properly aligned, and grows the buffer (if necessary).
|
* Add an `int` to the buffer, properly aligned, and grows the buffer (if necessary).
|
||||||
*
|
*
|
||||||
* @param x An `int` to put into the buffer.
|
* @param x An `int` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void addInt (int x) { prep(4, 0); putInt (x); }
|
public void addInt (int x) { prep(Constants.SIZEOF_INT, 0); putInt (x); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a `long` to the buffer, properly aligned, and grows the buffer (if necessary).
|
* Add a `long` to the buffer, properly aligned, and grows the buffer (if necessary).
|
||||||
*
|
*
|
||||||
* @param x A `long` to put into the buffer.
|
* @param x A `long` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void addLong (long x) { prep(8, 0); putLong (x); }
|
public void addLong (long x) { prep(Constants.SIZEOF_LONG, 0); putLong (x); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a `float` to the buffer, properly aligned, and grows the buffer (if necessary).
|
* Add a `float` to the buffer, properly aligned, and grows the buffer (if necessary).
|
||||||
*
|
*
|
||||||
* @param x A `float` to put into the buffer.
|
* @param x A `float` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void addFloat (float x) { prep(4, 0); putFloat (x); }
|
public void addFloat (float x) { prep(Constants.SIZEOF_FLOAT, 0); putFloat (x); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a `double` to the buffer, properly aligned, and grows the buffer (if necessary).
|
* Add a `double` to the buffer, properly aligned, and grows the buffer (if necessary).
|
||||||
*
|
*
|
||||||
* @param x A `double` to put into the buffer.
|
* @param x A `double` to put into the buffer.
|
||||||
*/
|
*/
|
||||||
public void addDouble (double x) { prep(8, 0); putDouble (x); }
|
public void addDouble (double x) { prep(Constants.SIZEOF_DOUBLE, 0); putDouble (x); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds on offset, relative to where it will be written.
|
* Adds on offset, relative to where it will be written.
|
||||||
@@ -361,19 +432,82 @@ public class FlatBufferBuilder {
|
|||||||
}
|
}
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new array/vector and return a ByteBuffer to be filled later.
|
||||||
|
* Call {@link #endVector} after this method to get an offset to the beginning
|
||||||
|
* of vector.
|
||||||
|
*
|
||||||
|
* @param elem_size the size of each element in bytes.
|
||||||
|
* @param num_elems number of elements in the vector.
|
||||||
|
* @param alignment byte alignment.
|
||||||
|
* @return ByteBuffer with position and limit set to the space allocated for the array.
|
||||||
|
*/
|
||||||
|
public ByteBuffer createUnintializedVector(int elem_size, int num_elems, int alignment) {
|
||||||
|
int length = elem_size * num_elems;
|
||||||
|
startVector(elem_size, num_elems, alignment);
|
||||||
|
|
||||||
|
bb.position(space -= length);
|
||||||
|
|
||||||
|
// Slice and limit the copy vector to point to the 'array'
|
||||||
|
ByteBuffer copy = bb.slice().order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
copy.limit(length);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode the string `s` in the buffer using UTF-8.
|
* Create a vector of tables.
|
||||||
|
*
|
||||||
|
* @param offsets Offsets of the tables.
|
||||||
|
* @return Returns offset of the vector.
|
||||||
|
*/
|
||||||
|
public int createVectorOfTables(int[] offsets) {
|
||||||
|
notNested();
|
||||||
|
startVector(Constants.SIZEOF_INT, offsets.length, Constants.SIZEOF_INT);
|
||||||
|
for(int i = offsets.length - 1; i >= 0; i--) addOffset(offsets[i]);
|
||||||
|
return endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a vector of sorted by the key tables.
|
||||||
|
*
|
||||||
|
* @param obj Instance of the table subclass.
|
||||||
|
* @param offsets Offsets of the tables.
|
||||||
|
* @return Returns offset of the sorted vector.
|
||||||
|
*/
|
||||||
|
public <T extends Table> int createSortedVectorOfTables(T obj, int[] offsets) {
|
||||||
|
obj.sortTables(offsets, bb);
|
||||||
|
return createVectorOfTables(offsets);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode the string `s` in the buffer using UTF-8. If {@code s} is
|
||||||
|
* already a {@link CharBuffer}, this method is allocation free.
|
||||||
*
|
*
|
||||||
* @param s The string to encode.
|
* @param s The string to encode.
|
||||||
* @return The offset in the buffer where the encoded string starts.
|
* @return The offset in the buffer where the encoded string starts.
|
||||||
*/
|
*/
|
||||||
public int createString(String s) {
|
public int createString(CharSequence s) {
|
||||||
byte[] utf8 = s.getBytes(utf8charset);
|
int length = s.length();
|
||||||
addByte((byte)0);
|
int estimatedDstCapacity = (int) (length * encoder.maxBytesPerChar());
|
||||||
startVector(1, utf8.length, 1);
|
if (dst == null || dst.capacity() < estimatedDstCapacity) {
|
||||||
bb.position(space -= utf8.length);
|
dst = ByteBuffer.allocate(Math.max(128, estimatedDstCapacity));
|
||||||
bb.put(utf8, 0, utf8.length);
|
}
|
||||||
return endVector();
|
|
||||||
|
dst.clear();
|
||||||
|
|
||||||
|
CharBuffer src = s instanceof CharBuffer ? (CharBuffer) s :
|
||||||
|
CharBuffer.wrap(s);
|
||||||
|
CoderResult result = encoder.encode(src, dst, true);
|
||||||
|
if (result.isError()) {
|
||||||
|
try {
|
||||||
|
result.throwException();
|
||||||
|
} catch (CharacterCodingException x) {
|
||||||
|
throw new Error(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dst.flip();
|
||||||
|
return createString(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -391,6 +525,20 @@ public class FlatBufferBuilder {
|
|||||||
return endVector();
|
return endVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a byte array in the buffer.
|
||||||
|
*
|
||||||
|
* @param arr A source array with data
|
||||||
|
* @return The offset in the buffer where the encoded array starts.
|
||||||
|
*/
|
||||||
|
public int createByteVector(byte[] arr) {
|
||||||
|
int length = arr.length;
|
||||||
|
startVector(1, length, 1);
|
||||||
|
bb.position(space -= length);
|
||||||
|
bb.put(arr);
|
||||||
|
return endVector();
|
||||||
|
}
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
/**
|
/**
|
||||||
* Should not be accessing the final buffer before it is finished.
|
* Should not be accessing the final buffer before it is finished.
|
||||||
@@ -428,8 +576,7 @@ public class FlatBufferBuilder {
|
|||||||
* call this directly. The `FlatBuffers` compiler will generate helper methods
|
* call this directly. The `FlatBuffers` compiler will generate helper methods
|
||||||
* that call this method internally.
|
* that call this method internally.
|
||||||
* <p>
|
* <p>
|
||||||
* For example, using the "Monster" code found on the
|
* For example, using the "Monster" code found on the "landing page". An
|
||||||
* @ref flatbuffers_guide_use_java_c-sharp "landing page". An
|
|
||||||
* object of type `Monster` can be created using the following code:
|
* object of type `Monster` can be created using the following code:
|
||||||
*
|
*
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
@@ -597,7 +744,11 @@ public class FlatBufferBuilder {
|
|||||||
addInt(0);
|
addInt(0);
|
||||||
int vtableloc = offset();
|
int vtableloc = offset();
|
||||||
// Write out the current vtable.
|
// Write out the current vtable.
|
||||||
for (int i = vtable_in_use - 1; i >= 0 ; i--) {
|
int i = vtable_in_use - 1;
|
||||||
|
// Trim trailing zeroes.
|
||||||
|
for (; i >= 0 && vtable[i] == 0; i--) {}
|
||||||
|
int trimmed_size = i + 1;
|
||||||
|
for (; i >= 0 ; i--) {
|
||||||
// Offset relative to the start of the table.
|
// Offset relative to the start of the table.
|
||||||
short off = (short)(vtable[i] != 0 ? vtableloc - vtable[i] : 0);
|
short off = (short)(vtable[i] != 0 ? vtableloc - vtable[i] : 0);
|
||||||
addShort(off);
|
addShort(off);
|
||||||
@@ -605,12 +756,12 @@ public class FlatBufferBuilder {
|
|||||||
|
|
||||||
final int standard_fields = 2; // The fields below:
|
final int standard_fields = 2; // The fields below:
|
||||||
addShort((short)(vtableloc - object_start));
|
addShort((short)(vtableloc - object_start));
|
||||||
addShort((short)((vtable_in_use + standard_fields) * SIZEOF_SHORT));
|
addShort((short)((trimmed_size + standard_fields) * SIZEOF_SHORT));
|
||||||
|
|
||||||
// Search for an existing vtable that matches the current one.
|
// Search for an existing vtable that matches the current one.
|
||||||
int existing_vtable = 0;
|
int existing_vtable = 0;
|
||||||
outer_loop:
|
outer_loop:
|
||||||
for (int i = 0; i < num_vtables; i++) {
|
for (i = 0; i < num_vtables; i++) {
|
||||||
int vt1 = bb.capacity() - vtables[i];
|
int vt1 = bb.capacity() - vtables[i];
|
||||||
int vt2 = space;
|
int vt2 = space;
|
||||||
short len = bb.getShort(vt1);
|
short len = bb.getShort(vt1);
|
||||||
@@ -708,6 +859,8 @@ public class FlatBufferBuilder {
|
|||||||
* Get the ByteBuffer representing the FlatBuffer. Only call this after you've
|
* Get the ByteBuffer representing the FlatBuffer. Only call this after you've
|
||||||
* called `finish()`. The actual data starts at the ByteBuffer's current position,
|
* called `finish()`. The actual data starts at the ByteBuffer's current position,
|
||||||
* not necessarily at `0`.
|
* not necessarily at `0`.
|
||||||
|
*
|
||||||
|
* @return The {@link ByteBuffer} representing the FlatBuffer
|
||||||
*/
|
*/
|
||||||
public ByteBuffer dataBuffer() {
|
public ByteBuffer dataBuffer() {
|
||||||
finished();
|
finished();
|
||||||
@@ -753,6 +906,41 @@ public class FlatBufferBuilder {
|
|||||||
public byte[] sizedByteArray() {
|
public byte[] sizedByteArray() {
|
||||||
return sizedByteArray(space, bb.capacity() - space);
|
return sizedByteArray(space, bb.capacity() - space);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility function to return an InputStream to the ByteBuffer data
|
||||||
|
*
|
||||||
|
* @return An InputStream that starts at the beginning of the ByteBuffer data
|
||||||
|
* and can read to the end of it.
|
||||||
|
*/
|
||||||
|
public InputStream sizedInputStream() {
|
||||||
|
finished();
|
||||||
|
ByteBuffer duplicate = bb.duplicate();
|
||||||
|
duplicate.position(space);
|
||||||
|
duplicate.limit(bb.capacity());
|
||||||
|
return new ByteBufferBackedInputStream(duplicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that allows a user to create an InputStream from a ByteBuffer.
|
||||||
|
*/
|
||||||
|
static class ByteBufferBackedInputStream extends InputStream {
|
||||||
|
|
||||||
|
ByteBuffer buf;
|
||||||
|
|
||||||
|
public ByteBufferBackedInputStream(ByteBuffer buf) {
|
||||||
|
this.buf = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read() throws IOException {
|
||||||
|
try {
|
||||||
|
return buf.get() & 0xFF;
|
||||||
|
} catch(BufferUnderflowException e) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ package com.google.flatbuffers;
|
|||||||
import static com.google.flatbuffers.Constants.*;
|
import static com.google.flatbuffers.Constants.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.CharBuffer;
|
||||||
|
import java.nio.charset.CharacterCodingException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.CharsetDecoder;
|
||||||
|
import java.nio.charset.CoderResult;
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
|
|
||||||
@@ -26,6 +31,19 @@ import java.nio.ByteOrder;
|
|||||||
* All tables in the generated code derive from this class, and add their own accessors.
|
* All tables in the generated code derive from this class, and add their own accessors.
|
||||||
*/
|
*/
|
||||||
public class Table {
|
public class Table {
|
||||||
|
private final static ThreadLocal<CharsetDecoder> UTF8_DECODER = new ThreadLocal<CharsetDecoder>() {
|
||||||
|
@Override
|
||||||
|
protected CharsetDecoder initialValue() {
|
||||||
|
return Charset.forName("UTF-8").newDecoder();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public final static ThreadLocal<Charset> UTF8_CHARSET = new ThreadLocal<Charset>() {
|
||||||
|
@Override
|
||||||
|
protected Charset initialValue() {
|
||||||
|
return Charset.forName("UTF-8");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private final static ThreadLocal<CharBuffer> CHAR_BUFFER = new ThreadLocal<CharBuffer>();
|
||||||
/** Used to hold the position of the `bb` buffer. */
|
/** Used to hold the position of the `bb` buffer. */
|
||||||
protected int bb_pos;
|
protected int bb_pos;
|
||||||
/** The underlying ByteBuffer to hold the data of the Table. */
|
/** The underlying ByteBuffer to hold the data of the Table. */
|
||||||
@@ -49,6 +67,11 @@ public class Table {
|
|||||||
return vtable_offset < bb.getShort(vtable) ? bb.getShort(vtable + vtable_offset) : 0;
|
return vtable_offset < bb.getShort(vtable) ? bb.getShort(vtable + vtable_offset) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static int __offset(int vtable_offset, int offset, ByteBuffer bb) {
|
||||||
|
int vtable = bb.capacity() - offset;
|
||||||
|
return bb.getShort(vtable + vtable_offset - bb.getInt(vtable)) + vtable;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a relative offset.
|
* Retrieve a relative offset.
|
||||||
*
|
*
|
||||||
@@ -59,6 +82,10 @@ public class Table {
|
|||||||
return offset + bb.getInt(offset);
|
return offset + bb.getInt(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static int __indirect(int offset, ByteBuffer bb) {
|
||||||
|
return offset + bb.getInt(offset);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
|
* Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
|
||||||
*
|
*
|
||||||
@@ -71,20 +98,34 @@ public class Table {
|
|||||||
* @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
|
* @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
|
||||||
*/
|
*/
|
||||||
protected String __string(int offset) {
|
protected String __string(int offset) {
|
||||||
|
CharsetDecoder decoder = UTF8_DECODER.get();
|
||||||
|
decoder.reset();
|
||||||
|
|
||||||
offset += bb.getInt(offset);
|
offset += bb.getInt(offset);
|
||||||
if (bb.hasArray()) {
|
ByteBuffer src = bb.duplicate().order(ByteOrder.LITTLE_ENDIAN);
|
||||||
return new String(bb.array(), bb.arrayOffset() + offset + SIZEOF_INT, bb.getInt(offset),
|
int length = src.getInt(offset);
|
||||||
FlatBufferBuilder.utf8charset);
|
src.position(offset + SIZEOF_INT);
|
||||||
} else {
|
src.limit(offset + SIZEOF_INT + length);
|
||||||
// We can't access .array(), since the ByteBuffer is read-only,
|
|
||||||
// off-heap or a memory map
|
int required = (int)((float)length * decoder.maxCharsPerByte());
|
||||||
ByteBuffer bb = this.bb.duplicate().order(ByteOrder.LITTLE_ENDIAN);
|
CharBuffer dst = CHAR_BUFFER.get();
|
||||||
// We're forced to make an extra copy:
|
if (dst == null || dst.capacity() < required) {
|
||||||
byte[] copy = new byte[bb.getInt(offset)];
|
dst = CharBuffer.allocate(required);
|
||||||
bb.position(offset + SIZEOF_INT);
|
CHAR_BUFFER.set(dst);
|
||||||
bb.get(copy);
|
|
||||||
return new String(copy, 0, copy.length, FlatBufferBuilder.utf8charset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dst.clear();
|
||||||
|
|
||||||
|
try {
|
||||||
|
CoderResult cr = decoder.decode(src, dst, true);
|
||||||
|
if (!cr.isUnderflow()) {
|
||||||
|
cr.throwException();
|
||||||
|
}
|
||||||
|
} catch (CharacterCodingException x) {
|
||||||
|
throw new Error(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst.flip().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,9 +154,13 @@ public class Table {
|
|||||||
/**
|
/**
|
||||||
* Get a whole vector as a ByteBuffer.
|
* Get a whole vector as a ByteBuffer.
|
||||||
*
|
*
|
||||||
* This is efficient, since it only allocates a new bytebuffer object, but does not actually copy
|
* This is efficient, since it only allocates a new {@link ByteBuffer} object,
|
||||||
* the data, it still refers to the same bytes as the original ByteBuffer. Also useful with nested
|
* but does not actually copy the data, it still refers to the same bytes
|
||||||
* FlatBuffers, etc.
|
* as the original ByteBuffer. Also useful with nested FlatBuffers, etc.
|
||||||
|
*
|
||||||
|
* @param vector_offset The position of the vector in the byte buffer
|
||||||
|
* @param elem_size The size of each element in the array
|
||||||
|
* @return The {@link ByteBuffer} for the array
|
||||||
*/
|
*/
|
||||||
protected ByteBuffer __vector_as_bytebuffer(int vector_offset, int elem_size) {
|
protected ByteBuffer __vector_as_bytebuffer(int vector_offset, int elem_size) {
|
||||||
int o = __offset(vector_offset);
|
int o = __offset(vector_offset);
|
||||||
@@ -142,10 +187,12 @@ public class Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a ByteBuffer contains a file identifier.
|
* Check if a {@link ByteBuffer} contains a file identifier.
|
||||||
*
|
*
|
||||||
* @param bb A `ByteBuffer` to check if it contains the identifier `ident`.
|
* @param bb A {@code ByteBuffer} to check if it contains the identifier
|
||||||
* @param ident A `String` identifier of the flatbuffer file.
|
* `ident`.
|
||||||
|
* @param ident A `String` identifier of the FlatBuffer file.
|
||||||
|
* @return True if the buffer contains the file identifier
|
||||||
*/
|
*/
|
||||||
protected static boolean __has_identifier(ByteBuffer bb, String ident) {
|
protected static boolean __has_identifier(ByteBuffer bb, String ident) {
|
||||||
if (ident.length() != FILE_IDENTIFIER_LENGTH)
|
if (ident.length() != FILE_IDENTIFIER_LENGTH)
|
||||||
@@ -156,6 +203,74 @@ public class Table {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort tables by the key.
|
||||||
|
*
|
||||||
|
* @param offsets An 'int' indexes of the tables into the bb.
|
||||||
|
* @param bb A {@code ByteBuffer} to get the tables.
|
||||||
|
*/
|
||||||
|
protected void sortTables(int[] offsets, final ByteBuffer bb) {
|
||||||
|
Integer[] off = new Integer[offsets.length];
|
||||||
|
for (int i = 0; i < offsets.length; i++) off[i] = offsets[i];
|
||||||
|
java.util.Arrays.sort(off, new java.util.Comparator<Integer>() {
|
||||||
|
public int compare(Integer o1, Integer o2) {
|
||||||
|
return keysCompare(o1, o2, bb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (int i = 0; i < offsets.length; i++) offsets[i] = off[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two tables by the key.
|
||||||
|
*
|
||||||
|
* @param o1 An 'Integer' index of the first key into the bb.
|
||||||
|
* @param o2 An 'Integer' index of the second key into the bb.
|
||||||
|
* @param bb A {@code ByteBuffer} to get the keys.
|
||||||
|
*/
|
||||||
|
protected int keysCompare(Integer o1, Integer o2, ByteBuffer bb) { return 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two strings in the buffer.
|
||||||
|
*
|
||||||
|
* @param offset_1 An 'int' index of the first string into the bb.
|
||||||
|
* @param offset_2 An 'int' index of the second string into the bb.
|
||||||
|
* @param bb A {@code ByteBuffer} to get the strings.
|
||||||
|
*/
|
||||||
|
protected static int compareStrings(int offset_1, int offset_2, ByteBuffer bb) {
|
||||||
|
offset_1 += bb.getInt(offset_1);
|
||||||
|
offset_2 += bb.getInt(offset_2);
|
||||||
|
int len_1 = bb.getInt(offset_1);
|
||||||
|
int len_2 = bb.getInt(offset_2);
|
||||||
|
int startPos_1 = offset_1 + SIZEOF_INT;
|
||||||
|
int startPos_2 = offset_2 + SIZEOF_INT;
|
||||||
|
int len = Math.min(len_1, len_2);
|
||||||
|
for(int i = 0; i < len; i++) {
|
||||||
|
if (bb.get(i + startPos_1) != bb.get(i + startPos_2))
|
||||||
|
return bb.get(i + startPos_1) - bb.get(i + startPos_2);
|
||||||
|
}
|
||||||
|
return len_1 - len_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare string from the buffer with the 'String' object.
|
||||||
|
*
|
||||||
|
* @param offset_1 An 'int' index of the first string into the bb.
|
||||||
|
* @param key Second string as a byte array.
|
||||||
|
* @param bb A {@code ByteBuffer} to get the first string.
|
||||||
|
*/
|
||||||
|
protected static int compareStrings(int offset_1, byte[] key, ByteBuffer bb) {
|
||||||
|
offset_1 += bb.getInt(offset_1);
|
||||||
|
int len_1 = bb.getInt(offset_1);
|
||||||
|
int len_2 = key.length;
|
||||||
|
int startPos_1 = offset_1 + Constants.SIZEOF_INT;
|
||||||
|
int len = Math.min(len_1, len_2);
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (bb.get(i + startPos_1) != key[i])
|
||||||
|
return bb.get(i + startPos_1) - key[i];
|
||||||
|
}
|
||||||
|
return len_1 - len_2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|||||||
@@ -2,6 +2,19 @@
|
|||||||
/// @addtogroup flatbuffers_javascript_api
|
/// @addtogroup flatbuffers_javascript_api
|
||||||
/// @{
|
/// @{
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fileoverview
|
||||||
|
*
|
||||||
|
* Need to suppress 'global this' error so the Node.js export line doesn't cause
|
||||||
|
* closure compile to error out.
|
||||||
|
* @suppress {globalThis}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @namespace
|
||||||
|
*/
|
||||||
var flatbuffers = {};
|
var flatbuffers = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,8 +84,8 @@ flatbuffers.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] =
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {number} high
|
|
||||||
* @param {number} low
|
* @param {number} low
|
||||||
|
* @param {number} high
|
||||||
*/
|
*/
|
||||||
flatbuffers.Long = function(low, high) {
|
flatbuffers.Long = function(low, high) {
|
||||||
/**
|
/**
|
||||||
@@ -88,11 +101,21 @@ flatbuffers.Long = function(low, high) {
|
|||||||
this.high = high | 0;
|
this.high = high | 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} low
|
||||||
|
* @param {number} high
|
||||||
|
* @returns {flatbuffers.Long}
|
||||||
|
*/
|
||||||
|
flatbuffers.Long.create = function(low, high) {
|
||||||
|
// Special-case zero to avoid GC overhead for default values
|
||||||
|
return low == 0 && high == 0 ? flatbuffers.Long.ZERO : new flatbuffers.Long(low, high);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {number}
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
flatbuffers.Long.prototype.toFloat64 = function() {
|
flatbuffers.Long.prototype.toFloat64 = function() {
|
||||||
return this.low + this.high * 0x100000000;
|
return (this.low >>> 0) + this.high * 0x100000000;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,11 +138,13 @@ flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0);
|
|||||||
* Create a FlatBufferBuilder.
|
* Create a FlatBufferBuilder.
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {number=} initial_size
|
* @param {number=} opt_initial_size
|
||||||
*/
|
*/
|
||||||
flatbuffers.Builder = function(initial_size) {
|
flatbuffers.Builder = function(opt_initial_size) {
|
||||||
if (!initial_size) {
|
if (!opt_initial_size) {
|
||||||
initial_size = 1024;
|
var initial_size = 1024;
|
||||||
|
} else {
|
||||||
|
var initial_size = opt_initial_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,9 +249,8 @@ flatbuffers.Builder.prototype.dataBuffer = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the ByteBuffer representing the FlatBuffer. Only call this after you've
|
* Get the bytes representing the FlatBuffer. Only call this after you've
|
||||||
* called finish(). The actual data starts at the ByteBuffer's current position,
|
* called finish().
|
||||||
* not necessarily at 0.
|
|
||||||
*
|
*
|
||||||
* @returns {Uint8Array}
|
* @returns {Uint8Array}
|
||||||
*/
|
*/
|
||||||
@@ -515,6 +539,10 @@ flatbuffers.Builder.prototype.offset = function() {
|
|||||||
* @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data
|
* @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data
|
||||||
* @returns {flatbuffers.ByteBuffer} A new byte buffer with the old data copied
|
* @returns {flatbuffers.ByteBuffer} A new byte buffer with the old data copied
|
||||||
* to it. The data is located at the end of the buffer.
|
* to it. The data is located at the end of the buffer.
|
||||||
|
*
|
||||||
|
* uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
|
||||||
|
* it a uint8Array we need to suppress the type check:
|
||||||
|
* @suppress {checkTypes}
|
||||||
*/
|
*/
|
||||||
flatbuffers.Builder.growByteBuffer = function(bb) {
|
flatbuffers.Builder.growByteBuffer = function(bb) {
|
||||||
var old_buf_size = bb.capacity();
|
var old_buf_size = bb.capacity();
|
||||||
@@ -576,23 +604,28 @@ flatbuffers.Builder.prototype.endObject = function() {
|
|||||||
this.addInt32(0);
|
this.addInt32(0);
|
||||||
var vtableloc = this.offset();
|
var vtableloc = this.offset();
|
||||||
|
|
||||||
|
// Trim trailing zeroes.
|
||||||
|
var i = this.vtable_in_use - 1;
|
||||||
|
for (; i >= 0 && this.vtable[i] == 0; i--) {}
|
||||||
|
var trimmed_size = i + 1;
|
||||||
|
|
||||||
// Write out the current vtable.
|
// Write out the current vtable.
|
||||||
for (var i = this.vtable_in_use - 1; i >= 0; i--) {
|
for (; i >= 0; i--) {
|
||||||
// Offset relative to the start of the table.
|
// Offset relative to the start of the table.
|
||||||
this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0);
|
this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var standard_fields = 2; // The fields below:
|
var standard_fields = 2; // The fields below:
|
||||||
this.addInt16(vtableloc - this.object_start);
|
this.addInt16(vtableloc - this.object_start);
|
||||||
this.addInt16((this.vtable_in_use + standard_fields) * flatbuffers.SIZEOF_SHORT);
|
var len = (trimmed_size + standard_fields) * flatbuffers.SIZEOF_SHORT;
|
||||||
|
this.addInt16(len);
|
||||||
|
|
||||||
// Search for an existing vtable that matches the current one.
|
// Search for an existing vtable that matches the current one.
|
||||||
var existing_vtable = 0;
|
var existing_vtable = 0;
|
||||||
|
var vt1 = this.space;
|
||||||
outer_loop:
|
outer_loop:
|
||||||
for (var i = 0; i < this.vtables.length; i++) {
|
for (i = 0; i < this.vtables.length; i++) {
|
||||||
var vt1 = this.bb.capacity() - this.vtables[i];
|
var vt2 = this.bb.capacity() - this.vtables[i];
|
||||||
var vt2 = this.space;
|
|
||||||
var len = this.bb.readInt16(vt1);
|
|
||||||
if (len == this.bb.readInt16(vt2)) {
|
if (len == this.bb.readInt16(vt2)) {
|
||||||
for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) {
|
for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) {
|
||||||
if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) {
|
if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) {
|
||||||
@@ -629,10 +662,11 @@ outer_loop:
|
|||||||
* Finalize a buffer, poiting to the given `root_table`.
|
* Finalize a buffer, poiting to the given `root_table`.
|
||||||
*
|
*
|
||||||
* @param {flatbuffers.Offset} root_table
|
* @param {flatbuffers.Offset} root_table
|
||||||
* @param {string=} file_identifier
|
* @param {string=} opt_file_identifier
|
||||||
*/
|
*/
|
||||||
flatbuffers.Builder.prototype.finish = function(root_table, file_identifier) {
|
flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier) {
|
||||||
if (file_identifier) {
|
if (opt_file_identifier) {
|
||||||
|
var file_identifier = opt_file_identifier;
|
||||||
this.prep(this.minalign, flatbuffers.SIZEOF_INT +
|
this.prep(this.minalign, flatbuffers.SIZEOF_INT +
|
||||||
flatbuffers.FILE_IDENTIFIER_LENGTH);
|
flatbuffers.FILE_IDENTIFIER_LENGTH);
|
||||||
if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
|
if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
|
||||||
@@ -751,6 +785,17 @@ flatbuffers.Builder.prototype.createString = function(s) {
|
|||||||
}
|
}
|
||||||
return this.endVector();
|
return this.endVector();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper function to avoid generated code depending on this file directly.
|
||||||
|
*
|
||||||
|
* @param {number} low
|
||||||
|
* @param {number} high
|
||||||
|
* @returns {flatbuffers.Long}
|
||||||
|
*/
|
||||||
|
flatbuffers.Builder.prototype.createLong = function(low, high) {
|
||||||
|
return flatbuffers.Long.create(low, high);
|
||||||
|
};
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
/**
|
/**
|
||||||
@@ -904,9 +949,17 @@ flatbuffers.ByteBuffer.prototype.readFloat64 = function(offset) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} offset
|
* @param {number} offset
|
||||||
* @param {number} value
|
* @param {number|boolean} value
|
||||||
*/
|
*/
|
||||||
flatbuffers.ByteBuffer.prototype.writeInt8 = function(offset, value) {
|
flatbuffers.ByteBuffer.prototype.writeInt8 = function(offset, value) {
|
||||||
|
this.bytes_[offset] = /** @type {number} */(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} offset
|
||||||
|
* @param {number} value
|
||||||
|
*/
|
||||||
|
flatbuffers.ByteBuffer.prototype.writeUint8 = function(offset, value) {
|
||||||
this.bytes_[offset] = value;
|
this.bytes_[offset] = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -919,6 +972,15 @@ flatbuffers.ByteBuffer.prototype.writeInt16 = function(offset, value) {
|
|||||||
this.bytes_[offset + 1] = value >> 8;
|
this.bytes_[offset + 1] = value >> 8;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} offset
|
||||||
|
* @param {number} value
|
||||||
|
*/
|
||||||
|
flatbuffers.ByteBuffer.prototype.writeUint16 = function(offset, value) {
|
||||||
|
this.bytes_[offset] = value;
|
||||||
|
this.bytes_[offset + 1] = value >> 8;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} offset
|
* @param {number} offset
|
||||||
* @param {number} value
|
* @param {number} value
|
||||||
@@ -930,6 +992,17 @@ flatbuffers.ByteBuffer.prototype.writeInt32 = function(offset, value) {
|
|||||||
this.bytes_[offset + 3] = value >> 24;
|
this.bytes_[offset + 3] = value >> 24;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} offset
|
||||||
|
* @param {number} value
|
||||||
|
*/
|
||||||
|
flatbuffers.ByteBuffer.prototype.writeUint32 = function(offset, value) {
|
||||||
|
this.bytes_[offset] = value;
|
||||||
|
this.bytes_[offset + 1] = value >> 8;
|
||||||
|
this.bytes_[offset + 2] = value >> 16;
|
||||||
|
this.bytes_[offset + 3] = value >> 24;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} offset
|
* @param {number} offset
|
||||||
* @param {flatbuffers.Long} value
|
* @param {flatbuffers.Long} value
|
||||||
@@ -939,6 +1012,15 @@ flatbuffers.ByteBuffer.prototype.writeInt64 = function(offset, value) {
|
|||||||
this.writeInt32(offset + 4, value.high);
|
this.writeInt32(offset + 4, value.high);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} offset
|
||||||
|
* @param {flatbuffers.Long} value
|
||||||
|
*/
|
||||||
|
flatbuffers.ByteBuffer.prototype.writeUint64 = function(offset, value) {
|
||||||
|
this.writeUint32(offset, value.low);
|
||||||
|
this.writeUint32(offset + 4, value.high);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} offset
|
* @param {number} offset
|
||||||
* @param {number} value
|
* @param {number} value
|
||||||
@@ -994,10 +1076,10 @@ flatbuffers.ByteBuffer.prototype.__union = function(t, offset) {
|
|||||||
* FlatBuffer later on.
|
* FlatBuffer later on.
|
||||||
*
|
*
|
||||||
* @param {number} offset
|
* @param {number} offset
|
||||||
* @param {flatbuffers.Encoding=} optionalEncoding Defaults to UTF16_STRING
|
* @param {flatbuffers.Encoding=} opt_encoding Defaults to UTF16_STRING
|
||||||
* @returns {string|Uint8Array}
|
* @returns {string|Uint8Array}
|
||||||
*/
|
*/
|
||||||
flatbuffers.ByteBuffer.prototype.__string = function(offset, optionalEncoding) {
|
flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) {
|
||||||
offset += this.readInt32(offset);
|
offset += this.readInt32(offset);
|
||||||
|
|
||||||
var length = this.readInt32(offset);
|
var length = this.readInt32(offset);
|
||||||
@@ -1006,7 +1088,7 @@ flatbuffers.ByteBuffer.prototype.__string = function(offset, optionalEncoding) {
|
|||||||
|
|
||||||
offset += flatbuffers.SIZEOF_INT;
|
offset += flatbuffers.SIZEOF_INT;
|
||||||
|
|
||||||
if (optionalEncoding === flatbuffers.Encoding.UTF8_BYTES) {
|
if (opt_encoding === flatbuffers.Encoding.UTF8_BYTES) {
|
||||||
return this.bytes_.subarray(offset, offset + length);
|
return this.bytes_.subarray(offset, offset + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1101,6 +1183,17 @@ flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper function to avoid generated code depending on this file directly.
|
||||||
|
*
|
||||||
|
* @param {number} low
|
||||||
|
* @param {number} high
|
||||||
|
* @returns {flatbuffers.Long}
|
||||||
|
*/
|
||||||
|
flatbuffers.ByteBuffer.prototype.createLong = function(low, high) {
|
||||||
|
return flatbuffers.Long.create(low, high);
|
||||||
|
};
|
||||||
|
|
||||||
// Exports for Node.js and RequireJS
|
// Exports for Node.js and RequireJS
|
||||||
this.flatbuffers = flatbuffers;
|
this.flatbuffers = flatbuffers;
|
||||||
|
|
||||||
|
|||||||
27
net/FlatBuffers/ByteBuffer.cs
Executable file → Normal file
27
net/FlatBuffers/ByteBuffer.cs
Executable file → Normal file
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014 Google Inc. All rights reserved.
|
* Copyright 2014 Google Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -14,7 +14,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define UNSAFE_BYTEBUFFER // uncomment this line to use faster ByteBuffer
|
// There are 2 #defines that have an impact on performance of this ByteBuffer implementation
|
||||||
|
//
|
||||||
|
// UNSAFE_BYTEBUFFER
|
||||||
|
// This will use unsafe code to manipulate the underlying byte array. This
|
||||||
|
// can yield a reasonable performance increase.
|
||||||
|
//
|
||||||
|
// BYTEBUFFER_NO_BOUNDS_CHECK
|
||||||
|
// This will disable the bounds check asserts to the byte array. This can
|
||||||
|
// yield a small performance gain in normal code..
|
||||||
|
//
|
||||||
|
// Using UNSAFE_BYTEBUFFER and BYTEBUFFER_NO_BOUNDS_CHECK together can yield a
|
||||||
|
// performance gain of ~15% for some operations, however doing so is potentially
|
||||||
|
// dangerous. Do so at your own risk!
|
||||||
|
//
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
@@ -22,9 +35,6 @@ namespace FlatBuffers
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class to mimic Java's ByteBuffer which is used heavily in Flatbuffers.
|
/// Class to mimic Java's ByteBuffer which is used heavily in Flatbuffers.
|
||||||
/// If your execution environment allows unsafe code, you should enable
|
|
||||||
/// unsafe code in your project and #define UNSAFE_BYTEBUFFER to use a
|
|
||||||
/// MUCH faster version of ByteBuffer.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ByteBuffer
|
public class ByteBuffer
|
||||||
{
|
{
|
||||||
@@ -126,12 +136,14 @@ namespace FlatBuffers
|
|||||||
}
|
}
|
||||||
#endif // !UNSAFE_BYTEBUFFER
|
#endif // !UNSAFE_BYTEBUFFER
|
||||||
|
|
||||||
|
|
||||||
private void AssertOffsetAndLength(int offset, int length)
|
private void AssertOffsetAndLength(int offset, int length)
|
||||||
{
|
{
|
||||||
|
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||||
if (offset < 0 ||
|
if (offset < 0 ||
|
||||||
offset >= _buffer.Length ||
|
offset > _buffer.Length - length)
|
||||||
offset + length > _buffer.Length)
|
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PutSbyte(int offset, sbyte value)
|
public void PutSbyte(int offset, sbyte value)
|
||||||
@@ -201,7 +213,6 @@ namespace FlatBuffers
|
|||||||
public unsafe void PutUlong(int offset, ulong value)
|
public unsafe void PutUlong(int offset, ulong value)
|
||||||
{
|
{
|
||||||
AssertOffsetAndLength(offset, sizeof(ulong));
|
AssertOffsetAndLength(offset, sizeof(ulong));
|
||||||
|
|
||||||
fixed (byte* ptr = _buffer)
|
fixed (byte* ptr = _buffer)
|
||||||
{
|
{
|
||||||
*(ulong*)(ptr + offset) = BitConverter.IsLittleEndian
|
*(ulong*)(ptr + offset) = BitConverter.IsLittleEndian
|
||||||
|
|||||||
@@ -296,6 +296,18 @@ namespace FlatBuffers
|
|||||||
return new VectorOffset(Offset);
|
return new VectorOffset(Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a vector of tables.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offsets">Offsets of the tables.</param>
|
||||||
|
public VectorOffset CreateVectorOfTables<T>(Offset<T>[] offsets) where T : struct
|
||||||
|
{
|
||||||
|
NotNested();
|
||||||
|
StartVector(sizeof(int), offsets.Length, sizeof(int));
|
||||||
|
for (int i = offsets.Length - 1; i >= 0; i--) AddOffset(offsets[i].Value);
|
||||||
|
return EndVector();
|
||||||
|
}
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTENRAL
|
/// @cond FLATBUFFERS_INTENRAL
|
||||||
public void Nested(int obj)
|
public void Nested(int obj)
|
||||||
{
|
{
|
||||||
@@ -488,7 +500,11 @@ namespace FlatBuffers
|
|||||||
AddInt((int)0);
|
AddInt((int)0);
|
||||||
var vtableloc = Offset;
|
var vtableloc = Offset;
|
||||||
// Write out the current vtable.
|
// Write out the current vtable.
|
||||||
for (int i = _vtableSize - 1; i >= 0 ; i--) {
|
int i = _vtableSize - 1;
|
||||||
|
// Trim trailing zeroes.
|
||||||
|
for (; i >= 0 && _vtable[i] == 0; i--) {}
|
||||||
|
int trimmedSize = i + 1;
|
||||||
|
for (; i >= 0 ; i--) {
|
||||||
// Offset relative to the start of the table.
|
// Offset relative to the start of the table.
|
||||||
short off = (short)(_vtable[i] != 0
|
short off = (short)(_vtable[i] != 0
|
||||||
? vtableloc - _vtable[i]
|
? vtableloc - _vtable[i]
|
||||||
@@ -501,12 +517,12 @@ namespace FlatBuffers
|
|||||||
|
|
||||||
const int standardFields = 2; // The fields below:
|
const int standardFields = 2; // The fields below:
|
||||||
AddShort((short)(vtableloc - _objectStart));
|
AddShort((short)(vtableloc - _objectStart));
|
||||||
AddShort((short)((_vtableSize + standardFields) *
|
AddShort((short)((trimmedSize + standardFields) *
|
||||||
sizeof(short)));
|
sizeof(short)));
|
||||||
|
|
||||||
// Search for an existing vtable that matches the current one.
|
// Search for an existing vtable that matches the current one.
|
||||||
int existingVtable = 0;
|
int existingVtable = 0;
|
||||||
for (int i = 0; i < _numVtables; i++) {
|
for (i = 0; i < _numVtables; i++) {
|
||||||
int vt1 = _bb.Length - _vtables[i];
|
int vt1 = _bb.Length - _vtables[i];
|
||||||
int vt2 = _space;
|
int vt2 = _space;
|
||||||
short len = _bb.GetShort(vt1);
|
short len = _bb.GetShort(vt1);
|
||||||
@@ -582,6 +598,8 @@ namespace FlatBuffers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This is typically only called after you call `Finish()`.
|
/// This is typically only called after you call `Finish()`.
|
||||||
|
/// The actual data starts at the ByteBuffer's current position,
|
||||||
|
/// not necessarily at `0`.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// Returns the ByteBuffer for this FlatBuffer.
|
/// Returns the ByteBuffer for this FlatBuffer.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014 Google Inc. All rights reserved.
|
* Copyright 2014 Google Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
<Compile Include="ByteBuffer.cs" />
|
<Compile Include="ByteBuffer.cs" />
|
||||||
<Compile Include="FlatBufferBuilder.cs" />
|
<Compile Include="FlatBufferBuilder.cs" />
|
||||||
<Compile Include="FlatBufferConstants.cs" />
|
<Compile Include="FlatBufferConstants.cs" />
|
||||||
|
<Compile Include="IFlatbufferObject.cs" />
|
||||||
<Compile Include="Offset.cs" />
|
<Compile Include="Offset.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Struct.cs" />
|
<Compile Include="Struct.cs" />
|
||||||
|
|||||||
28
net/FlatBuffers/IFlatbufferObject.cs
Normal file
28
net/FlatBuffers/IFlatbufferObject.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FlatBuffers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This is the base for both structs and tables.
|
||||||
|
/// </summary>
|
||||||
|
public interface IFlatbufferObject
|
||||||
|
{
|
||||||
|
void __init(int _i, ByteBuffer _bb);
|
||||||
|
|
||||||
|
ByteBuffer ByteBuffer { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ namespace FlatBuffers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Offset class for typesafe assignments.
|
/// Offset class for typesafe assignments.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct Offset<T> where T : class
|
public struct Offset<T> where T : struct
|
||||||
{
|
{
|
||||||
public int Value;
|
public int Value;
|
||||||
public Offset(int value)
|
public Offset(int value)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014 Google Inc. All rights reserved.
|
* Copyright 2014 Google Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -26,7 +26,7 @@ using System.Runtime.InteropServices;
|
|||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("")]
|
||||||
[assembly: AssemblyProduct("FlatBuffers")]
|
[assembly: AssemblyProduct("FlatBuffers")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2015 Google Inc")]
|
[assembly: AssemblyCopyright("Copyright (c) 2015 Google Inc")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014 Google Inc. All rights reserved.
|
* Copyright 2014 Google Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -19,9 +19,9 @@ namespace FlatBuffers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// All structs in the generated code derive from this class, and add their own accessors.
|
/// All structs in the generated code derive from this class, and add their own accessors.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class Struct
|
public struct Struct
|
||||||
{
|
{
|
||||||
protected int bb_pos;
|
public int bb_pos;
|
||||||
protected ByteBuffer bb;
|
public ByteBuffer bb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,31 +20,42 @@ using System.Text;
|
|||||||
namespace FlatBuffers
|
namespace FlatBuffers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All tables in the generated code derive from this class, and add their own accessors.
|
/// All tables in the generated code derive from this struct, and add their own accessors.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class Table
|
public struct Table
|
||||||
{
|
{
|
||||||
protected int bb_pos;
|
public int bb_pos;
|
||||||
protected ByteBuffer bb;
|
public ByteBuffer bb;
|
||||||
|
|
||||||
public ByteBuffer ByteBuffer { get { return bb; } }
|
public ByteBuffer ByteBuffer { get { return bb; } }
|
||||||
|
|
||||||
// Look up a field in the vtable, return an offset into the object, or 0 if the field is not
|
// Look up a field in the vtable, return an offset into the object, or 0 if the field is not
|
||||||
// present.
|
// present.
|
||||||
protected int __offset(int vtableOffset)
|
public int __offset(int vtableOffset)
|
||||||
{
|
{
|
||||||
int vtable = bb_pos - bb.GetInt(bb_pos);
|
int vtable = bb_pos - bb.GetInt(bb_pos);
|
||||||
return vtableOffset < bb.GetShort(vtable) ? (int)bb.GetShort(vtable + vtableOffset) : 0;
|
return vtableOffset < bb.GetShort(vtable) ? (int)bb.GetShort(vtable + vtableOffset) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int __offset(int vtableOffset, int offset, ByteBuffer bb)
|
||||||
|
{
|
||||||
|
int vtable = bb.Length - offset;
|
||||||
|
return (int)bb.GetShort(vtable + vtableOffset - bb.GetInt(vtable)) + vtable;
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve the relative offset stored at "offset"
|
// Retrieve the relative offset stored at "offset"
|
||||||
protected int __indirect(int offset)
|
public int __indirect(int offset)
|
||||||
|
{
|
||||||
|
return offset + bb.GetInt(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int __indirect(int offset, ByteBuffer bb)
|
||||||
{
|
{
|
||||||
return offset + bb.GetInt(offset);
|
return offset + bb.GetInt(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a .NET String from UTF-8 data stored inside the flatbuffer.
|
// Create a .NET String from UTF-8 data stored inside the flatbuffer.
|
||||||
protected string __string(int offset)
|
public string __string(int offset)
|
||||||
{
|
{
|
||||||
offset += bb.GetInt(offset);
|
offset += bb.GetInt(offset);
|
||||||
var len = bb.GetInt(offset);
|
var len = bb.GetInt(offset);
|
||||||
@@ -53,7 +64,7 @@ namespace FlatBuffers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the length of a vector whose offset is stored at "offset" in this object.
|
// Get the length of a vector whose offset is stored at "offset" in this object.
|
||||||
protected int __vector_len(int offset)
|
public int __vector_len(int offset)
|
||||||
{
|
{
|
||||||
offset += bb_pos;
|
offset += bb_pos;
|
||||||
offset += bb.GetInt(offset);
|
offset += bb.GetInt(offset);
|
||||||
@@ -61,7 +72,7 @@ namespace FlatBuffers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the start of data of a vector whose offset is stored at "offset" in this object.
|
// Get the start of data of a vector whose offset is stored at "offset" in this object.
|
||||||
protected int __vector(int offset)
|
public int __vector(int offset)
|
||||||
{
|
{
|
||||||
offset += bb_pos;
|
offset += bb_pos;
|
||||||
return offset + bb.GetInt(offset) + sizeof(int); // data starts after the length
|
return offset + bb.GetInt(offset) + sizeof(int); // data starts after the length
|
||||||
@@ -70,7 +81,8 @@ namespace FlatBuffers
|
|||||||
// Get the data of a vector whoses offset is stored at "offset" in this object as an
|
// Get the data of a vector whoses offset is stored at "offset" in this object as an
|
||||||
// ArraySegment<byte>. If the vector is not present in the ByteBuffer,
|
// ArraySegment<byte>. If the vector is not present in the ByteBuffer,
|
||||||
// then a null value will be returned.
|
// then a null value will be returned.
|
||||||
protected ArraySegment<byte>? __vector_as_arraysegment(int offset) {
|
public ArraySegment<byte>? __vector_as_arraysegment(int offset)
|
||||||
|
{
|
||||||
var o = this.__offset(offset);
|
var o = this.__offset(offset);
|
||||||
if (0 == o)
|
if (0 == o)
|
||||||
{
|
{
|
||||||
@@ -83,15 +95,15 @@ namespace FlatBuffers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize any Table-derived type to point to the union at the given offset.
|
// Initialize any Table-derived type to point to the union at the given offset.
|
||||||
protected TTable __union<TTable>(TTable t, int offset) where TTable : Table
|
public T __union<T>(int offset) where T : struct, IFlatbufferObject
|
||||||
{
|
{
|
||||||
offset += bb_pos;
|
offset += bb_pos;
|
||||||
t.bb_pos = offset + bb.GetInt(offset);
|
T t = new T();
|
||||||
t.bb = bb;
|
t.__init(offset + bb.GetInt(offset), bb);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static bool __has_identifier(ByteBuffer bb, string ident)
|
public static bool __has_identifier(ByteBuffer bb, string ident)
|
||||||
{
|
{
|
||||||
if (ident.Length != FlatBufferConstants.FileIdentifierLength)
|
if (ident.Length != FlatBufferConstants.FileIdentifierLength)
|
||||||
throw new ArgumentException("FlatBuffers: file identifier must be length " + FlatBufferConstants.FileIdentifierLength, "ident");
|
throw new ArgumentException("FlatBuffers: file identifier must be length " + FlatBufferConstants.FileIdentifierLength, "ident");
|
||||||
@@ -104,6 +116,38 @@ namespace FlatBuffers
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compare strings in the ByteBuffer.
|
||||||
|
public static int CompareStrings(int offset_1, int offset_2, ByteBuffer bb)
|
||||||
|
{
|
||||||
|
offset_1 += bb.GetInt(offset_1);
|
||||||
|
offset_2 += bb.GetInt(offset_2);
|
||||||
|
var len_1 = bb.GetInt(offset_1);
|
||||||
|
var len_2 = bb.GetInt(offset_2);
|
||||||
|
var startPos_1 = offset_1 + sizeof(int);
|
||||||
|
var startPos_2 = offset_2 + sizeof(int);
|
||||||
|
var len = Math.Min(len_1, len_2);
|
||||||
|
byte[] bbArray = bb.Data;
|
||||||
|
for(int i = 0; i < len; i++) {
|
||||||
|
if (bbArray[i + startPos_1] != bbArray[i + startPos_2])
|
||||||
|
return bbArray[i + startPos_1] - bbArray[i + startPos_2];
|
||||||
|
}
|
||||||
|
return len_1 - len_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare string from the ByteBuffer with the string object
|
||||||
|
public static int CompareStrings(int offset_1, byte[] key, ByteBuffer bb)
|
||||||
|
{
|
||||||
|
offset_1 += bb.GetInt(offset_1);
|
||||||
|
var len_1 = bb.GetInt(offset_1);
|
||||||
|
var len_2 = key.Length;
|
||||||
|
var startPos_1 = offset_1 + sizeof(int);
|
||||||
|
var len = Math.Min(len_1, len_2);
|
||||||
|
byte[] bbArray = bb.Data;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (bbArray[i + startPos_1] != key[i])
|
||||||
|
return bbArray[i + startPos_1] - key[i];
|
||||||
|
}
|
||||||
|
return len_1 - len_2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user