Compare commits
3709 Commits
src
...
XPCOM_M8_P
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b38b5431f4 | ||
|
|
9c4ce69474 | ||
|
|
033e103521 | ||
|
|
6f31df3804 | ||
|
|
e09f408d32 | ||
|
|
69ff4c5e28 | ||
|
|
08cc0da33f | ||
|
|
e6d66a31c8 | ||
|
|
b089efa46d | ||
|
|
16d56f8c29 | ||
|
|
c474a7e978 | ||
|
|
03896aed3b | ||
|
|
1faa402d05 | ||
|
|
2bd49a3742 | ||
|
|
de99da5303 | ||
|
|
37c7fa75bc | ||
|
|
d6f434b193 | ||
|
|
29c1baa59c | ||
|
|
21c6f54372 | ||
|
|
2a43926ce8 | ||
|
|
666974771c | ||
|
|
47a94e12b5 | ||
|
|
bab066c35e | ||
|
|
7f7de309bc | ||
|
|
ad8748b928 | ||
|
|
d0015a2822 | ||
|
|
5a672d0530 | ||
|
|
b0f5202f33 | ||
|
|
ea17cba094 | ||
|
|
a2e6482e7a | ||
|
|
9530819997 | ||
|
|
fa7df41183 | ||
|
|
544a1e8cc6 | ||
|
|
3e21752205 | ||
|
|
5c5d2478ba | ||
|
|
6f9e4dc415 | ||
|
|
96242f9b51 | ||
|
|
2d7ae6ab1a | ||
|
|
117d94e100 | ||
|
|
dccc57f016 | ||
|
|
49e22150fa | ||
|
|
073b468139 | ||
|
|
16428747b9 | ||
|
|
db2190f83a | ||
|
|
7b4ee82ffa | ||
|
|
c46bc91071 | ||
|
|
b18c9fe795 | ||
|
|
a32c5538dd | ||
|
|
658f77bfcf | ||
|
|
3ded103016 | ||
|
|
f0eb9df737 | ||
|
|
755b17b67e | ||
|
|
a44aef2f2e | ||
|
|
ce6c1f2bdd | ||
|
|
941f6709ac | ||
|
|
1ced106a53 | ||
|
|
a3cdd51d02 | ||
|
|
25c27303e4 | ||
|
|
65fc7ea6ea | ||
|
|
329652cc90 | ||
|
|
3b1a317404 | ||
|
|
952cec4faa | ||
|
|
ac7cdfc906 | ||
|
|
367cbf5625 | ||
|
|
2769bdcc9f | ||
|
|
920dea6a0f | ||
|
|
998b4ac00c | ||
|
|
b4516b6093 | ||
|
|
d28fa84f4f | ||
|
|
97e493ce3f | ||
|
|
3312d37d00 | ||
|
|
bc24e26490 | ||
|
|
85d3b7dc58 | ||
|
|
d5bf33481a | ||
|
|
7dec28fe33 | ||
|
|
e564eb594c | ||
|
|
9dc4da4a3e | ||
|
|
2ae55e5761 | ||
|
|
880e9ed48f | ||
|
|
bfa459e8d2 | ||
|
|
19e16daaf1 | ||
|
|
88aa181804 | ||
|
|
be69b669fb | ||
|
|
32f5401615 | ||
|
|
e17e43a953 | ||
|
|
1eba64788c | ||
|
|
64e256950f | ||
|
|
03bd81f647 | ||
|
|
ebe1cda245 | ||
|
|
e0eaf48451 | ||
|
|
57fdc5649d | ||
|
|
ff4b7810b3 | ||
|
|
9131e10776 | ||
|
|
e08d124ef8 | ||
|
|
9de5d18391 | ||
|
|
3fdf25f7aa | ||
|
|
210b24c193 | ||
|
|
360e823201 | ||
|
|
bca3a2f65b | ||
|
|
ef99640e6a | ||
|
|
24a97be697 | ||
|
|
3a1cf02c01 | ||
|
|
eb2c886395 | ||
|
|
80a3fb3ea9 | ||
|
|
6110c55ac5 | ||
|
|
3618fda5f3 | ||
|
|
a157d6f90a | ||
|
|
dc4b78b5b1 | ||
|
|
8ad2780d32 | ||
|
|
e1ae868b8f | ||
|
|
e278017bcd | ||
|
|
934f30a05c | ||
|
|
0d49f312e2 | ||
|
|
8b1231e0ae | ||
|
|
58d631e1da | ||
|
|
c2ebd2ac36 | ||
|
|
d0667245d7 | ||
|
|
0ca0501d10 | ||
|
|
bce585f406 | ||
|
|
b9ad7e0ec0 | ||
|
|
3ce10bd48a | ||
|
|
49826cb224 | ||
|
|
37683fb4e8 | ||
|
|
ebb4924d31 | ||
|
|
8f6b3c10ad | ||
|
|
b9614987b1 | ||
|
|
0513dccdf4 | ||
|
|
72023cf976 | ||
|
|
af99988415 | ||
|
|
090f723a2e | ||
|
|
fab79c8cb9 | ||
|
|
53b3727a48 | ||
|
|
4a772c42c0 | ||
|
|
08a9e2e637 | ||
|
|
0d91adab31 | ||
|
|
d787d07fca | ||
|
|
72a04e5b82 | ||
|
|
6a85e54025 | ||
|
|
a001d622eb | ||
|
|
96df8c1b9e | ||
|
|
295e5113d6 | ||
|
|
f85a03ebe7 | ||
|
|
87a9d8b629 | ||
|
|
c9ddd97aec | ||
|
|
3b30bf0056 | ||
|
|
24b1b5476f | ||
|
|
243d006cae | ||
|
|
3ed64a5078 | ||
|
|
4c569ae681 | ||
|
|
aaaa87a18c | ||
|
|
88a21299f0 | ||
|
|
2bf72dbb03 | ||
|
|
1e5c752f72 | ||
|
|
8d7287d3e4 | ||
|
|
831126af0d | ||
|
|
40b549cf66 | ||
|
|
39996cd3b8 | ||
|
|
44d8b6ef0b | ||
|
|
37279af5d3 | ||
|
|
c327ee36e4 | ||
|
|
4d535474a8 | ||
|
|
b176b22c4f | ||
|
|
dcf8ff59fb | ||
|
|
bfd9b82db2 | ||
|
|
6a6d59ff68 | ||
|
|
9716fdac2a | ||
|
|
d83c833313 | ||
|
|
e29b5f2101 | ||
|
|
f473717e63 | ||
|
|
bd45ebcd60 | ||
|
|
02fa3bd6bd | ||
|
|
3d4646654f | ||
|
|
12dab899e4 | ||
|
|
fbed121956 | ||
|
|
a08e39024d | ||
|
|
167f325647 | ||
|
|
66f425712a | ||
|
|
1361b1bb20 | ||
|
|
fa77cc2277 | ||
|
|
c35619cc53 | ||
|
|
f04cb93173 | ||
|
|
9596f286ef | ||
|
|
c1303b8b21 | ||
|
|
3b033a31cd | ||
|
|
4c53d61c58 | ||
|
|
ae0ddf1d91 | ||
|
|
8f97f994e0 | ||
|
|
03e9ccf38c | ||
|
|
8eb3c480bb | ||
|
|
76f6398b20 | ||
|
|
446d2af4fb | ||
|
|
d5abf28edc | ||
|
|
2d7a698cda | ||
|
|
36de102206 | ||
|
|
aeeb0cb3d1 | ||
|
|
4ab75873d4 | ||
|
|
d027b8dc05 | ||
|
|
928e532d0e | ||
|
|
853a05705a | ||
|
|
60ced1e02f | ||
|
|
8f270c71ad | ||
|
|
18be5e494e | ||
|
|
6e134a79ae | ||
|
|
859c3542ef | ||
|
|
31d4d3bf26 | ||
|
|
ae5660d9b2 | ||
|
|
50681113ae | ||
|
|
2bfe67cabf | ||
|
|
a087bc1796 | ||
|
|
7c00f26d90 | ||
|
|
fed08cf519 | ||
|
|
e0de8e6170 | ||
|
|
87d5829509 | ||
|
|
11f9f030ed | ||
|
|
1742acc59c | ||
|
|
27fb3a05cf | ||
|
|
5f9d4c0b44 | ||
|
|
9927e05f37 | ||
|
|
691b3263fd | ||
|
|
96d0d118d3 | ||
|
|
e71fc28d03 | ||
|
|
55a7251df6 | ||
|
|
407dc82818 | ||
|
|
8e58adc2c2 | ||
|
|
513825d5d1 | ||
|
|
e2c76feee9 | ||
|
|
d9089e62e2 | ||
|
|
84c9383e12 | ||
|
|
150e4b8e65 | ||
|
|
9c4625fa70 | ||
|
|
1cef7222c8 | ||
|
|
eb0d247365 | ||
|
|
e55b5c7168 | ||
|
|
8b155d3ee2 | ||
|
|
2c5afbbd59 | ||
|
|
ee9448227f | ||
|
|
e585dea4af | ||
|
|
5bd2ed2750 | ||
|
|
f7d74c9b83 | ||
|
|
19f8e2d3b8 | ||
|
|
a1c8d93494 | ||
|
|
d72e48ffbc | ||
|
|
cf965cd3d6 | ||
|
|
cc5c62232a | ||
|
|
ffbf97429b | ||
|
|
1430c6074a | ||
|
|
5ba66187f3 | ||
|
|
77b16aae45 | ||
|
|
c7f897590b | ||
|
|
3e34b745d7 | ||
|
|
d64f05c597 | ||
|
|
a5b72478b3 | ||
|
|
4f148753e7 | ||
|
|
11167ab4c7 | ||
|
|
3f7c6a17f8 | ||
|
|
8800fbd073 | ||
|
|
67b768d820 | ||
|
|
acc2016c78 | ||
|
|
a6c216e391 | ||
|
|
a36b31af6f | ||
|
|
a509f67439 | ||
|
|
ffcec8a4cf | ||
|
|
8d48f48a91 | ||
|
|
09d003848a | ||
|
|
826f677168 | ||
|
|
b1d11092c1 | ||
|
|
35c913e396 | ||
|
|
5b2faf00aa | ||
|
|
7fcb7f6b28 | ||
|
|
e2af4400bd | ||
|
|
1193e8f8f1 | ||
|
|
60b57db179 | ||
|
|
5be87ae69e | ||
|
|
1bec8c5360 | ||
|
|
16b79bc408 | ||
|
|
83297d17aa | ||
|
|
a68346bb7e | ||
|
|
2058b3a8d2 | ||
|
|
8bce4d6ac8 | ||
|
|
68d11ccc79 | ||
|
|
733e047edd | ||
|
|
9c72e43ec0 | ||
|
|
93b0dbd87b | ||
|
|
ab52924916 | ||
|
|
52e3512770 | ||
|
|
fa704f382a | ||
|
|
617d46a5ae | ||
|
|
4cbb4ce6a1 | ||
|
|
03f1a4a531 | ||
|
|
402ced3aff | ||
|
|
c6970d71cd | ||
|
|
2fb45d996c | ||
|
|
7a1b68ea24 | ||
|
|
7195368191 | ||
|
|
85c9eb0a85 | ||
|
|
de6e9c03e7 | ||
|
|
9bb2664f9d | ||
|
|
22af0a38b5 | ||
|
|
09ad481b2b | ||
|
|
e031e3202a | ||
|
|
6921693a16 | ||
|
|
1af64cfc8e | ||
|
|
cef9687fd6 | ||
|
|
f1588e6197 | ||
|
|
f1f4205797 | ||
|
|
b22485c12a | ||
|
|
4dbeba7920 | ||
|
|
4059951821 | ||
|
|
9ffe404459 | ||
|
|
180949a473 | ||
|
|
ae35fb03ad | ||
|
|
164536c1c1 | ||
|
|
f660351faa | ||
|
|
97bef3a116 | ||
|
|
a60936fdae | ||
|
|
42df826e30 | ||
|
|
f63351a962 | ||
|
|
2ef81cee26 | ||
|
|
c2d795e464 | ||
|
|
63bed96031 | ||
|
|
c0f7351823 | ||
|
|
44b1e90da0 | ||
|
|
38347ad4d2 | ||
|
|
9342bd261d | ||
|
|
00f19d472d | ||
|
|
759ec2937d | ||
|
|
3a03fbbd68 | ||
|
|
a34ca3a05b | ||
|
|
b2b48f5168 | ||
|
|
fb2c65e5cd | ||
|
|
deb12f14b6 | ||
|
|
364aea910c | ||
|
|
6ae9c4bf93 | ||
|
|
ebd7ce1252 | ||
|
|
b560dc6a84 | ||
|
|
2737748d7f | ||
|
|
adfa5e61ff | ||
|
|
2e899d89cd | ||
|
|
c0616bdc59 | ||
|
|
ba09080b75 | ||
|
|
6e5cfba7ee | ||
|
|
cf48f65273 | ||
|
|
ece9930005 | ||
|
|
13f4cb8157 | ||
|
|
1082ca5342 | ||
|
|
12c2195b8a | ||
|
|
80afaba69e | ||
|
|
9c7f494efd | ||
|
|
62fb8f7c1f | ||
|
|
c66394589f | ||
|
|
74c14b270c | ||
|
|
8fc0dd2f58 | ||
|
|
a2d0be4d64 | ||
|
|
57e3089ae3 | ||
|
|
af403a664e | ||
|
|
2ca3237327 | ||
|
|
de7144cae5 | ||
|
|
e299920b40 | ||
|
|
6e58a1c196 | ||
|
|
dc608130b4 | ||
|
|
51dc87f07c | ||
|
|
ea708a16a8 | ||
|
|
db23dd7d5c | ||
|
|
478c08520e | ||
|
|
9ea8cebe57 | ||
|
|
5c968b9fdd | ||
|
|
7df5e4ac3e | ||
|
|
13dd905b76 | ||
|
|
8dece188fd | ||
|
|
8546a43e40 | ||
|
|
20ffc454a0 | ||
|
|
501341674d | ||
|
|
1cd4f8b45d | ||
|
|
48965ca20e | ||
|
|
3ea21353d9 | ||
|
|
fd2d046e02 | ||
|
|
490e5a7612 | ||
|
|
b38e118631 | ||
|
|
49cc175467 | ||
|
|
91c1952a7c | ||
|
|
ced0b68123 | ||
|
|
242d9e9751 | ||
|
|
6262706d53 | ||
|
|
6f6356c718 | ||
|
|
e43b136c6e | ||
|
|
ac56309a00 | ||
|
|
7dd50c2dba | ||
|
|
08033e3f08 | ||
|
|
2a91067210 | ||
|
|
7f2efdd7f0 | ||
|
|
c8b6811625 | ||
|
|
d3f7b64189 | ||
|
|
85b027f229 | ||
|
|
8de966fc93 | ||
|
|
b366c7e0ba | ||
|
|
96f1a13abc | ||
|
|
05f18fdaad | ||
|
|
49262effd9 | ||
|
|
366db19b81 | ||
|
|
46fd7834e4 | ||
|
|
986647866b | ||
|
|
c5c8558130 | ||
|
|
115d1a2d22 | ||
|
|
08c27abd93 | ||
|
|
18d7f3f7d6 | ||
|
|
8f72f8ed85 | ||
|
|
3a175a8bec | ||
|
|
4ce5e79297 | ||
|
|
d00724f7a9 | ||
|
|
9ed95cf650 | ||
|
|
353c54aca0 | ||
|
|
76a695d3bc | ||
|
|
b230f614b6 | ||
|
|
7d8178e2cb | ||
|
|
d706aeaa96 | ||
|
|
8524d783be | ||
|
|
f121ff0a45 | ||
|
|
6729c65cef | ||
|
|
73722053f2 | ||
|
|
9c707a84d6 | ||
|
|
45466f2cf6 | ||
|
|
065eb7e9bf | ||
|
|
75fedccf62 | ||
|
|
e096e04f69 | ||
|
|
9954729e0d | ||
|
|
3fc80e0d5e | ||
|
|
60466c5a92 | ||
|
|
e7a82219ba | ||
|
|
07c65849f8 | ||
|
|
f7159eae6e | ||
|
|
e181bd9b17 | ||
|
|
6edc5046cd | ||
|
|
1ff1c4afc6 | ||
|
|
1606c7ea24 | ||
|
|
5dbef7bd5d | ||
|
|
d53000f915 | ||
|
|
93382f1cdf | ||
|
|
eadd5c52d7 | ||
|
|
8fe1fcffbd | ||
|
|
ab0248d2f9 | ||
|
|
ef28587250 | ||
|
|
d22456181e | ||
|
|
b07400d6e5 | ||
|
|
04077f5cdb | ||
|
|
f6e8d5ab2f | ||
|
|
9c76951016 | ||
|
|
8f43479760 | ||
|
|
fe81bb2b77 | ||
|
|
a1493ccefb | ||
|
|
626f18b05a | ||
|
|
2203b521b5 | ||
|
|
258d10f86d | ||
|
|
efa5a8b509 | ||
|
|
b09061fc15 | ||
|
|
af01a06c40 | ||
|
|
263a427bbf | ||
|
|
952a6ce95a | ||
|
|
4e0ead7d4a | ||
|
|
45b7a189dd | ||
|
|
1777cd0c52 | ||
|
|
c0285db520 | ||
|
|
1858036f00 | ||
|
|
af49c2cbb7 | ||
|
|
dea7e417b2 | ||
|
|
13ff02cbb3 | ||
|
|
268d31ffa8 | ||
|
|
863f107e7f | ||
|
|
39b5622aac | ||
|
|
32c50e0d6f | ||
|
|
8aa3e6f3fb | ||
|
|
3cc0446d53 | ||
|
|
934947e9a3 | ||
|
|
0f2bb066b3 | ||
|
|
d6b35c14c0 | ||
|
|
2621940248 | ||
|
|
9ed6178def | ||
|
|
ca8ff9bcaa | ||
|
|
3da8ce9f7c | ||
|
|
e176eaf8d9 | ||
|
|
503f279021 | ||
|
|
b591304aa8 | ||
|
|
3aa1944807 | ||
|
|
f5944ba6e8 | ||
|
|
257f637793 | ||
|
|
4e37593235 | ||
|
|
4eb2d0e6ce | ||
|
|
b25981c241 | ||
|
|
efea63e9e7 | ||
|
|
f80e1fb56c | ||
|
|
ea045b2352 | ||
|
|
fcfe8cdbcc | ||
|
|
c0945c19ad | ||
|
|
cb70a78bf8 | ||
|
|
ad6de52b29 | ||
|
|
ccea8c3b4e | ||
|
|
2e647a7e9a | ||
|
|
5e638c523d | ||
|
|
21b2e0c621 | ||
|
|
d74e1bd377 | ||
|
|
558f68bad8 | ||
|
|
4549428e61 | ||
|
|
49cbedf7cf | ||
|
|
44c8982c43 | ||
|
|
5172770dd8 | ||
|
|
9519ff1dd7 | ||
|
|
9d9ecd952f | ||
|
|
dc4439e7b0 | ||
|
|
f6de81e947 | ||
|
|
0ad9ad5d34 | ||
|
|
d862fb2a9b | ||
|
|
5de0e9a3b7 | ||
|
|
8a2eeb9780 | ||
|
|
d8d34c796f | ||
|
|
f4d2c6ce79 | ||
|
|
46d397d824 | ||
|
|
0417f51829 | ||
|
|
1ba3d36efc | ||
|
|
e39159b98b | ||
|
|
83c9568f23 | ||
|
|
d6ab1a17c4 | ||
|
|
eddc229f49 | ||
|
|
61945a51b0 | ||
|
|
9934414824 | ||
|
|
6923eadd06 | ||
|
|
6d655c9b68 | ||
|
|
6c8c372820 | ||
|
|
00cd6f2ea9 | ||
|
|
457732c966 | ||
|
|
fddcf47e13 | ||
|
|
934f726fdb | ||
|
|
0688db31b1 | ||
|
|
c64e586b7c | ||
|
|
3bb37c757b | ||
|
|
1e6547d545 | ||
|
|
37239f31d8 | ||
|
|
527e0a8c50 | ||
|
|
104fea7d94 | ||
|
|
2e5c8dcea4 | ||
|
|
34ca8b83be | ||
|
|
88d9f28d87 | ||
|
|
5eab108ef1 | ||
|
|
4da086664a | ||
|
|
295a363c2b | ||
|
|
fdfb71c862 | ||
|
|
5a2dce122d | ||
|
|
c77ebfea96 | ||
|
|
82d83cee07 | ||
|
|
d63066afbf | ||
|
|
5ddd883098 | ||
|
|
587b80f834 | ||
|
|
3b04a45bf3 | ||
|
|
a5b83d822c | ||
|
|
3763e594eb | ||
|
|
c35aa58669 | ||
|
|
886c2a8871 | ||
|
|
cd4a1fb027 | ||
|
|
f8322188a9 | ||
|
|
e4984a9306 | ||
|
|
67a2fda949 | ||
|
|
e0999cba02 | ||
|
|
c89bb22dc5 | ||
|
|
53cf0631c6 | ||
|
|
86809761b1 | ||
|
|
df76dde9ac | ||
|
|
8a457f4b51 | ||
|
|
51fd5f2d7e | ||
|
|
d94e56698f | ||
|
|
21a545d5ea | ||
|
|
a0e007d087 | ||
|
|
937930b3ef | ||
|
|
8e418e46c4 | ||
|
|
39cd7e1396 | ||
|
|
a07847c5b4 | ||
|
|
04db729b47 | ||
|
|
654ff25033 | ||
|
|
69ecdf9e0b | ||
|
|
2fd605cc6f | ||
|
|
ab20bcc3c9 | ||
|
|
01b7eb7407 | ||
|
|
be9a88e7ef | ||
|
|
dd05ba8332 | ||
|
|
9e29774bfd | ||
|
|
9c60edebe0 | ||
|
|
3d9d9d07a6 | ||
|
|
6c5c21734f | ||
|
|
2a739d7205 | ||
|
|
08fe4f44e4 | ||
|
|
0bba7c2d36 | ||
|
|
82ff56b9fc | ||
|
|
b2660a7eab | ||
|
|
589ee16095 | ||
|
|
54144d1981 | ||
|
|
1dc84bd010 | ||
|
|
84ac9ca460 | ||
|
|
334e504e37 | ||
|
|
3e3953c958 | ||
|
|
e8c9fcc774 | ||
|
|
1e9f0f85ee | ||
|
|
79117e0402 | ||
|
|
b95e4e8e56 | ||
|
|
d0e79ea9eb | ||
|
|
a2710032b8 | ||
|
|
8d81b37149 | ||
|
|
e38dca2bd7 | ||
|
|
b2fb5c94e2 | ||
|
|
b10a25de46 | ||
|
|
01a9111cdb | ||
|
|
ee536468f1 | ||
|
|
6a6b0024c0 | ||
|
|
31a54e0a35 | ||
|
|
33c4d78c11 | ||
|
|
0102c28573 | ||
|
|
c041266e4e | ||
|
|
2e4e19dafc | ||
|
|
df65e1aca0 | ||
|
|
c95b4dec17 | ||
|
|
02be303d37 | ||
|
|
6e6122795b | ||
|
|
352e9a4847 | ||
|
|
887ee61a11 | ||
|
|
3b7db0ec0d | ||
|
|
12c27839ef | ||
|
|
d74dc3378a | ||
|
|
d557f1e1cf | ||
|
|
c11126fa87 | ||
|
|
94bbcdaf2f | ||
|
|
f15a3a6c5c | ||
|
|
22e32fc718 | ||
|
|
fca929373d | ||
|
|
f15243f99e | ||
|
|
4f1da80168 | ||
|
|
fde28d71d7 | ||
|
|
a168479153 | ||
|
|
b8c7c90073 | ||
|
|
4dda33ca60 | ||
|
|
86b0fbef9b | ||
|
|
929dd44cfc | ||
|
|
03b40ad41a | ||
|
|
d6019cbb44 | ||
|
|
ef3b34668b | ||
|
|
bf8a2c11ce | ||
|
|
fdcfe6394d | ||
|
|
d849b0d1a1 | ||
|
|
b390461bd8 | ||
|
|
43d08b3a8f | ||
|
|
a4d5616b7e | ||
|
|
faabf1b7f8 | ||
|
|
04e4b7f745 | ||
|
|
edebafd069 | ||
|
|
079a6ae1cc | ||
|
|
1443cb5d28 | ||
|
|
b4ef70b987 | ||
|
|
f204bb1484 | ||
|
|
ec81455e2b | ||
|
|
0635fbf5eb | ||
|
|
5f47d04c04 | ||
|
|
9b89cc5970 | ||
|
|
0645ea83f3 | ||
|
|
99a9d8adc8 | ||
|
|
14c783ed9c | ||
|
|
6946f22573 | ||
|
|
eb84b0d2bc | ||
|
|
ab334c4e29 | ||
|
|
5a1f0069b9 | ||
|
|
c98fbbffb3 | ||
|
|
4356c0de97 | ||
|
|
7ed80ebd20 | ||
|
|
c8ef3645e4 | ||
|
|
7eda04fc75 | ||
|
|
13da383641 | ||
|
|
5e316491eb | ||
|
|
76606ba4da | ||
|
|
a7f7c5a60a | ||
|
|
18cd4492f3 | ||
|
|
3195cc5789 | ||
|
|
cac316b3ec | ||
|
|
40e2f9ed02 | ||
|
|
a8f8c21c87 | ||
|
|
2ec9c0afea | ||
|
|
9243292055 | ||
|
|
972f0c8ff2 | ||
|
|
6a07ca4fc4 | ||
|
|
9fa64e29bf | ||
|
|
4e36501ca5 | ||
|
|
f789ca07bd | ||
|
|
37d129b997 | ||
|
|
526edfe683 | ||
|
|
7717f6a489 | ||
|
|
cbdd3d6821 | ||
|
|
838a51c0f7 | ||
|
|
ad75d69a0d | ||
|
|
7aced8a463 | ||
|
|
e3cd4c7f0c | ||
|
|
b1f4a38603 | ||
|
|
09b5565279 | ||
|
|
3b6f15975f | ||
|
|
cd5a4d1bf0 | ||
|
|
3e9d94942c | ||
|
|
6c6f4ca803 | ||
|
|
c0df942899 | ||
|
|
fdf6c938bb | ||
|
|
76a4a480fc | ||
|
|
8e71a55e5b | ||
|
|
9f702a8a91 | ||
|
|
7fe41c88b7 | ||
|
|
cce020fd77 | ||
|
|
4fb31bc268 | ||
|
|
ca442784f0 | ||
|
|
c4eb23cd38 | ||
|
|
7daab2910c | ||
|
|
82f43d459e | ||
|
|
cf5e6bd0f7 | ||
|
|
4905826f2f | ||
|
|
ff17b25cf6 | ||
|
|
245c93ddeb | ||
|
|
fc63d0500a | ||
|
|
002110f568 | ||
|
|
6864664759 | ||
|
|
7b82473d6a | ||
|
|
e64b8aa601 | ||
|
|
6c457ab2cd | ||
|
|
a8c4d25dc2 | ||
|
|
c6c355c4a8 | ||
|
|
3cc4de730a | ||
|
|
f145994df5 | ||
|
|
66f308cd1c | ||
|
|
f05a33f361 | ||
|
|
d22e5203c5 | ||
|
|
74055893a2 | ||
|
|
e44817cb97 | ||
|
|
3a3367ced7 | ||
|
|
bfcfe864dc | ||
|
|
9f8b661817 | ||
|
|
157bd41438 | ||
|
|
2300ca567a | ||
|
|
1ae05240c6 | ||
|
|
7391f40410 | ||
|
|
3c981be387 | ||
|
|
bce2ce4c8a | ||
|
|
539625b175 | ||
|
|
126a101b13 | ||
|
|
22503d3b05 | ||
|
|
70b6b8be4f | ||
|
|
32c6751eca | ||
|
|
1c77b926e9 | ||
|
|
a42a1abdc5 | ||
|
|
4234dbdb1f | ||
|
|
d45594ef3b | ||
|
|
5dda632167 | ||
|
|
c41a988faa | ||
|
|
c7a71394fb | ||
|
|
a1145e2556 | ||
|
|
2cb5d70d36 | ||
|
|
f8d8d6c3f6 | ||
|
|
7b1fb05165 | ||
|
|
9fb73e455e | ||
|
|
c0f3883b36 | ||
|
|
0485be551e | ||
|
|
131e5c33b1 | ||
|
|
8b8e65e6bf | ||
|
|
d15fb2652a | ||
|
|
27dfe50d2f | ||
|
|
84ae85c120 | ||
|
|
efaaa701e8 | ||
|
|
3505e2cba2 | ||
|
|
fc9220377b | ||
|
|
830ee5f0bf | ||
|
|
e30f4ece86 | ||
|
|
bbfb2b3fd3 | ||
|
|
b32659f0db | ||
|
|
c70a13bf31 | ||
|
|
c8c7d9bdc0 | ||
|
|
6883d4e422 | ||
|
|
609c0291ef | ||
|
|
6b36359bd0 | ||
|
|
68348d066e | ||
|
|
2354a5390b | ||
|
|
311b6f1407 | ||
|
|
a2f15452d6 | ||
|
|
1359298b63 | ||
|
|
519e5babe8 | ||
|
|
bd820fada9 | ||
|
|
7d66bf5fef | ||
|
|
9ef5f50421 | ||
|
|
10ef0de896 | ||
|
|
c4c336d772 | ||
|
|
a2607f36c2 | ||
|
|
33476a93a4 | ||
|
|
072f26b556 | ||
|
|
f0e721ab18 | ||
|
|
58fa05a98a | ||
|
|
bd02827cdf | ||
|
|
0e8116efd8 | ||
|
|
5928a06bb6 | ||
|
|
5494d46910 | ||
|
|
9ec10a55cf | ||
|
|
bd25c6bf1d | ||
|
|
d9275898f4 | ||
|
|
aa0e9fc80e | ||
|
|
51861e50e1 | ||
|
|
69f52253da | ||
|
|
05fa433341 | ||
|
|
c4640f3bed | ||
|
|
61b2299973 | ||
|
|
6507ca4ab9 | ||
|
|
87a6e5a914 | ||
|
|
41f55c446a | ||
|
|
d80754b545 | ||
|
|
0f6725e1e8 | ||
|
|
7ff1cbe268 | ||
|
|
5dfd3a74c3 | ||
|
|
76bcffe394 | ||
|
|
dcc46434a3 | ||
|
|
9558d85773 | ||
|
|
8c0c0491df | ||
|
|
89e72f0fcb | ||
|
|
dc51d2deed | ||
|
|
41cd098ec2 | ||
|
|
f6a872948f | ||
|
|
fa27cb1ea3 | ||
|
|
771d0d59dd | ||
|
|
579c928cf0 | ||
|
|
b4027f7cf6 | ||
|
|
3f013e65da | ||
|
|
8f634998b7 | ||
|
|
a74d3a715e | ||
|
|
d8dde5481d | ||
|
|
475b049f3c | ||
|
|
28bebb2e2e | ||
|
|
2f154b2c86 | ||
|
|
cf909c766c | ||
|
|
210f73d92e | ||
|
|
b78384e33b | ||
|
|
33bd20ae1f | ||
|
|
44220a1b32 | ||
|
|
c0977e23ac | ||
|
|
ccf4ef6b04 | ||
|
|
d314457228 | ||
|
|
5e9eb2e25b | ||
|
|
d040b26800 | ||
|
|
e26c8accf9 | ||
|
|
74dd405e57 | ||
|
|
7f425fc031 | ||
|
|
63648d418d | ||
|
|
9ccee9325f | ||
|
|
1fb37e628f | ||
|
|
7c2988c8f6 | ||
|
|
f1fb07fb9f | ||
|
|
ee7574dbe7 | ||
|
|
adb7bdd83c | ||
|
|
a8d812f66d | ||
|
|
f2b0421709 | ||
|
|
ca219ebc3a | ||
|
|
2ab4cbd6f4 | ||
|
|
225b3fdc31 | ||
|
|
7d329dc129 | ||
|
|
6c34a10cd4 | ||
|
|
54f32a884b | ||
|
|
b4b609beef | ||
|
|
14fb0ff603 | ||
|
|
2fd102d6c4 | ||
|
|
cbef5fcb48 | ||
|
|
1054062dfb | ||
|
|
a125f0a621 | ||
|
|
ca431364ec | ||
|
|
ee7e3babb8 | ||
|
|
7c478d64e4 | ||
|
|
ce236f5af5 | ||
|
|
3a2e4a5152 | ||
|
|
98b29185d0 | ||
|
|
5bf56f2824 | ||
|
|
56af93e0d1 | ||
|
|
83c4cabaf7 | ||
|
|
d6dd99109e | ||
|
|
d1a61845a5 | ||
|
|
b870de7299 | ||
|
|
411f68d823 | ||
|
|
da2f868ce1 | ||
|
|
65df07fd72 | ||
|
|
49f7acdaa6 | ||
|
|
f6418afc8e | ||
|
|
bbaa2a673a | ||
|
|
411835cd65 | ||
|
|
ee3b745244 | ||
|
|
68374e581a | ||
|
|
232dfe2ca4 | ||
|
|
9fc86d5246 | ||
|
|
b0d4d0ab83 | ||
|
|
cc52a7cf83 | ||
|
|
42dfd3a539 | ||
|
|
b832b663a2 | ||
|
|
8dc16a9400 | ||
|
|
a44586b9e3 | ||
|
|
250af07667 | ||
|
|
17a836a044 | ||
|
|
5dfa3227db | ||
|
|
7b82bd0f3b | ||
|
|
d940e81c73 | ||
|
|
859fa251bc | ||
|
|
ffacaa6f7d | ||
|
|
7db8171d5c | ||
|
|
d69d5534b1 | ||
|
|
230daaa230 | ||
|
|
1290c51b05 | ||
|
|
b7705d9bcf | ||
|
|
c49e438a18 | ||
|
|
3420c3f961 | ||
|
|
fe9bf9adea | ||
|
|
050b4783f0 | ||
|
|
ea77318e13 | ||
|
|
7427419abb | ||
|
|
4c7ea3f2f7 | ||
|
|
5fc7f47ca8 | ||
|
|
b097e52bdc | ||
|
|
53b58e5c91 | ||
|
|
98cc862236 | ||
|
|
09ba23297a | ||
|
|
93609f76da | ||
|
|
e2789e8e0d | ||
|
|
5257d63875 | ||
|
|
e1f56f54b7 | ||
|
|
1ba16b0cec | ||
|
|
9c117ff5c2 | ||
|
|
9e7c8582c4 | ||
|
|
d88fa6aa8c | ||
|
|
d1580b351a | ||
|
|
f577c446fc | ||
|
|
8b853e8b5e | ||
|
|
9bad1c202f | ||
|
|
8da9622a1f | ||
|
|
0ba286d1f1 | ||
|
|
7c6d53b215 | ||
|
|
30e0f160d8 | ||
|
|
741b9ebc71 | ||
|
|
b6ddc33395 | ||
|
|
bd1a695a05 | ||
|
|
708f075e6e | ||
|
|
01acbea445 | ||
|
|
b0c2162847 | ||
|
|
a597e0cb12 | ||
|
|
a27469d77a | ||
|
|
63046dd31d | ||
|
|
e4ae452a70 | ||
|
|
1110ed609e | ||
|
|
6dbcbe8366 | ||
|
|
aed4c74b48 | ||
|
|
de0459d959 | ||
|
|
7b882da357 | ||
|
|
4973b3ef25 | ||
|
|
5ed0d75ddc | ||
|
|
3242949dce | ||
|
|
40e630ccfc | ||
|
|
90642b4262 | ||
|
|
a382cd6551 | ||
|
|
80edb85372 | ||
|
|
f23241ce64 | ||
|
|
7c49d74855 | ||
|
|
0bf660e6a5 | ||
|
|
888955a4dd | ||
|
|
078a1a95b5 | ||
|
|
3e04dfe404 | ||
|
|
dffc7be628 | ||
|
|
2ab3621289 | ||
|
|
ef2d1ad0ac | ||
|
|
247d8287bf | ||
|
|
df2a112825 | ||
|
|
4e2e468a8b | ||
|
|
752acf3124 | ||
|
|
0060b31ab8 | ||
|
|
645aea2d47 | ||
|
|
cf895ab905 | ||
|
|
e410e909be | ||
|
|
ce4988678f | ||
|
|
e087d2a186 | ||
|
|
8dc6fa2001 | ||
|
|
aee3fa924e | ||
|
|
89be0198b5 | ||
|
|
1fea1185dc | ||
|
|
18cd344ab6 | ||
|
|
9f827df32c | ||
|
|
9895628558 | ||
|
|
c160b06f19 | ||
|
|
44c41db93c | ||
|
|
5b92a76da1 | ||
|
|
cba5ac300d | ||
|
|
bebc77fffa | ||
|
|
2787dec93c | ||
|
|
814fdc1213 | ||
|
|
66719f757b | ||
|
|
5ebf4dd9d5 | ||
|
|
cb9ff6c168 | ||
|
|
39c373000b | ||
|
|
fd63f157ef | ||
|
|
41d50ebfc7 | ||
|
|
1aa536d67c | ||
|
|
bc5c9d506e | ||
|
|
91a28d3986 | ||
|
|
29855c8143 | ||
|
|
56be324fe8 | ||
|
|
36c74ee7ca | ||
|
|
229444124e | ||
|
|
a4086ab047 | ||
|
|
ad9e57e6a5 | ||
|
|
f9a5e1c33f | ||
|
|
1c6b791348 | ||
|
|
25f1f59d16 | ||
|
|
1d9e2f72c5 | ||
|
|
5c0f9c71cf | ||
|
|
e05e937225 | ||
|
|
f1dd76ab17 | ||
|
|
ba1505d0bb | ||
|
|
fe81f5f1a1 | ||
|
|
cd2b469274 | ||
|
|
97f9fe4ee7 | ||
|
|
aecc508d1c | ||
|
|
637e828345 | ||
|
|
71ac661243 | ||
|
|
8587aed016 | ||
|
|
8adb166053 | ||
|
|
7369f04d18 | ||
|
|
ba8cdb82cd | ||
|
|
0d1c522b07 | ||
|
|
40bcd4ec82 | ||
|
|
8df3f820f3 | ||
|
|
3201766b4f | ||
|
|
808e46e480 | ||
|
|
bbf33be786 | ||
|
|
a8e36e2b25 | ||
|
|
37f37b892f | ||
|
|
5dd32b9c34 | ||
|
|
15ffae156c | ||
|
|
4a8ce02ac2 | ||
|
|
ca17b30dca | ||
|
|
088aef5f33 | ||
|
|
022af85def | ||
|
|
d89c76ae44 | ||
|
|
5229d9fada | ||
|
|
09ba83181f | ||
|
|
4b2050b216 | ||
|
|
85339c74ca | ||
|
|
e1cc8fdc5b | ||
|
|
ebf328866d | ||
|
|
fc77a5b645 | ||
|
|
80802fb17a | ||
|
|
e280e117d2 | ||
|
|
c27bd7ddf7 | ||
|
|
564c8537ce | ||
|
|
fcb9184dec | ||
|
|
92dbf36c8e | ||
|
|
d300973ab3 | ||
|
|
8986daacf7 | ||
|
|
2929bfb855 | ||
|
|
4fac69383c | ||
|
|
1164fbac08 | ||
|
|
85cf611027 | ||
|
|
bbda350593 | ||
|
|
0e78a21407 | ||
|
|
ca9e1ed617 | ||
|
|
d60509b4f9 | ||
|
|
e9a4ed4ab3 | ||
|
|
0e0ec4b809 | ||
|
|
764f2cd471 | ||
|
|
760ec4ca96 | ||
|
|
e91519b897 | ||
|
|
e5e05757e0 | ||
|
|
8d3222052f | ||
|
|
5526ed6cff | ||
|
|
7d0bc05b15 | ||
|
|
b5bf59f810 | ||
|
|
7edf948299 | ||
|
|
c70ec0e75b | ||
|
|
3e33b354ad | ||
|
|
841c6e9a3d | ||
|
|
67c474d4b0 | ||
|
|
0f1d136c43 | ||
|
|
d66432d2a5 | ||
|
|
d013650223 | ||
|
|
5da778e3d1 | ||
|
|
974ad3ee7d | ||
|
|
dc987f7c11 | ||
|
|
8194604dd9 | ||
|
|
d27727c637 | ||
|
|
dc918f3875 | ||
|
|
fb3151090a | ||
|
|
5185e80ca4 | ||
|
|
83b69fbff3 | ||
|
|
e4a5ad2255 | ||
|
|
aa453d6143 | ||
|
|
46aa8daaca | ||
|
|
ea13429b97 | ||
|
|
030e59671b | ||
|
|
fe8d569d77 | ||
|
|
217404e094 | ||
|
|
e44217d3a5 | ||
|
|
94490e069f | ||
|
|
2f522c1be0 | ||
|
|
cf42252f89 | ||
|
|
3f1e4a1a94 | ||
|
|
bee4260812 | ||
|
|
12713a9ffb | ||
|
|
1c9c93eb05 | ||
|
|
0abfd553de | ||
|
|
fd8ed23848 | ||
|
|
79860a8aae | ||
|
|
281800d7e2 | ||
|
|
145ee48043 | ||
|
|
c194f5abea | ||
|
|
49ef59a7a5 | ||
|
|
12b89fe23b | ||
|
|
a1c74d641c | ||
|
|
40e974ccab | ||
|
|
a65cfca827 | ||
|
|
6ab7cdf7ef | ||
|
|
df79b0ac17 | ||
|
|
a5b343fa4f | ||
|
|
4264042bd4 | ||
|
|
bc935ac7de | ||
|
|
4c515c542b | ||
|
|
ea1fbfbcca | ||
|
|
6f0ab85c7c | ||
|
|
820b516b83 | ||
|
|
02a1a5b6f7 | ||
|
|
ac52bebc76 | ||
|
|
63047f1840 | ||
|
|
0d5c5b20af | ||
|
|
dba51b76a4 | ||
|
|
fd895755c1 | ||
|
|
35917e8933 | ||
|
|
6daf39e5fc | ||
|
|
4ba95a1c30 | ||
|
|
bf8c382d14 | ||
|
|
b600b3eb91 | ||
|
|
36fc0be7bc | ||
|
|
2759404a46 | ||
|
|
7cab0fa310 | ||
|
|
9048f59acb | ||
|
|
7748ea4fe8 | ||
|
|
07d74b61fc | ||
|
|
0b6007b26d | ||
|
|
c3040765bd | ||
|
|
dedf8df377 | ||
|
|
dd0df766ff | ||
|
|
64252804be | ||
|
|
b164c9adeb | ||
|
|
b9c7507780 | ||
|
|
0a11fed54c | ||
|
|
1b15e312b7 | ||
|
|
31908d8477 | ||
|
|
28802137a4 | ||
|
|
06d707be48 | ||
|
|
be89261178 | ||
|
|
d6494b515f | ||
|
|
214926cd77 | ||
|
|
687e43a274 | ||
|
|
0f6e04324b | ||
|
|
f8e4b88516 | ||
|
|
bb3b06e86f | ||
|
|
8421adfeb7 | ||
|
|
24a617c6a8 | ||
|
|
475509ad15 | ||
|
|
0536f90b5f | ||
|
|
558744904b | ||
|
|
d894d9469e | ||
|
|
d0d3288d6e | ||
|
|
f3d792f74f | ||
|
|
60c367ff31 | ||
|
|
7b23c091d5 | ||
|
|
b0e02f9f06 | ||
|
|
355cea2deb | ||
|
|
ca08baa549 | ||
|
|
bef5c4c5cd | ||
|
|
6dc2dee608 | ||
|
|
ecc567f294 | ||
|
|
cc27753642 | ||
|
|
759382aac0 | ||
|
|
5f5ef29e3b | ||
|
|
8d65536806 | ||
|
|
cac14ff353 | ||
|
|
cc881a1da5 | ||
|
|
d6a17f446b | ||
|
|
5ed0245da6 | ||
|
|
cf94ebf383 | ||
|
|
d3200e9421 | ||
|
|
3a945ab3fc | ||
|
|
550a02b3b2 | ||
|
|
90088fb679 | ||
|
|
846b171932 | ||
|
|
573ad960ff | ||
|
|
044c1ccb38 | ||
|
|
811b744711 | ||
|
|
8562dbb779 | ||
|
|
19129ce30e | ||
|
|
ed214635ca | ||
|
|
e0ec674dd7 | ||
|
|
dbb4875b55 | ||
|
|
93ee3e8353 | ||
|
|
74aee971b2 | ||
|
|
2b96a1c741 | ||
|
|
2f70a2cf7d | ||
|
|
6332477235 | ||
|
|
8bbccf60c3 | ||
|
|
68ba31af57 | ||
|
|
5b7fa62cf0 | ||
|
|
3fb8c0df7d | ||
|
|
bf80accb20 | ||
|
|
9c317dfe6d | ||
|
|
8d0dbff086 | ||
|
|
f8788ed37c | ||
|
|
bda09c3060 | ||
|
|
61b3d185f9 | ||
|
|
3a29c895f4 | ||
|
|
819c9d4ce0 | ||
|
|
b472ad0a9e | ||
|
|
4120467dac | ||
|
|
1cd979f934 | ||
|
|
556650f105 | ||
|
|
2a8ea00a4e | ||
|
|
1beb5db8a0 | ||
|
|
66d3196491 | ||
|
|
3bea24246d | ||
|
|
1b2397034f | ||
|
|
f11f6c2557 | ||
|
|
6ae6267556 | ||
|
|
3502f1548c | ||
|
|
e54109f41a | ||
|
|
2afe604112 | ||
|
|
cfa86d3ce5 | ||
|
|
734eba273c | ||
|
|
2d7605a33a | ||
|
|
ff3b67b3cb | ||
|
|
e4bdb04116 | ||
|
|
75397022d9 | ||
|
|
c293e808f8 | ||
|
|
095fe79084 | ||
|
|
321f4f7e9e | ||
|
|
6aece09b7e | ||
|
|
1130e5a5ce | ||
|
|
23709b377e | ||
|
|
91df12984f | ||
|
|
b4485ca970 | ||
|
|
4dbf8e3371 | ||
|
|
0199435e9f | ||
|
|
3351982f60 | ||
|
|
83a23355fc | ||
|
|
856cbed60f | ||
|
|
5fc7e904bc | ||
|
|
62ffbb6470 | ||
|
|
1641e64739 | ||
|
|
8933f6f161 | ||
|
|
97abe86c7f | ||
|
|
a8f55c2339 | ||
|
|
6662ed1523 | ||
|
|
e34e6f0b60 | ||
|
|
8710e9037c | ||
|
|
dd072e4667 | ||
|
|
85fa9ac827 | ||
|
|
49e392659b | ||
|
|
12cfd6b8d2 | ||
|
|
2c86ea3b34 | ||
|
|
198d040cc4 | ||
|
|
03b327e5b4 | ||
|
|
3182d63b9e | ||
|
|
0d0318dfeb | ||
|
|
86f4b770d9 | ||
|
|
07008e069b | ||
|
|
61b39ba1b4 | ||
|
|
fd2b26b169 | ||
|
|
1cc60a50e9 | ||
|
|
22e43a403f | ||
|
|
316f8ba08a | ||
|
|
cd49358fc9 | ||
|
|
9a893ba131 | ||
|
|
c68b124e0c | ||
|
|
a2afe74c3f | ||
|
|
4cac2072ff | ||
|
|
9389404b84 | ||
|
|
b5606334be | ||
|
|
fdc30716dd | ||
|
|
6bc7106bb6 | ||
|
|
462fde037f | ||
|
|
849a70352a | ||
|
|
9cdb3cc856 | ||
|
|
7731928b90 | ||
|
|
31db10b03f | ||
|
|
f0f8dfc7a0 | ||
|
|
470220749a | ||
|
|
802aab161d | ||
|
|
5f4a32e823 | ||
|
|
a1720eb600 | ||
|
|
5c4539e40b | ||
|
|
d0b7ec51c0 | ||
|
|
ce134dba55 | ||
|
|
bb94780a00 | ||
|
|
31d50e2f64 | ||
|
|
5817d17edb | ||
|
|
8fe8bae1e7 | ||
|
|
36006b2436 | ||
|
|
bc9d2c8fac | ||
|
|
306825e71f | ||
|
|
882c033346 | ||
|
|
050011a97f | ||
|
|
6462919c5c | ||
|
|
9bff967085 | ||
|
|
2fafb42a64 | ||
|
|
eccaf2fa6d | ||
|
|
d63cad3447 | ||
|
|
9ac7edc1f1 | ||
|
|
4789cc09c7 | ||
|
|
b0c1daff63 | ||
|
|
b175b76d00 | ||
|
|
1f34ddfea0 | ||
|
|
7dadf79c62 | ||
|
|
cdb89f2006 | ||
|
|
747b1cda72 | ||
|
|
02a99efdc6 | ||
|
|
3989842a07 | ||
|
|
486881c927 | ||
|
|
5172c44a44 | ||
|
|
7811bed44a | ||
|
|
b99fa1d547 | ||
|
|
2397542bf2 | ||
|
|
5c95646d94 | ||
|
|
bec0ad9788 | ||
|
|
e4f0d64e95 | ||
|
|
24407fb7ad | ||
|
|
bb434bebd5 | ||
|
|
4316538b33 | ||
|
|
9ff5472f35 | ||
|
|
579387454b | ||
|
|
34a69f8ace | ||
|
|
fbee213684 | ||
|
|
5875226262 | ||
|
|
54708b6881 | ||
|
|
870e14df1c | ||
|
|
61df20fe21 | ||
|
|
0b901bc5c6 | ||
|
|
3cd273d854 | ||
|
|
ceda10fe85 | ||
|
|
daad347732 | ||
|
|
b13d6fa957 | ||
|
|
6676f02956 | ||
|
|
9a6ac1aff1 | ||
|
|
abf28b8ea8 | ||
|
|
3d35a542ce | ||
|
|
25cc6d0cb2 | ||
|
|
c7d43e1025 | ||
|
|
59f5b9c69d | ||
|
|
7d907c2850 | ||
|
|
250622a5a2 | ||
|
|
629fac9192 | ||
|
|
f6a8cc8c2c | ||
|
|
5cc17da209 | ||
|
|
ba253888c8 | ||
|
|
70cc16bc4a | ||
|
|
d18357d7cf | ||
|
|
6cc3fa69d3 | ||
|
|
8639b8cf5e | ||
|
|
4d53bd2638 | ||
|
|
aa9a0f88f5 | ||
|
|
642b20ba30 | ||
|
|
24de630311 | ||
|
|
23c664a127 | ||
|
|
eb64292864 | ||
|
|
d77c43568a | ||
|
|
dc49396542 | ||
|
|
23a344f5a0 | ||
|
|
dac1243979 | ||
|
|
033ad63962 | ||
|
|
19f6a4448e | ||
|
|
3413f4a8d5 | ||
|
|
8fb062b85f | ||
|
|
364e2bdecb | ||
|
|
443d13eb4e | ||
|
|
618f16c625 | ||
|
|
f10f30929b | ||
|
|
70c7469102 | ||
|
|
5ea18610ac | ||
|
|
22530daf99 | ||
|
|
884f1a3457 | ||
|
|
0e6ed45527 | ||
|
|
b1b65d9178 | ||
|
|
e36209606b | ||
|
|
338fbaa52e | ||
|
|
b7ed4d2a9b | ||
|
|
e25df62cf9 | ||
|
|
9837bf5549 | ||
|
|
ffa61ccd97 | ||
|
|
38e0e15c2b | ||
|
|
1ad31b056b | ||
|
|
b34de1697e | ||
|
|
3a8e0d8903 | ||
|
|
835df5211b | ||
|
|
09e004b62f | ||
|
|
2e751a6772 | ||
|
|
edd47482da | ||
|
|
9c2eff4aee | ||
|
|
60dbf85f6f | ||
|
|
0e88931527 | ||
|
|
7cd358d83b | ||
|
|
156ce06305 | ||
|
|
42dc278cfa | ||
|
|
5436aa72e0 | ||
|
|
032facf7a6 | ||
|
|
17ab9063d4 | ||
|
|
6a52a04714 | ||
|
|
45e9370b36 | ||
|
|
bb2c0fd655 | ||
|
|
047f8629e8 | ||
|
|
7c9351e1eb | ||
|
|
aaca2327b8 | ||
|
|
0227c9b7fb | ||
|
|
6ecf801eb7 | ||
|
|
3c5c9dbec2 | ||
|
|
58492e135a | ||
|
|
94987d7676 | ||
|
|
6d81a55490 | ||
|
|
c2dd3936b9 | ||
|
|
6bc0922f80 | ||
|
|
26dfadfea4 | ||
|
|
07039128db | ||
|
|
cc1799d1b2 | ||
|
|
5482ce7faf | ||
|
|
b06c35ff6c | ||
|
|
09b0227cbf | ||
|
|
5efb1acfc8 | ||
|
|
8ff4f3bd51 | ||
|
|
b720811918 | ||
|
|
2ff0458943 | ||
|
|
a594034297 | ||
|
|
8ce460c060 | ||
|
|
208c495a19 | ||
|
|
fcdd355990 | ||
|
|
b23da3b181 | ||
|
|
aca0e8a59a | ||
|
|
c04579e399 | ||
|
|
878a824c30 | ||
|
|
e5c1a199fe | ||
|
|
5e49b28d93 | ||
|
|
bb21c7ca4f | ||
|
|
9143f818c3 | ||
|
|
59ea6ac4f2 | ||
|
|
bac0d8adfa | ||
|
|
5c1bb39d17 | ||
|
|
c791f0c036 | ||
|
|
040ca9ca76 | ||
|
|
99d3512b02 | ||
|
|
44272bfdbf | ||
|
|
a2d049e3ae | ||
|
|
53b53d70fa | ||
|
|
749ca99b34 | ||
|
|
bd10fbbf52 | ||
|
|
db0f9d97f1 | ||
|
|
9036af7471 | ||
|
|
ad50825ff3 | ||
|
|
5074d939f8 | ||
|
|
310e710d75 | ||
|
|
b4814ecbf6 | ||
|
|
4f21da9822 | ||
|
|
8b969a38a4 | ||
|
|
0a6deae7fb | ||
|
|
0173c64451 | ||
|
|
4621367218 | ||
|
|
f8bb4ef7a7 | ||
|
|
4c37594c67 | ||
|
|
cfc25aa725 | ||
|
|
9a111c9aea | ||
|
|
3f7dec1ebd | ||
|
|
04deb8631f | ||
|
|
e224b8f146 | ||
|
|
7cede22d8f | ||
|
|
bd911642f5 | ||
|
|
3a6feb1500 | ||
|
|
37cbb85790 | ||
|
|
d8c8aa4009 | ||
|
|
6211631fdc | ||
|
|
675ad43fc0 | ||
|
|
c89ae9c790 | ||
|
|
dbc76bf3ce | ||
|
|
2ecce20f07 | ||
|
|
b2f2bf7a70 | ||
|
|
13c07cf443 | ||
|
|
240ca13f23 | ||
|
|
74388fd02e | ||
|
|
08e6fe2789 | ||
|
|
59dec2acd4 | ||
|
|
3a3bf6e294 | ||
|
|
b0cc232d87 | ||
|
|
6371a68ed3 | ||
|
|
8184f40f10 | ||
|
|
4da2cf58f6 | ||
|
|
007828d5f1 | ||
|
|
7792abe2c0 | ||
|
|
3ddadd3d11 | ||
|
|
43d0836510 | ||
|
|
62f51d9168 | ||
|
|
33b54daf18 | ||
|
|
b92b67e0f5 | ||
|
|
c905921f4d | ||
|
|
4cce6cdce9 | ||
|
|
c7dae1445a | ||
|
|
f7ab40426d | ||
|
|
0dc11d1d63 | ||
|
|
56b64aa6b8 | ||
|
|
8608fcefb6 | ||
|
|
48d7e7e97a | ||
|
|
fb358d372a | ||
|
|
12b5e5f8b1 | ||
|
|
2b75070262 | ||
|
|
066af00545 | ||
|
|
af6cc98f71 | ||
|
|
c7d1d49eb5 | ||
|
|
352f2a4bd0 | ||
|
|
4ec3b848d0 | ||
|
|
f807bb00b7 | ||
|
|
598f44d5aa | ||
|
|
bab68e8c91 | ||
|
|
7a97c48d19 | ||
|
|
0f3bebe404 | ||
|
|
9f7ea1034f | ||
|
|
ae4d160a11 | ||
|
|
5c2f2935fe | ||
|
|
ea9786f957 | ||
|
|
9da173bc31 | ||
|
|
13d651e382 | ||
|
|
74efa6332b | ||
|
|
1274f502a8 | ||
|
|
2a27e4cea1 | ||
|
|
5d502799df | ||
|
|
c3f105753d | ||
|
|
a42b8bb002 | ||
|
|
04bb11a37a | ||
|
|
a5ef770dcd | ||
|
|
8884982431 | ||
|
|
bd23dd256a | ||
|
|
071391c946 | ||
|
|
e55dff6fa4 | ||
|
|
a9a754a3d0 | ||
|
|
f780310e0f | ||
|
|
ff0129e52f | ||
|
|
029c89c751 | ||
|
|
dcf750c2c2 | ||
|
|
bb660db9f7 | ||
|
|
6d0d70ab2b | ||
|
|
ac689b5488 | ||
|
|
510b6bd5bd | ||
|
|
2154dd2d78 | ||
|
|
141ea351ad | ||
|
|
a7a7380d71 | ||
|
|
60704ce592 | ||
|
|
2a4f8f3946 | ||
|
|
4e384638f3 | ||
|
|
62c91fca07 | ||
|
|
05bf96ad86 | ||
|
|
6b5825c96f | ||
|
|
e6db9e08c8 | ||
|
|
f91eb75eb3 | ||
|
|
46b84c43f5 | ||
|
|
7bde5319d9 | ||
|
|
5a2010006a | ||
|
|
ffa4270f7e | ||
|
|
8f81708baf | ||
|
|
09a430dedd | ||
|
|
e3b337640c | ||
|
|
5b627064e6 | ||
|
|
55783c414e | ||
|
|
6aabb6033b | ||
|
|
2397a8f3d6 | ||
|
|
537559b590 | ||
|
|
14b6a5e31f | ||
|
|
c04339b026 | ||
|
|
c82cfa6ecc | ||
|
|
5e9f7ed87b | ||
|
|
10f8d0856d | ||
|
|
c7c9eefc26 | ||
|
|
ddf346dd37 | ||
|
|
0f0f1e3d5c | ||
|
|
f79860aa7f | ||
|
|
bf086c62e4 | ||
|
|
ea83cfbc18 | ||
|
|
171ff185dc | ||
|
|
722e4838f9 | ||
|
|
344db7454b | ||
|
|
e4869bce4a | ||
|
|
7637573c34 | ||
|
|
db137b5980 | ||
|
|
704446fe1c | ||
|
|
62333c3c30 | ||
|
|
ef987358f3 | ||
|
|
c646961130 | ||
|
|
aa1088a0c6 | ||
|
|
bdb06601d5 | ||
|
|
d89d7b412a | ||
|
|
673e850292 | ||
|
|
ba36aad5c2 | ||
|
|
ac94f8e4e0 | ||
|
|
571f2a1a16 | ||
|
|
41551f66ab | ||
|
|
c5cff30ac8 | ||
|
|
6acc3bbd87 | ||
|
|
35f66382a7 | ||
|
|
a93ee3e248 | ||
|
|
64bb4480ee | ||
|
|
7274fad247 | ||
|
|
693f0077ef | ||
|
|
d531fc630f | ||
|
|
f1236bf31c | ||
|
|
c153fb4d4c | ||
|
|
29bee2b4eb | ||
|
|
ea17d04d39 | ||
|
|
461d447ffe | ||
|
|
257707e7ff | ||
|
|
8afd0c31d1 | ||
|
|
d019f9ce2b | ||
|
|
9a6ff322f8 | ||
|
|
5df4f6187b | ||
|
|
ee930ce3f8 | ||
|
|
86bd6bd89c | ||
|
|
46cb6c6ada | ||
|
|
8655868d6f | ||
|
|
06ef8ce005 | ||
|
|
e738881207 | ||
|
|
4fa4e2e84d | ||
|
|
f8cf48d35b | ||
|
|
2b83719402 | ||
|
|
2e9bde5707 | ||
|
|
212bdaf329 | ||
|
|
357f15b0be | ||
|
|
935f987b36 | ||
|
|
e029c7903a | ||
|
|
af289e10ab | ||
|
|
2d20a1593d | ||
|
|
d96550683b | ||
|
|
629522fb4c | ||
|
|
336f92d50c | ||
|
|
e69c21596b | ||
|
|
1f2f41a771 | ||
|
|
305aee1b49 | ||
|
|
fbfa299e67 | ||
|
|
4f6c71f833 | ||
|
|
88af6201f1 | ||
|
|
5d323fb491 | ||
|
|
4e9f918b5a | ||
|
|
8e08fdc0c6 | ||
|
|
9a77e64ead | ||
|
|
9a1cbea9bc | ||
|
|
9fec481018 | ||
|
|
24a7606254 | ||
|
|
e3c8d71a01 | ||
|
|
ea31a1c4b8 | ||
|
|
8622aa2f81 | ||
|
|
8ebb857660 | ||
|
|
d9766367d5 | ||
|
|
927b24dc40 | ||
|
|
a1126bff88 | ||
|
|
f89f2a350d | ||
|
|
7883b5d2a2 | ||
|
|
9972377ad2 | ||
|
|
daf6861e60 | ||
|
|
eca7a6ae1e | ||
|
|
0016d15c84 | ||
|
|
06481dcaab | ||
|
|
4a73019098 | ||
|
|
8565f8d329 | ||
|
|
11f082290c | ||
|
|
bb00cb0945 | ||
|
|
e621136f16 | ||
|
|
ee3621104d | ||
|
|
fce56036f0 | ||
|
|
d3663c46e3 | ||
|
|
a4f314b7ff | ||
|
|
b00e37509d | ||
|
|
3243f56af3 | ||
|
|
a946fddf22 | ||
|
|
fcc87d468e | ||
|
|
a40b125986 | ||
|
|
f5545d55c1 | ||
|
|
9cc8c710fd | ||
|
|
e9da222324 | ||
|
|
3da4ad9be3 | ||
|
|
c063552f59 | ||
|
|
bf6586b554 | ||
|
|
89b2ecc807 | ||
|
|
5691564e80 | ||
|
|
8c6130f264 | ||
|
|
3c230ce015 | ||
|
|
eb2017c427 | ||
|
|
9faa9cb223 | ||
|
|
76630b14c1 | ||
|
|
1f099440ac | ||
|
|
b955f8f621 | ||
|
|
a92a6d3b89 | ||
|
|
253c1dcf34 | ||
|
|
7b33bcaa8e | ||
|
|
e3ad6958f9 | ||
|
|
2915043876 | ||
|
|
ae3e96aa5e | ||
|
|
5a4b85ed88 | ||
|
|
063677e6e9 | ||
|
|
4fc3ad4e08 | ||
|
|
57eaa41a12 | ||
|
|
f348dd8ed2 | ||
|
|
a910491319 | ||
|
|
ab08e086d4 | ||
|
|
29d756c2f5 | ||
|
|
53026171ea | ||
|
|
9d49b0ba5e | ||
|
|
fab90f1e90 | ||
|
|
0003b6a218 | ||
|
|
c44cbc1fa7 | ||
|
|
22c674eb88 | ||
|
|
487055f223 | ||
|
|
9de8beddf7 | ||
|
|
34263a8ca6 | ||
|
|
d983fb8d2e | ||
|
|
d852045e1f | ||
|
|
8fd6a9796d | ||
|
|
a84649ba07 | ||
|
|
1b33a49066 | ||
|
|
ba3ef45bce | ||
|
|
2ebf347236 | ||
|
|
00d6da8b0d | ||
|
|
50606b8e34 | ||
|
|
b798ce46a3 | ||
|
|
e413aafe07 | ||
|
|
f3fe6c6d13 | ||
|
|
8f551f726b | ||
|
|
e5616ebbdb | ||
|
|
b103483ab5 | ||
|
|
a248ada3dd | ||
|
|
fd02c25f8b | ||
|
|
18957e4484 | ||
|
|
9c2c527f01 | ||
|
|
e19ef83fb5 | ||
|
|
39691919cd | ||
|
|
34c398fd4f | ||
|
|
a59404197c | ||
|
|
9d8448f9db | ||
|
|
1bbd739131 | ||
|
|
3ec32b01ec | ||
|
|
8bc32bab29 | ||
|
|
3e326c02c9 | ||
|
|
0f43ffca1d | ||
|
|
bb778ecb1f | ||
|
|
6d043a28a5 | ||
|
|
a86f4802a3 | ||
|
|
5770b2f9a6 | ||
|
|
262c024b61 | ||
|
|
994f4f4c20 | ||
|
|
cf8d4effe1 | ||
|
|
bd7b75801d | ||
|
|
dab091fda9 | ||
|
|
ac36a93d5a | ||
|
|
1659b03f62 | ||
|
|
f278c932b4 | ||
|
|
056b8eb71d | ||
|
|
c5e85cb531 | ||
|
|
07ce5cf20b | ||
|
|
14abd86023 | ||
|
|
e4854bd257 | ||
|
|
dba13afe57 | ||
|
|
b49938cfcc | ||
|
|
34329cf783 | ||
|
|
9c97726dbc | ||
|
|
31a6da33c0 | ||
|
|
0e7aa68bd8 | ||
|
|
ed8ac7c79c | ||
|
|
545ded29f5 | ||
|
|
d908baf252 | ||
|
|
72661a376b | ||
|
|
9c842315ec | ||
|
|
3512f5a5f9 | ||
|
|
7ff45ac8f5 | ||
|
|
1ce5a1bf28 | ||
|
|
1c53aaec59 | ||
|
|
05c4a4b604 | ||
|
|
1e068fe4e0 | ||
|
|
80638fa053 | ||
|
|
5301f90f8b | ||
|
|
203c0c7631 | ||
|
|
6b475c686a | ||
|
|
ca6c1a3d36 | ||
|
|
0af1f8f6d1 | ||
|
|
43674ab48e | ||
|
|
c24a0ef0ee | ||
|
|
b670993976 | ||
|
|
6ea8276e99 | ||
|
|
e481f068c2 | ||
|
|
c4d1ac9b9b | ||
|
|
7f4b857914 | ||
|
|
fcac155fcb | ||
|
|
9314e8c0fd | ||
|
|
43e3606d63 | ||
|
|
1da755d932 | ||
|
|
4932cde3cf | ||
|
|
b0ed737d4e | ||
|
|
f839256ffb | ||
|
|
6cb3c62ff9 | ||
|
|
003486244b | ||
|
|
b3ec99f296 | ||
|
|
ff5039c9f6 | ||
|
|
1221ac1cc0 | ||
|
|
1fafa621b4 | ||
|
|
480d812687 | ||
|
|
285d776c21 | ||
|
|
bf790334ec | ||
|
|
9abea099f4 | ||
|
|
4e612f7bce | ||
|
|
9081dcee74 | ||
|
|
85e0830ca5 | ||
|
|
1a6de599ba | ||
|
|
43b859ff7b | ||
|
|
549f5a4fe6 | ||
|
|
7f1d1f85e8 | ||
|
|
725e1658f7 | ||
|
|
6b5779bcf8 | ||
|
|
6ee73b8ff9 | ||
|
|
8b1ee7529d | ||
|
|
1784850441 | ||
|
|
fb779f6f02 | ||
|
|
65ae0724c3 | ||
|
|
de04424f72 | ||
|
|
76338689e7 | ||
|
|
c94ea9d669 | ||
|
|
99e28f20cf | ||
|
|
4f9901c5fe | ||
|
|
f643d8223c | ||
|
|
12bd64e970 | ||
|
|
3c715fd75b | ||
|
|
c3b3f2fb2f | ||
|
|
488588081e | ||
|
|
1b72cfee5b | ||
|
|
cdc6027941 | ||
|
|
aface37a9e | ||
|
|
dcf90fba85 | ||
|
|
6d767e7900 | ||
|
|
9fea56b5f8 | ||
|
|
daeb84e9fe | ||
|
|
cac896e871 | ||
|
|
0143851e83 | ||
|
|
a72551e11b | ||
|
|
48590ea9b6 | ||
|
|
b01d95c15d | ||
|
|
6433e00bb3 | ||
|
|
b9c9cc95a1 | ||
|
|
d862ba14f3 | ||
|
|
e5880c8aa6 | ||
|
|
7d86f7a5e9 | ||
|
|
e5c0d34d91 | ||
|
|
b911cdf0ae | ||
|
|
bf550f5348 | ||
|
|
3a94d4f0be | ||
|
|
86b169912d | ||
|
|
f46902fa6b | ||
|
|
7f042a583d | ||
|
|
0ad5ad4b4b | ||
|
|
ff6ad9e181 | ||
|
|
111a3af6d6 | ||
|
|
8154b700e1 | ||
|
|
a9a778be57 | ||
|
|
362a835691 | ||
|
|
dd250dc838 | ||
|
|
99bc4ff232 | ||
|
|
f4ec91d3ec | ||
|
|
aba7d2a324 | ||
|
|
6889524375 | ||
|
|
1cc9deab39 | ||
|
|
955ffba2a9 | ||
|
|
cd06b36af7 | ||
|
|
f4816602ee | ||
|
|
e5fe173125 | ||
|
|
15d3d4ef10 | ||
|
|
767d4f61b3 | ||
|
|
632800454c | ||
|
|
e7840a0ada | ||
|
|
ec8fd288c2 | ||
|
|
4f64ef995b | ||
|
|
b28116e9b0 | ||
|
|
c8118dee3e | ||
|
|
936c5ca3d7 | ||
|
|
1278260f3c | ||
|
|
7fd43d6316 | ||
|
|
abd1750bd2 | ||
|
|
ad66b78a7f | ||
|
|
629185ee2a | ||
|
|
551717687a | ||
|
|
ab994e28c8 | ||
|
|
0a8ec439ba | ||
|
|
efff0ea4f1 | ||
|
|
de3211f6d6 | ||
|
|
a3de261c42 | ||
|
|
7d9456c22e | ||
|
|
1ebf77ee79 | ||
|
|
ecfb2ed35b | ||
|
|
346f6ea4e8 | ||
|
|
6d203047f2 | ||
|
|
aa13f89293 | ||
|
|
619bc2db1d | ||
|
|
8258d8059c | ||
|
|
7f2ab75e9b | ||
|
|
604c92205e | ||
|
|
b24409e014 | ||
|
|
17a3cc4628 | ||
|
|
d7d1246bf2 | ||
|
|
08a46b7c92 | ||
|
|
7c6f901d03 | ||
|
|
7db8a03581 | ||
|
|
01652fd586 | ||
|
|
3c2f155cb4 | ||
|
|
d33f176f98 | ||
|
|
5e0305dc22 | ||
|
|
487e3ebceb | ||
|
|
06b2eb17f9 | ||
|
|
ed352aa541 | ||
|
|
23025c4b77 | ||
|
|
494308738b | ||
|
|
0c7b20876a | ||
|
|
b9b1d37baa | ||
|
|
a356eafdaa | ||
|
|
229f3ae1ff | ||
|
|
b595db6509 | ||
|
|
d187228592 | ||
|
|
f27330cb72 | ||
|
|
8fe0901f17 | ||
|
|
b018cf10ce | ||
|
|
6e6f661619 | ||
|
|
c4cdce5bfc | ||
|
|
7506dbb643 | ||
|
|
98bf47bfd6 | ||
|
|
245bf1d96e | ||
|
|
80023948c4 | ||
|
|
82ed772c77 | ||
|
|
a5ae9d3197 | ||
|
|
1e5929f8fa | ||
|
|
47b1e6f67f | ||
|
|
e12a8361e4 | ||
|
|
33bd604dc3 | ||
|
|
7a16600f50 | ||
|
|
e0616d471d | ||
|
|
4070a8ae6d | ||
|
|
f6aa6e376b | ||
|
|
9e5a50f9b5 | ||
|
|
9e9f61c249 | ||
|
|
42c5df2c1b | ||
|
|
0ede68b054 | ||
|
|
fc2be00a11 | ||
|
|
ad879aac73 | ||
|
|
dbc99486c1 | ||
|
|
a2c7181b37 | ||
|
|
728f632f68 | ||
|
|
4a9ad9e17e | ||
|
|
0dec58089e | ||
|
|
da58e766e1 | ||
|
|
ea63443208 | ||
|
|
9f05c83fb9 | ||
|
|
69449663c2 | ||
|
|
24b6e72c12 | ||
|
|
0b5d36e888 | ||
|
|
61576acec0 | ||
|
|
1d7008c9a1 | ||
|
|
8450083be8 | ||
|
|
0f4f0817ff | ||
|
|
865b17ff04 | ||
|
|
023eb2dd77 | ||
|
|
dcc4eb02da | ||
|
|
42dab97dc9 | ||
|
|
c94a71dbb9 | ||
|
|
c367066727 | ||
|
|
5a2807f3a0 | ||
|
|
02fc3ead24 | ||
|
|
9ac574ec89 | ||
|
|
24dd9edced | ||
|
|
b996c1fe1b | ||
|
|
2fed9e535c | ||
|
|
5d2b212757 | ||
|
|
171e4f9689 | ||
|
|
f6e93b5e44 | ||
|
|
55f7a45355 | ||
|
|
5de58f08ab | ||
|
|
1a7d105d8d | ||
|
|
875ea9b499 | ||
|
|
f959eb5d1b | ||
|
|
31c384cdf8 | ||
|
|
88a6f93e78 | ||
|
|
4964d69d07 | ||
|
|
54664adf4e | ||
|
|
a94ba34321 | ||
|
|
82b6f8f370 | ||
|
|
802236a201 | ||
|
|
c67c7c66b8 | ||
|
|
e11f39047b | ||
|
|
be46092e74 | ||
|
|
44c9798e7c | ||
|
|
ea88e50957 | ||
|
|
babaad9c18 | ||
|
|
b29b58e27b | ||
|
|
c2b67434da | ||
|
|
fc33fc3474 | ||
|
|
ae3420fb17 | ||
|
|
7522dc5bb4 | ||
|
|
e49b19a538 | ||
|
|
2f50472c00 | ||
|
|
88283344c4 | ||
|
|
762729d03b | ||
|
|
d0fddb49f8 | ||
|
|
bfc8154d7d | ||
|
|
48791d631e | ||
|
|
78a4313ef0 | ||
|
|
5acfa76172 | ||
|
|
458004adb3 | ||
|
|
d05da63300 | ||
|
|
44dd0a04bd | ||
|
|
c3453e4f35 | ||
|
|
0b9d193a00 | ||
|
|
04e4d15221 | ||
|
|
64aa772a58 | ||
|
|
da190bcd66 | ||
|
|
82c9e7225a | ||
|
|
ba3297bfed | ||
|
|
eb90ef2c8a | ||
|
|
8b5a5bc0d9 | ||
|
|
1721617943 | ||
|
|
1e96c5e167 | ||
|
|
353309812c | ||
|
|
e340b53e30 | ||
|
|
092f276537 | ||
|
|
9bd79920cc | ||
|
|
baeb3ea890 | ||
|
|
11d23ef644 | ||
|
|
cf6795d693 | ||
|
|
593e7ef293 | ||
|
|
29e6fa110d | ||
|
|
eb7e1a1ec1 | ||
|
|
0c1ba60273 | ||
|
|
f2e6c8d4de | ||
|
|
7325d54d58 | ||
|
|
b2ed125d6e | ||
|
|
7cbe853773 | ||
|
|
0a96edf3cb | ||
|
|
64e43d4fee | ||
|
|
05116a2914 | ||
|
|
ab933eb087 | ||
|
|
7e5a37fddc | ||
|
|
da5a1f912c | ||
|
|
b2485f0c47 | ||
|
|
8ca5588a22 | ||
|
|
548a10029e | ||
|
|
f5e5ff2fe2 | ||
|
|
265453b5a7 | ||
|
|
67b4b2ccc8 | ||
|
|
0e15eff54e | ||
|
|
2f0909d91e | ||
|
|
f5f92fe30e | ||
|
|
07f8f36a84 | ||
|
|
cc65384092 | ||
|
|
7c1443cdd0 | ||
|
|
678fa54119 | ||
|
|
3008a4f872 | ||
|
|
febafd9e44 | ||
|
|
5ff037aa9e | ||
|
|
68a4a1e8e1 | ||
|
|
823e0fcb39 | ||
|
|
449c08cbfa | ||
|
|
5e982a0832 | ||
|
|
c09a0a2dd8 | ||
|
|
1f35ff9acd | ||
|
|
228c4d1aef | ||
|
|
a5d51bf47d | ||
|
|
4f17293d1a | ||
|
|
044d4d3556 | ||
|
|
6e7a02d30b | ||
|
|
b95b589d49 | ||
|
|
33f5fa6cb0 | ||
|
|
f2d254d1bd | ||
|
|
8c03177cde | ||
|
|
d35239d364 | ||
|
|
3fecdf8813 | ||
|
|
b0d6138e47 | ||
|
|
7a3806e659 | ||
|
|
e83567c0f1 | ||
|
|
167d4bc642 | ||
|
|
752bdba383 | ||
|
|
447eb03126 | ||
|
|
1b13b0f841 | ||
|
|
b98a4b3425 | ||
|
|
0fd8424124 | ||
|
|
b0f5c6fefe | ||
|
|
7bf867f8e8 | ||
|
|
5cacc78db3 | ||
|
|
c12062ec71 | ||
|
|
ee0ad1d392 | ||
|
|
7a434edbb3 | ||
|
|
1e824d81bc | ||
|
|
56837741f7 | ||
|
|
61e2cc35f8 | ||
|
|
ae46c37f43 | ||
|
|
68ed891b0f | ||
|
|
d4d748d801 | ||
|
|
fdffe24292 | ||
|
|
8583ae8b7d | ||
|
|
7d9a2e947d | ||
|
|
7ec1fd3f8b | ||
|
|
88922114e0 | ||
|
|
b91d25c962 | ||
|
|
45bd135183 | ||
|
|
0eb2d25a55 | ||
|
|
b5540991c3 | ||
|
|
26c8590a2b | ||
|
|
c16321300c | ||
|
|
a6224ff4c3 | ||
|
|
bada5688fd | ||
|
|
b7844aad20 | ||
|
|
9ff1127f25 | ||
|
|
8273c8bced | ||
|
|
26b14e1548 | ||
|
|
3c147e85aa | ||
|
|
f2395ad7bf | ||
|
|
330d5159f4 | ||
|
|
d3e870d992 | ||
|
|
5a325382c8 | ||
|
|
b720dccaeb | ||
|
|
d3e57ed0c9 | ||
|
|
2285a919a0 | ||
|
|
dd2c0b7fd4 | ||
|
|
5b1e30c2d8 | ||
|
|
83bd1d2db2 | ||
|
|
18e1eab082 | ||
|
|
75b59e64ac | ||
|
|
f8e8a60864 | ||
|
|
a48894abaf | ||
|
|
96c9d37399 | ||
|
|
57e6c8e9b2 | ||
|
|
3c20bcb00f | ||
|
|
14a2270e1c | ||
|
|
e9933eba30 | ||
|
|
fa083d6e2a | ||
|
|
479be36988 | ||
|
|
546d03c21a | ||
|
|
3b8a6cc841 | ||
|
|
9c6cbaff82 | ||
|
|
1c9d68fcb2 | ||
|
|
810c303a52 | ||
|
|
9d72b542eb | ||
|
|
d0e35f79c5 | ||
|
|
c26865436d | ||
|
|
eace9f2cd3 | ||
|
|
ff1427278d | ||
|
|
7e47cd0829 | ||
|
|
13af06acae | ||
|
|
3c9ca436f3 | ||
|
|
c74a5a88b4 | ||
|
|
f9b8092054 | ||
|
|
ab2f4d08b2 | ||
|
|
606d7774a4 | ||
|
|
8e3a860ed7 | ||
|
|
39a0ff2bde | ||
|
|
ede67127dc | ||
|
|
e0e4bffb67 | ||
|
|
2ec00ce50f | ||
|
|
2ce886b9fe | ||
|
|
e068d78c95 | ||
|
|
c2465637b3 | ||
|
|
611aedf097 | ||
|
|
257dd26c58 | ||
|
|
119c6c4a82 | ||
|
|
6bbdbf71b6 | ||
|
|
48b0222d5d | ||
|
|
df34a26f31 | ||
|
|
ec710c89b2 | ||
|
|
cfcf136257 | ||
|
|
d56278b0bd | ||
|
|
897f278d3d | ||
|
|
d1f5db2195 | ||
|
|
4a352f4269 | ||
|
|
5e4ac05bb8 | ||
|
|
45b77f8744 | ||
|
|
23594e80f4 | ||
|
|
3b9be65438 | ||
|
|
7b0e5aeeda | ||
|
|
91b047854d | ||
|
|
d320ba1de8 | ||
|
|
cb3ce29e0b | ||
|
|
0619184fed | ||
|
|
61370baba7 | ||
|
|
3c239c8b1a | ||
|
|
6bc9c37235 | ||
|
|
7a44de9e4e | ||
|
|
2ed23c55c0 | ||
|
|
31defc43b0 | ||
|
|
3035417772 | ||
|
|
9ec09955af | ||
|
|
54b85a6eeb | ||
|
|
547a56c0e5 | ||
|
|
48e3773fb4 | ||
|
|
56f053a605 | ||
|
|
2df6c9fa5c | ||
|
|
378b503e34 | ||
|
|
547167bb7c | ||
|
|
6eaeee69dd | ||
|
|
beb5583b23 | ||
|
|
1be1c85f5b | ||
|
|
061e0a72af | ||
|
|
7d58679f65 | ||
|
|
d4925d7a68 | ||
|
|
eb380feb54 | ||
|
|
c5a84d91e8 | ||
|
|
a7e8033a85 | ||
|
|
478e7c417a | ||
|
|
293ea440fe | ||
|
|
1de3516033 | ||
|
|
b68b57c213 | ||
|
|
a14c604b99 | ||
|
|
39549a02b1 | ||
|
|
8b557774b7 | ||
|
|
7151575972 | ||
|
|
6d53c488b5 | ||
|
|
10005f91eb | ||
|
|
dc57448f3a | ||
|
|
266bdeb26b | ||
|
|
7d683638d7 | ||
|
|
45f901db00 | ||
|
|
99038ad54d | ||
|
|
fec604c3ef | ||
|
|
caec41a883 | ||
|
|
2d17ff5ace | ||
|
|
b8d8e91a46 | ||
|
|
b8353f02b7 | ||
|
|
feed155138 | ||
|
|
133c9a6fb2 | ||
|
|
e6362da180 | ||
|
|
ff9f954cba | ||
|
|
be3aed93b1 | ||
|
|
e9e6473499 | ||
|
|
ded043986c | ||
|
|
ebfd198db2 | ||
|
|
e16e9c75be | ||
|
|
186eacb62f | ||
|
|
4082dcf7d6 | ||
|
|
e13c6913c1 | ||
|
|
84161663ef | ||
|
|
5fa77fef77 | ||
|
|
9a352b81fd | ||
|
|
d4db300cba | ||
|
|
aba6216161 | ||
|
|
a300a2fa69 | ||
|
|
c065ac8c9c | ||
|
|
1d15736fc8 | ||
|
|
d044bd2640 | ||
|
|
ff70cb0460 | ||
|
|
5c4a619463 | ||
|
|
c15b5f2c86 | ||
|
|
16cfc2fcf3 | ||
|
|
137476cbfb | ||
|
|
e03cefd7c7 | ||
|
|
38bb3e3ed2 | ||
|
|
5704751b88 | ||
|
|
7876dc239b | ||
|
|
47d69e47b5 | ||
|
|
62a6ee8570 | ||
|
|
71b813e43c | ||
|
|
544d8d9cef | ||
|
|
fcc1f4f5cb | ||
|
|
cf41488e53 | ||
|
|
a0bf3fbecd | ||
|
|
7d84137a79 | ||
|
|
2960acc2b6 | ||
|
|
887ac00407 | ||
|
|
2f35eadb9b | ||
|
|
078256dba8 | ||
|
|
8e7082b3aa | ||
|
|
e2c320e27d | ||
|
|
7a84203930 | ||
|
|
7ea32ee2c4 | ||
|
|
c28700cf2d | ||
|
|
ad7eb2da6d | ||
|
|
3bed02e2d0 | ||
|
|
887db136b0 | ||
|
|
0e4268630c | ||
|
|
b3fa226dff | ||
|
|
5a7cb82de1 | ||
|
|
3aa1b2e565 | ||
|
|
280ce3deb8 | ||
|
|
32033e0a82 | ||
|
|
e0745dafd7 | ||
|
|
d183933e3e | ||
|
|
e8f30d5f43 | ||
|
|
16822a2715 | ||
|
|
b0b65db96c | ||
|
|
98e80ada70 | ||
|
|
9d7270fb87 | ||
|
|
aef0c9821c | ||
|
|
16ae30744d | ||
|
|
5826a92dd7 | ||
|
|
96b698384d | ||
|
|
5d0bd2fa3d | ||
|
|
92c010d4f7 | ||
|
|
3f4d75b8c3 | ||
|
|
16b12398ad | ||
|
|
6d5a0b4004 | ||
|
|
824db2e9b4 | ||
|
|
0bae0c1a04 | ||
|
|
08109ed280 | ||
|
|
58fc1493f9 | ||
|
|
c009860f8f | ||
|
|
4ac61e25d3 | ||
|
|
55d85cf2d6 | ||
|
|
690b6ec969 | ||
|
|
b1232288a8 | ||
|
|
ece5c35801 | ||
|
|
ade032357b | ||
|
|
d80b856b2b | ||
|
|
8120857730 | ||
|
|
85a9783e7a | ||
|
|
9929a02b24 | ||
|
|
5e45b132b9 | ||
|
|
e4497eb7a4 | ||
|
|
3142059e02 | ||
|
|
8f094cf52a | ||
|
|
5149a29f46 | ||
|
|
3c5f4d4fc1 | ||
|
|
5f4e33d089 | ||
|
|
8c6ba6cf4e | ||
|
|
e897b52b25 | ||
|
|
795e08719f | ||
|
|
d90680d892 | ||
|
|
a7302a2c7b | ||
|
|
486a69592f | ||
|
|
3c05823443 | ||
|
|
13c3ea8078 | ||
|
|
3c69310de5 | ||
|
|
f32ee28abb | ||
|
|
593324ca66 | ||
|
|
8fc7522955 | ||
|
|
8c3e6bc3e6 | ||
|
|
ad4a86e123 | ||
|
|
aa8f2be5b5 | ||
|
|
1250df240e | ||
|
|
fb18842156 | ||
|
|
d4f390e372 | ||
|
|
99f911359a | ||
|
|
7b8faf0fff | ||
|
|
aab9750f21 | ||
|
|
0518e43e5b | ||
|
|
92c8d64f45 | ||
|
|
584ee3314f | ||
|
|
845376db4f | ||
|
|
a6064ea48f | ||
|
|
4dbc274d59 | ||
|
|
878bcdd7ad | ||
|
|
e3eef553a7 | ||
|
|
4d52292017 | ||
|
|
a64d14749a | ||
|
|
5c2c4b30e5 | ||
|
|
0143d6a3fa | ||
|
|
a450d1bfba | ||
|
|
cf0489fb83 | ||
|
|
b020694215 | ||
|
|
33fb4efaef | ||
|
|
762cc1d3ee | ||
|
|
edad965b29 | ||
|
|
e21e1c0c2f | ||
|
|
11dac7bbef | ||
|
|
d1e9762b93 | ||
|
|
91f2070891 | ||
|
|
803a0f175d | ||
|
|
589baef929 | ||
|
|
ad810909f0 | ||
|
|
192fe6b11a | ||
|
|
bf056c0f5d | ||
|
|
02e0f80d71 | ||
|
|
54296b02ac | ||
|
|
5b2039fa07 | ||
|
|
1c99019f97 | ||
|
|
5258e10cb1 | ||
|
|
c8e83135e1 | ||
|
|
0453db72f5 | ||
|
|
23a4d59c0a | ||
|
|
27bac3add4 | ||
|
|
f19ca56b72 | ||
|
|
d1bf76337e | ||
|
|
14554c98cd | ||
|
|
304d735c7e | ||
|
|
67cbb9dcf8 | ||
|
|
b077529bb9 | ||
|
|
5354fabe84 | ||
|
|
7c1bb8d6a8 | ||
|
|
70cb14677e | ||
|
|
fc93994c84 | ||
|
|
61c2a72e45 | ||
|
|
ed30adc2d7 | ||
|
|
9b5ccff7e3 | ||
|
|
e5b993dd76 | ||
|
|
d70a6d276b | ||
|
|
1c543f3a5e | ||
|
|
3070792cff | ||
|
|
8823a7e8df | ||
|
|
0e39838f57 | ||
|
|
3648ddb21c | ||
|
|
4b5583cc5b | ||
|
|
a0d76bf639 | ||
|
|
13a476a717 | ||
|
|
4be1360692 | ||
|
|
458f9dbaf6 | ||
|
|
a7a7b53d04 | ||
|
|
5bf3f0bc32 | ||
|
|
e95ac5d9c9 | ||
|
|
a294d9658a | ||
|
|
1e293abb2c | ||
|
|
0ba20d9f37 | ||
|
|
98c9c247be | ||
|
|
7a5e16657b | ||
|
|
09b1df7600 | ||
|
|
7d3b16d3ab | ||
|
|
fc2f70d298 | ||
|
|
b338b9c54d | ||
|
|
b49c227b08 | ||
|
|
38a217c93a | ||
|
|
8620f6315b | ||
|
|
cd5d9af34f | ||
|
|
9ee198ea26 | ||
|
|
81c648b8eb | ||
|
|
7f62283d43 | ||
|
|
6629bfcb04 | ||
|
|
9ac86c73cd | ||
|
|
bb10182347 | ||
|
|
1f4be17602 | ||
|
|
8ecacf5ff9 | ||
|
|
ba33e73da3 | ||
|
|
0643946696 | ||
|
|
f9e5e07768 | ||
|
|
650b890778 | ||
|
|
c06c83b299 | ||
|
|
e995e7bec0 | ||
|
|
79d2b5abd5 | ||
|
|
8fc8b5803f | ||
|
|
ea46aeb77e | ||
|
|
5496bbae3d | ||
|
|
1e6b7a34c2 | ||
|
|
32a9207366 | ||
|
|
347f675454 | ||
|
|
005c5554ca | ||
|
|
a16b45eba6 | ||
|
|
2bea8089b5 | ||
|
|
251d87362d | ||
|
|
fdc371a715 | ||
|
|
870349fc7b | ||
|
|
ec7719fef6 | ||
|
|
8b8115d8ad | ||
|
|
46fbcf1bc9 | ||
|
|
68d2cf91ea | ||
|
|
2a978ae6bd | ||
|
|
1e8a5e3015 | ||
|
|
ae5d2ae35e | ||
|
|
a85af68895 | ||
|
|
7d6e1fb81f | ||
|
|
644ab58052 | ||
|
|
394a4b9160 | ||
|
|
0d20ff493d | ||
|
|
ea17ec1289 | ||
|
|
a110a85aaa | ||
|
|
104e0c915d | ||
|
|
f0b60a4301 | ||
|
|
e9c8e018e2 | ||
|
|
f140537ba6 | ||
|
|
a672c8316c | ||
|
|
1746b524c7 | ||
|
|
d6b293d17b | ||
|
|
a6b72bcc45 | ||
|
|
823c780a87 | ||
|
|
4111ecea19 | ||
|
|
a1e8558bb9 | ||
|
|
4ce152489f | ||
|
|
93f1506365 | ||
|
|
90360081fd | ||
|
|
7feead6cde | ||
|
|
e572ff0c73 | ||
|
|
86fefbf8d3 | ||
|
|
5a6f8cbfab | ||
|
|
b8f0991e89 | ||
|
|
f6b302546a | ||
|
|
2072e2e55d | ||
|
|
e4e049e502 | ||
|
|
24458bb27e | ||
|
|
e3e3cf2a9f | ||
|
|
d1abca605f | ||
|
|
7bb2fa955d | ||
|
|
67d6e29690 | ||
|
|
180d65b855 | ||
|
|
7a50fe57f5 | ||
|
|
27fe865f17 | ||
|
|
373eefa5ee | ||
|
|
264904f68e | ||
|
|
878cad6586 | ||
|
|
5d767f7ccd | ||
|
|
c5a8dad98f | ||
|
|
a50a425d9b | ||
|
|
8390819f32 | ||
|
|
742180e73b | ||
|
|
154020439c | ||
|
|
95110c8caa | ||
|
|
749a0eca23 | ||
|
|
64ddb83767 | ||
|
|
17b8c6a58e | ||
|
|
e7d38e04ed | ||
|
|
c94bac5a24 | ||
|
|
15d3b09d55 | ||
|
|
aa9de216b9 | ||
|
|
29857082ee | ||
|
|
986c8c9ed0 | ||
|
|
c7ac1263c0 | ||
|
|
45988c086f | ||
|
|
4823ea99ad | ||
|
|
e96b64ef1f | ||
|
|
a14cf049ee | ||
|
|
9d28d69f9a | ||
|
|
d4ded7fcb4 | ||
|
|
09fbfa9c3e | ||
|
|
6b1fcf8009 | ||
|
|
9d7c000d4e | ||
|
|
14688fcbfe | ||
|
|
5e142c23f9 | ||
|
|
5a48a3a6d0 | ||
|
|
7e4b358a9e | ||
|
|
407e992f48 | ||
|
|
22b8cf7615 | ||
|
|
25b556e8bf | ||
|
|
ba23b98a81 | ||
|
|
8cd10323ee | ||
|
|
33ad8b3f41 | ||
|
|
6dda78bed8 | ||
|
|
faa5d08633 | ||
|
|
2323fc89fd | ||
|
|
1da36d7c08 | ||
|
|
1e71bfb687 | ||
|
|
c0d13f7322 | ||
|
|
c998cb5738 | ||
|
|
0f68404ed3 | ||
|
|
6fdf1db1ee | ||
|
|
5f5d573afc | ||
|
|
a1afa0e362 | ||
|
|
cfcf775019 | ||
|
|
1f1b934bb9 | ||
|
|
ff04a581e1 | ||
|
|
323629b0bf | ||
|
|
20f6884924 | ||
|
|
4a6d29e716 | ||
|
|
1b01001342 | ||
|
|
6ba2eff004 | ||
|
|
356bdb0d29 | ||
|
|
1982076de0 | ||
|
|
68a71d3ca6 | ||
|
|
a78c50d6cc | ||
|
|
84fb39f532 | ||
|
|
25a37673a3 | ||
|
|
acbc3f414b | ||
|
|
3eea2bc60e | ||
|
|
89d8dfb35e | ||
|
|
ead627bdd4 | ||
|
|
9b4c334efb | ||
|
|
2233633bb2 | ||
|
|
c80876db1d | ||
|
|
13507e9f98 | ||
|
|
15a24b995e | ||
|
|
b1e77dc6a3 | ||
|
|
957e7f0de9 | ||
|
|
bf060b62ab | ||
|
|
533e62e5ab | ||
|
|
ae1de07242 | ||
|
|
fa1a40c2e3 | ||
|
|
1f4eadfe4d | ||
|
|
2b1560421a | ||
|
|
87435a585d | ||
|
|
6d56b78e87 | ||
|
|
bf89c14459 | ||
|
|
35179bbb64 | ||
|
|
5fd75ab919 | ||
|
|
84c77414a8 | ||
|
|
e21d74eb6e | ||
|
|
511c24cd17 | ||
|
|
69918ef5ab | ||
|
|
5c0fb77eeb | ||
|
|
663c4a42c1 | ||
|
|
7c4a361bb0 | ||
|
|
0d0d1f8ebb | ||
|
|
acc02f0d74 | ||
|
|
71cf485ae8 | ||
|
|
27123daf77 | ||
|
|
de649aac98 | ||
|
|
44e7ebf5dd | ||
|
|
3e0f62ac95 | ||
|
|
c73c766cb1 | ||
|
|
5757dcaf2f | ||
|
|
891f537f8e | ||
|
|
c035592fb5 | ||
|
|
62bfd35b35 | ||
|
|
b3ecf00132 | ||
|
|
810a48e65e | ||
|
|
d81eea5f61 | ||
|
|
2cb4248bd9 | ||
|
|
cb059620b1 | ||
|
|
31f03e8a7a | ||
|
|
f8d28d310e | ||
|
|
6229edb430 | ||
|
|
f8eaf156e2 | ||
|
|
822b809174 | ||
|
|
af2b091f9a | ||
|
|
ee5df66612 | ||
|
|
7e5fed03fa | ||
|
|
0846133faf | ||
|
|
273643c438 | ||
|
|
24d54b41d8 | ||
|
|
9dee4dbd73 | ||
|
|
aafa0183ad | ||
|
|
acfdf93b87 | ||
|
|
c621d053c6 | ||
|
|
45ab5d5b13 | ||
|
|
f288e775fc | ||
|
|
2c4876217b | ||
|
|
8c0c378a37 | ||
|
|
2e045d8315 | ||
|
|
fd1e6f9ec2 | ||
|
|
199d4363fd | ||
|
|
3fdb13e2f4 | ||
|
|
4f7f2794c5 | ||
|
|
0b76a73962 | ||
|
|
b209dc74b5 | ||
|
|
4369ac38be | ||
|
|
45b16a8baf | ||
|
|
6bda33f40e | ||
|
|
b66e35f9d6 | ||
|
|
5d64000a40 | ||
|
|
a15bfc2588 | ||
|
|
490b197f4a | ||
|
|
4e86df49a1 | ||
|
|
c1ef30a561 | ||
|
|
0e36b2aa60 | ||
|
|
16ec1828f5 | ||
|
|
22fdffeab1 | ||
|
|
5bc13cc1cc | ||
|
|
328c9c6999 | ||
|
|
19c17d1d6a | ||
|
|
57d9268011 | ||
|
|
42ab29c131 | ||
|
|
1a4f197fa7 | ||
|
|
6905e258db | ||
|
|
fca2426bc3 | ||
|
|
e29b721cf7 | ||
|
|
d36d5053b7 | ||
|
|
64b16e4168 | ||
|
|
7b94de64b6 | ||
|
|
0cfef23aaa | ||
|
|
842f16e8a0 | ||
|
|
8997c2364f | ||
|
|
40f9b76016 | ||
|
|
68a3a5bc2f | ||
|
|
637446e2bc | ||
|
|
f1300adcbe | ||
|
|
772a460bd4 | ||
|
|
5f4bba2ae5 | ||
|
|
8e360f9516 | ||
|
|
61b4a19b82 | ||
|
|
48ebbb6439 | ||
|
|
e1f4704793 | ||
|
|
a58ff3889b | ||
|
|
8d2476ca0e | ||
|
|
185ba1e56a | ||
|
|
e30570a54f | ||
|
|
42762abad9 | ||
|
|
f8dddcae9c | ||
|
|
6ea6adbcc2 | ||
|
|
dd310396c9 | ||
|
|
6f1a3ec464 | ||
|
|
5c55f8281f | ||
|
|
154dca77cb | ||
|
|
44280723a0 | ||
|
|
2bc61c5523 | ||
|
|
1f1d370348 | ||
|
|
f01f4d4177 | ||
|
|
b3b2492e39 | ||
|
|
aa460cdfdb | ||
|
|
68e7778cb1 | ||
|
|
ea74392715 | ||
|
|
bf39d98a64 | ||
|
|
7ece6b4552 | ||
|
|
503c346630 | ||
|
|
17cd7246b8 | ||
|
|
9899611910 | ||
|
|
1eafb358d4 | ||
|
|
26bab3f988 | ||
|
|
0e1b8c7aad | ||
|
|
5db9ab231b | ||
|
|
8959bd9a9f | ||
|
|
5a9be56e76 | ||
|
|
0cdd42f7e4 | ||
|
|
fa95e6aa23 | ||
|
|
35b452e6bd | ||
|
|
c56e10044b | ||
|
|
1ca7ce2b8d | ||
|
|
2b92caea80 | ||
|
|
8069f262bb | ||
|
|
f6d643c709 | ||
|
|
0b4a10a109 | ||
|
|
eb58989f6b | ||
|
|
a9b121ca89 | ||
|
|
5db8306557 | ||
|
|
2fdd8a3e81 | ||
|
|
c876f21ef3 | ||
|
|
f8e87704a2 | ||
|
|
56c5880014 | ||
|
|
7462438cbe | ||
|
|
a3fb3e7196 | ||
|
|
144f073c62 | ||
|
|
45ed3c204e | ||
|
|
6465965ac8 | ||
|
|
2900f3eb31 | ||
|
|
89ffb93ec5 | ||
|
|
52869d557a | ||
|
|
5324b574d3 | ||
|
|
085672396d | ||
|
|
ad623a0b59 | ||
|
|
15bff55a66 | ||
|
|
21ad463edf | ||
|
|
699b88c3e1 | ||
|
|
f5f3627aff | ||
|
|
3decfd668d | ||
|
|
1d24b7f8c3 | ||
|
|
29dc256a4f | ||
|
|
d1906eec9a | ||
|
|
f1e024f67f | ||
|
|
b22bd6219d | ||
|
|
b1b4ed9c0c | ||
|
|
330ce1a68a | ||
|
|
1e231ecd86 | ||
|
|
bb05876536 | ||
|
|
b2a2c02eac | ||
|
|
a5d081eae5 | ||
|
|
2dc6f4fa0f | ||
|
|
d10cf0b444 | ||
|
|
ce27e666ad | ||
|
|
fdc23ccb1b | ||
|
|
4f0476dd20 | ||
|
|
643ea17272 | ||
|
|
a921fca398 | ||
|
|
91f72d1f82 | ||
|
|
7d34375077 | ||
|
|
8650f1059b | ||
|
|
26b26b4ab0 | ||
|
|
ca2a634d97 | ||
|
|
21a15def92 | ||
|
|
4062735a01 | ||
|
|
73afde7b71 | ||
|
|
684bb08a8d | ||
|
|
3554e0b087 | ||
|
|
976a72c833 | ||
|
|
c7ff7ab896 | ||
|
|
a1b1cb2963 | ||
|
|
11829db7ca | ||
|
|
3c226bb99f | ||
|
|
b8adaad7e3 | ||
|
|
0de862590b | ||
|
|
140dd409d2 | ||
|
|
71bfb9d7d8 | ||
|
|
e35d7746b7 | ||
|
|
aea528655a | ||
|
|
915a67d0c4 | ||
|
|
85e947383a | ||
|
|
6c7fbe0271 | ||
|
|
9ce368c9e1 | ||
|
|
a1a83a4ea7 | ||
|
|
c7f5e5d0c9 | ||
|
|
1bde299d6f | ||
|
|
50600ebfb0 | ||
|
|
de4ae79cf3 | ||
|
|
945fc61529 | ||
|
|
de84938fce | ||
|
|
29d7d10d5b | ||
|
|
db8176ecc1 | ||
|
|
87f40affc1 | ||
|
|
9dec3904ca | ||
|
|
e7eb31ad48 | ||
|
|
25d0cce0ca | ||
|
|
c7689ec171 | ||
|
|
d4bf0bf877 | ||
|
|
aa6822fa14 | ||
|
|
9c2b61909b | ||
|
|
f769e571e4 | ||
|
|
274ee6d1a2 | ||
|
|
3b73f6690e | ||
|
|
164bf71469 | ||
|
|
2a0d18cf41 | ||
|
|
b5568edd02 | ||
|
|
b0442d0ce8 | ||
|
|
2acb7fb2aa | ||
|
|
e8fe0cf3c4 | ||
|
|
9096a6f51c | ||
|
|
827f1e3b3f | ||
|
|
c7e1211fb1 | ||
|
|
76cabb03d3 | ||
|
|
8723410029 | ||
|
|
e95c0a1e71 | ||
|
|
786e0eb5ce | ||
|
|
ae16bfb2d8 | ||
|
|
29a200f6f3 | ||
|
|
510168afe3 | ||
|
|
f27ffb8efc | ||
|
|
89a37950cc | ||
|
|
65dff35e1e | ||
|
|
c2956c6b83 | ||
|
|
b32f67a8a9 | ||
|
|
0d88744fb8 | ||
|
|
177f37d06f | ||
|
|
4dbdaef4cf | ||
|
|
0b8541733b | ||
|
|
bdc1298557 | ||
|
|
f7f8d0f24e | ||
|
|
7f52ade062 | ||
|
|
df059bed47 | ||
|
|
0913b8ef91 | ||
|
|
bd8c71d3d0 | ||
|
|
4dbbd3e8c7 | ||
|
|
68d8d61fec | ||
|
|
4c99a1649d | ||
|
|
a56e7c62ac | ||
|
|
f7d2222f18 | ||
|
|
0c076004c8 | ||
|
|
bf9b5f28c1 | ||
|
|
9465779a16 | ||
|
|
8e2b932b12 | ||
|
|
6d72b15356 | ||
|
|
a9ba7b2cdd | ||
|
|
d59e2a9e54 | ||
|
|
ee41abd1a8 | ||
|
|
207c218a16 | ||
|
|
9980d10c96 | ||
|
|
e0af9c3bb9 | ||
|
|
1827bdff68 | ||
|
|
691ead1e2f | ||
|
|
f6a998a901 | ||
|
|
9c6c376512 | ||
|
|
9af17368af | ||
|
|
c3780a7ecb | ||
|
|
a583b6d8e4 | ||
|
|
61b5c92698 | ||
|
|
55c8ea8e59 | ||
|
|
16daf5e57c | ||
|
|
7b74874945 | ||
|
|
9fab568c18 | ||
|
|
7319ebd433 | ||
|
|
2394f4f4a9 | ||
|
|
30f70faf68 | ||
|
|
51ef58fbae | ||
|
|
c1080e7459 | ||
|
|
9c3d2350ea | ||
|
|
ac23eae97a | ||
|
|
900de8bfd5 | ||
|
|
aacdb6f80f | ||
|
|
bc23621d00 | ||
|
|
0260f0de34 | ||
|
|
6946d5cf8b | ||
|
|
f4ec424590 | ||
|
|
cefc7c0917 | ||
|
|
8aa7ef3e42 | ||
|
|
c3d6c39406 | ||
|
|
e3bdb359ea | ||
|
|
22ae5f4890 | ||
|
|
0d6ce1ad8c | ||
|
|
a56404d38e | ||
|
|
4e26d7b668 | ||
|
|
007a26d085 | ||
|
|
7cb420c2c1 | ||
|
|
e69948ccbb | ||
|
|
af3775cbc9 | ||
|
|
78555a50e8 | ||
|
|
0193878767 | ||
|
|
71cdad332b | ||
|
|
16260c15d6 | ||
|
|
4edfa78bd0 | ||
|
|
55fea45ed8 | ||
|
|
ec98adf0d2 | ||
|
|
c9e25b38a8 | ||
|
|
902bb9b25e | ||
|
|
753c50eb70 | ||
|
|
e6aed221a9 | ||
|
|
e8e07b6461 | ||
|
|
41100bb362 | ||
|
|
4d4340aa36 | ||
|
|
05dbc4f660 | ||
|
|
088a2c2da9 | ||
|
|
5b63d649f7 | ||
|
|
54626dd29f | ||
|
|
3bb77e930d | ||
|
|
125fa1898a | ||
|
|
544c2d7b04 | ||
|
|
02f7c40f1a | ||
|
|
f9d06510a0 | ||
|
|
b6e4528902 | ||
|
|
2cace3b020 | ||
|
|
c373864370 | ||
|
|
a516c9660b | ||
|
|
954322bbde | ||
|
|
8ebb55a444 | ||
|
|
a406af3879 | ||
|
|
7ec609c4ed | ||
|
|
a0e3953a87 | ||
|
|
d980ad10cf | ||
|
|
093f16cf4e | ||
|
|
8478385a66 | ||
|
|
533bb1d574 | ||
|
|
910d64f269 | ||
|
|
748a144747 | ||
|
|
a4901508aa | ||
|
|
29694ff3f4 | ||
|
|
cae1f83a53 | ||
|
|
24d077ce8a | ||
|
|
785ce7670b | ||
|
|
972f33b580 | ||
|
|
5c986abf57 | ||
|
|
a33b33f71f | ||
|
|
dd36038d2d | ||
|
|
a1b6551e73 | ||
|
|
e006b4b058 | ||
|
|
2988c8bcbb | ||
|
|
445df872a7 | ||
|
|
dccdd615d3 | ||
|
|
2b7f6ba4fb | ||
|
|
86de352d6a | ||
|
|
6cc072bdd8 | ||
|
|
9cba895395 | ||
|
|
a7a5e1a496 | ||
|
|
94e5aabc39 | ||
|
|
21de2e9959 | ||
|
|
35928d7fde | ||
|
|
13161996b7 | ||
|
|
1500892775 | ||
|
|
b9a5a999cb | ||
|
|
a4c96eb91a | ||
|
|
03943f1585 | ||
|
|
596814c9b4 | ||
|
|
30bbac4481 | ||
|
|
31de283bea | ||
|
|
6f521027d4 | ||
|
|
77b4440471 | ||
|
|
d13afcc15a | ||
|
|
d1f07ef339 | ||
|
|
a334563929 | ||
|
|
7dd5543dda | ||
|
|
725b2f99ce | ||
|
|
370efa8a1d | ||
|
|
cabff886d3 | ||
|
|
4ecbd9dacb | ||
|
|
771acb9497 | ||
|
|
55cfe73afc | ||
|
|
082ba71455 | ||
|
|
48c664666b | ||
|
|
58c89f189a | ||
|
|
91b099c77c | ||
|
|
ecc03beffb | ||
|
|
1c95641985 | ||
|
|
67fc1e3129 | ||
|
|
77295483a3 | ||
|
|
965b29cd14 | ||
|
|
f8346bb575 | ||
|
|
fbe83f8adc | ||
|
|
6cd3181afe | ||
|
|
32a2989a04 | ||
|
|
074e50bb58 | ||
|
|
ed61bcca4d | ||
|
|
444754f752 | ||
|
|
83a809c62a | ||
|
|
78c3d043eb | ||
|
|
82f918aa99 | ||
|
|
adb0d9b5f1 | ||
|
|
efa71cc9a7 | ||
|
|
74fbbc42b1 | ||
|
|
041dc1ae54 | ||
|
|
ad4c790544 | ||
|
|
b0df24e48c | ||
|
|
9b2e86a5c3 | ||
|
|
d0c8de6da2 | ||
|
|
3e5f66f671 | ||
|
|
9afad6ed83 | ||
|
|
b3adcfe170 | ||
|
|
1337494985 | ||
|
|
4a776d4d0b | ||
|
|
58110cdb96 | ||
|
|
08eb72105b | ||
|
|
a6da7e3cd8 | ||
|
|
4091439102 | ||
|
|
554e18d05b | ||
|
|
c3866c9e79 | ||
|
|
eb3ae6604b | ||
|
|
c36988d177 | ||
|
|
85cb484926 | ||
|
|
67b0713a62 | ||
|
|
c25770fedd | ||
|
|
bfb714e576 | ||
|
|
5b61273847 | ||
|
|
a7f06431d9 | ||
|
|
5b2065032e | ||
|
|
3e05078ed6 | ||
|
|
32b80e3a09 | ||
|
|
a7e3640191 | ||
|
|
a56f472adf | ||
|
|
75fa8d657f | ||
|
|
5632d597ba | ||
|
|
cf71c2e029 | ||
|
|
0636ecea47 | ||
|
|
de91f5ae9b | ||
|
|
a4990a8363 | ||
|
|
7cb2ba1a65 | ||
|
|
a6626ea66d | ||
|
|
0a220b88ad | ||
|
|
3817aa452b | ||
|
|
e0486d146d | ||
|
|
a056c0dfa5 | ||
|
|
9091203500 | ||
|
|
4555b39ff0 | ||
|
|
14d73e7f5b | ||
|
|
7dc5c992ea | ||
|
|
41dd2f7332 | ||
|
|
6e9718443a | ||
|
|
e179eabb97 | ||
|
|
3278bc46f4 | ||
|
|
f524f0e259 | ||
|
|
5354c5e7b5 | ||
|
|
5e3d81475b | ||
|
|
d2b1868514 | ||
|
|
c14a08ca40 | ||
|
|
74bd7637a5 | ||
|
|
44ea3bf179 | ||
|
|
06986144aa | ||
|
|
39394063cf | ||
|
|
6fdb7aa05b | ||
|
|
c19c6afa08 | ||
|
|
286f876bf7 | ||
|
|
f8488c360a | ||
|
|
f46ece1554 | ||
|
|
45befba712 | ||
|
|
298e72c3e6 | ||
|
|
bb01c623c9 | ||
|
|
0d7d3f799e | ||
|
|
75db693647 | ||
|
|
f41673bfbd | ||
|
|
5cc87fa56e | ||
|
|
9ee8cd5583 | ||
|
|
b92179cf5c | ||
|
|
7af8deae73 | ||
|
|
0f2b50816a | ||
|
|
d5e0d681e5 | ||
|
|
637c0c4cf7 | ||
|
|
ac3516569d | ||
|
|
0168c86d7a | ||
|
|
7f719b4853 | ||
|
|
c9c1296e38 | ||
|
|
b7e01cc097 | ||
|
|
302054f955 | ||
|
|
ac11dad736 | ||
|
|
284cb51917 | ||
|
|
8db344082f | ||
|
|
35e195d338 | ||
|
|
0f2b0cb13a | ||
|
|
ab433ffa4a | ||
|
|
9f4e82f302 | ||
|
|
f1782c29bd | ||
|
|
413a2af13e | ||
|
|
8585d8b4fa | ||
|
|
6f17d10149 | ||
|
|
5079f0a9d2 | ||
|
|
9167b84331 | ||
|
|
1af875416f | ||
|
|
10fa44a00a | ||
|
|
7446424a69 | ||
|
|
df063c42e1 | ||
|
|
576bea3a90 | ||
|
|
55df9d517b | ||
|
|
372a20dfd5 | ||
|
|
721983551c | ||
|
|
eb1ffa3a60 | ||
|
|
69ecff015f | ||
|
|
25463565c0 | ||
|
|
4d49aeac5e | ||
|
|
4f596d061e | ||
|
|
62c337e5d0 | ||
|
|
b340c92cd2 | ||
|
|
e78377edd1 | ||
|
|
3f952e455e | ||
|
|
d3cca3c5db | ||
|
|
17c3d0b033 | ||
|
|
bb3197f863 | ||
|
|
d14d046cc5 | ||
|
|
da45e7f10c | ||
|
|
f3ae589f0e | ||
|
|
cb3af301d3 | ||
|
|
48ce9c78b2 | ||
|
|
3992aeebeb | ||
|
|
da9bcac667 | ||
|
|
5002510d43 | ||
|
|
587bb51013 | ||
|
|
d83c36dd0f | ||
|
|
d0bcfd4327 | ||
|
|
c27bc67a4b | ||
|
|
b60353da3f | ||
|
|
7a12fa043a | ||
|
|
0a0bb4ed48 | ||
|
|
14ecefdf5e | ||
|
|
81ddf5fe49 | ||
|
|
0c64adbeaf | ||
|
|
f4b80d5fd8 | ||
|
|
aa5b1f951b | ||
|
|
423ddcdaf9 | ||
|
|
3b9fc69f44 | ||
|
|
3d04c0bad5 | ||
|
|
c14a8e16ad | ||
|
|
16a5ea4c15 | ||
|
|
bb7532935e | ||
|
|
e88ec76817 | ||
|
|
3bcdf27e45 | ||
|
|
ebc2d06273 | ||
|
|
2d45ab829d | ||
|
|
36c6cca200 | ||
|
|
992229e94a | ||
|
|
98e6c376ad | ||
|
|
bf6f829561 | ||
|
|
1d4e4f09e4 | ||
|
|
2408e32596 | ||
|
|
c4362cd5f8 | ||
|
|
b1c3f1b226 | ||
|
|
e0ac832aab | ||
|
|
087e93c985 | ||
|
|
31d6d1c9a5 | ||
|
|
eb1d5ccb9f | ||
|
|
c83f3a7da6 | ||
|
|
258538bee2 | ||
|
|
fcf49b32de | ||
|
|
832e50712e | ||
|
|
e8100f1ad2 | ||
|
|
3ada190f0c | ||
|
|
d9b1c6a72f | ||
|
|
83c191892d | ||
|
|
7037f23f47 | ||
|
|
61c06327eb | ||
|
|
2cbcddde7f | ||
|
|
0395ecfb60 | ||
|
|
9002ae199a | ||
|
|
fa8e80aa1d | ||
|
|
c710d1e279 | ||
|
|
48ab4f6525 | ||
|
|
642b2f087f | ||
|
|
7f2b1c8a75 | ||
|
|
69ec94f111 | ||
|
|
c2374d293f | ||
|
|
7afe7bd16b | ||
|
|
bf64c89334 | ||
|
|
399120094b | ||
|
|
ab9a793482 | ||
|
|
9d4154956a | ||
|
|
3c272f6406 | ||
|
|
7c86760dbe | ||
|
|
1318c22b6b | ||
|
|
9de36f5fa3 | ||
|
|
caf3065e01 | ||
|
|
90d260e83f | ||
|
|
b32e651c72 | ||
|
|
89d4fb8624 | ||
|
|
bd0cbfa235 | ||
|
|
6342442bae | ||
|
|
f6b4993bd9 | ||
|
|
f9357bc0c0 | ||
|
|
592da646d0 | ||
|
|
eee7aa5d60 | ||
|
|
b18e748574 | ||
|
|
36282c2a4a | ||
|
|
5befe20b98 | ||
|
|
406ce053f6 | ||
|
|
1395c98675 | ||
|
|
bfd3a64713 | ||
|
|
a076943e46 | ||
|
|
9393d67233 | ||
|
|
f97f887fd5 | ||
|
|
d50b9b4b58 | ||
|
|
eaeb84e88f | ||
|
|
c153a60bfd | ||
|
|
a71f6c15f1 | ||
|
|
021800d963 | ||
|
|
bb715f5868 | ||
|
|
1654607cbd | ||
|
|
7b8754c15c | ||
|
|
d35bdc33a8 | ||
|
|
3cd96278fb | ||
|
|
a4efa0d630 | ||
|
|
e9c382512e | ||
|
|
c4bfc904c9 | ||
|
|
f91fff94e2 | ||
|
|
8b2a129528 | ||
|
|
cc4b42de8e | ||
|
|
d5a49e563d | ||
|
|
35d2bfdc03 | ||
|
|
7582baa723 | ||
|
|
481b0b5652 | ||
|
|
b7149d69fd | ||
|
|
3300943c79 | ||
|
|
49c2c26e26 | ||
|
|
4bad1b96b8 | ||
|
|
d85306e46c | ||
|
|
75642372a6 | ||
|
|
7c41977b10 | ||
|
|
6875784258 | ||
|
|
2996b4f2f8 | ||
|
|
eab839e288 | ||
|
|
5ad35122f3 | ||
|
|
47f5078a7b | ||
|
|
ad3ad85b2c | ||
|
|
b55af898aa | ||
|
|
ae8cf6ee6d | ||
|
|
6c1dae9b50 | ||
|
|
5fb6d0a0bd | ||
|
|
b055b96eb2 | ||
|
|
758f231fff | ||
|
|
52eeaca3ad | ||
|
|
0ab0217597 | ||
|
|
11556f50d2 | ||
|
|
ee7a67a711 | ||
|
|
f67fa3a0e3 | ||
|
|
6250b1f442 | ||
|
|
2802b8d1f6 | ||
|
|
b735e4fe2b | ||
|
|
3f79367f64 | ||
|
|
8382ad4e78 | ||
|
|
4f4f487b50 | ||
|
|
996fb0ff93 | ||
|
|
2bd0f48f17 | ||
|
|
be4312aefa | ||
|
|
0ef8a75d53 | ||
|
|
4a1ccd2148 | ||
|
|
08e15ec90e | ||
|
|
348f792fe4 | ||
|
|
3fd19af552 | ||
|
|
2516a94415 | ||
|
|
db5735ae10 | ||
|
|
301ec72ea4 | ||
|
|
c8ba3f2ab6 | ||
|
|
377cf6aa97 | ||
|
|
66dc68d42a | ||
|
|
2c0ad92351 | ||
|
|
b0fefb46e4 | ||
|
|
5c3f886035 | ||
|
|
076c114235 | ||
|
|
723b023418 | ||
|
|
b573de271f | ||
|
|
0f0c501180 | ||
|
|
7f7953d882 | ||
|
|
89a8428f49 | ||
|
|
ee09a04094 | ||
|
|
f042904d94 | ||
|
|
c383a155a9 | ||
|
|
d0d7894082 | ||
|
|
e780123ea3 | ||
|
|
3a81fef8e2 | ||
|
|
5d17f62fe7 | ||
|
|
9388a02a0d | ||
|
|
f178c9ddac | ||
|
|
5a774d6b96 | ||
|
|
47382f98c9 | ||
|
|
80ce270063 | ||
|
|
1b96bb936c | ||
|
|
8c78a4eed4 | ||
|
|
87e04c2984 | ||
|
|
dc924d2084 | ||
|
|
bbf3618837 | ||
|
|
efb72eb889 | ||
|
|
5083ca5b7e | ||
|
|
ccf097f432 | ||
|
|
026dcd1dcf | ||
|
|
36fef04410 | ||
|
|
c3f666b33c | ||
|
|
faf27a433b | ||
|
|
08451f9027 | ||
|
|
d41b6f6748 | ||
|
|
1a3eda5744 | ||
|
|
8e024fa8f0 | ||
|
|
c52025ea91 | ||
|
|
9ab568f58d | ||
|
|
25b15817f7 | ||
|
|
57a8f8ffc6 | ||
|
|
bed46b51e0 | ||
|
|
e5731ff736 | ||
|
|
ebc1f7436a | ||
|
|
b3dd090806 | ||
|
|
00a856b938 | ||
|
|
0aee839144 | ||
|
|
a0a58671d0 | ||
|
|
b621a96d91 | ||
|
|
a42da99b5a | ||
|
|
fae7d2944e | ||
|
|
1039d688ae | ||
|
|
48f0a728ec | ||
|
|
8fd0c627d2 | ||
|
|
4db1f54f79 | ||
|
|
338852fb20 | ||
|
|
8ef931c119 | ||
|
|
b62d476704 | ||
|
|
3352821fe0 | ||
|
|
fac683ae77 | ||
|
|
ca984e0334 | ||
|
|
f9f143eadd | ||
|
|
8b0109a555 | ||
|
|
3c88fc0d90 | ||
|
|
c553b89023 | ||
|
|
2c810b0c31 | ||
|
|
0e9a5c4958 | ||
|
|
d0e25f4a05 | ||
|
|
25b7bf1a12 | ||
|
|
0e237e981a | ||
|
|
139fc10e3b | ||
|
|
5a0a55c231 | ||
|
|
55816e4184 | ||
|
|
82a9263afd | ||
|
|
c7c8ab9bed | ||
|
|
9af559ad0a | ||
|
|
2c58808b6f | ||
|
|
00efc527ff | ||
|
|
5e2e8cbcfe | ||
|
|
36896282b6 | ||
|
|
52924b32c6 | ||
|
|
d24259325f | ||
|
|
c59aca54d4 | ||
|
|
57252d3f7d | ||
|
|
b0088c7a3d | ||
|
|
e1bc1dbfa4 | ||
|
|
a28104d0d4 | ||
|
|
5f662f4e8f | ||
|
|
2f28b74565 | ||
|
|
8c3f416e7e | ||
|
|
1830a32784 | ||
|
|
442e9b2234 | ||
|
|
203780b77f | ||
|
|
174abbc2ea | ||
|
|
74e401982e | ||
|
|
4ea215fa42 | ||
|
|
b5925d2eda | ||
|
|
598be1c1e9 | ||
|
|
a8d3fccb73 | ||
|
|
8d9a0d7fd5 | ||
|
|
2a88383a43 | ||
|
|
4dde4f42d9 | ||
|
|
66b884a0c3 | ||
|
|
3db80acc76 | ||
|
|
065441374b | ||
|
|
fa7049446f | ||
|
|
549733fe01 | ||
|
|
561c4e00dd | ||
|
|
99cfd398be | ||
|
|
b2f799d4e3 | ||
|
|
0b6ab279be | ||
|
|
221379e1d0 | ||
|
|
0a3b777cb2 | ||
|
|
48188d5670 | ||
|
|
e338cd4f07 | ||
|
|
01b82f5581 | ||
|
|
cdec11bd06 | ||
|
|
7ac8a438cc | ||
|
|
d137a45808 | ||
|
|
5141b68613 | ||
|
|
cba37f6bba | ||
|
|
6a33d730fe | ||
|
|
8ab82a929a | ||
|
|
692eec7521 | ||
|
|
64346769b5 | ||
|
|
dc019f45e3 | ||
|
|
1b6168d675 | ||
|
|
4933ed2e42 | ||
|
|
a0cb0dc40c | ||
|
|
a34435a611 | ||
|
|
b8ecb4da9e | ||
|
|
b4deb35e6d | ||
|
|
9e71f526a3 | ||
|
|
85396d1183 | ||
|
|
e4b4799952 | ||
|
|
90a8e39b5a | ||
|
|
ab0dc7362f | ||
|
|
50d401de12 | ||
|
|
315bf0adb5 | ||
|
|
fff5b7216c | ||
|
|
0f1b29664f | ||
|
|
9bdfc81c1d | ||
|
|
c2731130a5 | ||
|
|
09ef6f1b44 | ||
|
|
1d5aa63016 | ||
|
|
6726babcc9 | ||
|
|
3da108641d | ||
|
|
b4cf41d822 | ||
|
|
d9ddfd9200 | ||
|
|
18edb794e7 | ||
|
|
55c23b348b | ||
|
|
3b85ba970a | ||
|
|
5a78a0e102 | ||
|
|
170ca8965c | ||
|
|
8ed10f0200 | ||
|
|
6791973ab0 | ||
|
|
f1c0e8b288 | ||
|
|
6416713fa5 | ||
|
|
996b513ca8 | ||
|
|
2431059cb7 | ||
|
|
34ce93323c | ||
|
|
d5365cd6f1 | ||
|
|
07e7d53b83 | ||
|
|
96e56379e8 | ||
|
|
241cd05c79 | ||
|
|
52bf4523cf | ||
|
|
29acda2955 | ||
|
|
0615585206 | ||
|
|
4a327f0a87 | ||
|
|
aa175cb44e | ||
|
|
4b2b40f6f2 | ||
|
|
3cb5b24a38 | ||
|
|
360e027673 | ||
|
|
f644f996e5 | ||
|
|
6189743d0d | ||
|
|
9ddc597a3d | ||
|
|
833571b3c6 | ||
|
|
7776fe2d54 | ||
|
|
68bdc82b30 | ||
|
|
7db0124e7d | ||
|
|
10951415b5 | ||
|
|
3f12948197 | ||
|
|
33104aa60c | ||
|
|
9658d499fd | ||
|
|
f93fef3797 | ||
|
|
94d9b21e8d | ||
|
|
8c6604fc1a | ||
|
|
26139a0c99 | ||
|
|
b6d15f7ee8 | ||
|
|
a125e0542a | ||
|
|
d74142409a | ||
|
|
57fcf65693 | ||
|
|
2af5b8ef57 | ||
|
|
5d563edf7e | ||
|
|
9f8b8ae388 | ||
|
|
8e5f0aee4e | ||
|
|
1764aff0b1 | ||
|
|
4e4e276425 | ||
|
|
60c0db5143 | ||
|
|
f45c9da161 | ||
|
|
6bd5d3f16d | ||
|
|
d18ddd0c4c | ||
|
|
fb3d63a2f9 | ||
|
|
62be7125a3 | ||
|
|
ffab24e841 | ||
|
|
c3839f3847 | ||
|
|
db7ba0453e | ||
|
|
cd8157d67b | ||
|
|
9ff5f77871 | ||
|
|
ddcc4ce79d | ||
|
|
4f55fb6671 | ||
|
|
9a6ec276d0 | ||
|
|
2976fa1a8a | ||
|
|
fe17fbea9b | ||
|
|
905a6365ef | ||
|
|
a534dc1ca7 | ||
|
|
9b11f8564d | ||
|
|
56211264dc | ||
|
|
6ff5280451 | ||
|
|
be10af10cd | ||
|
|
82f9a59a36 | ||
|
|
74c7b8de31 | ||
|
|
44915c991b | ||
|
|
14c7ff9828 | ||
|
|
5ba7111437 | ||
|
|
536be0e408 | ||
|
|
27dacf0681 | ||
|
|
57ed4b640d | ||
|
|
3cc0fa603c | ||
|
|
a008e57d09 | ||
|
|
60e65fa836 | ||
|
|
f2c25e8fbc | ||
|
|
b6039eca5f | ||
|
|
d82f107a0a | ||
|
|
f68bc74338 | ||
|
|
a3cf1703df | ||
|
|
085a38f62a | ||
|
|
774f31ad1f | ||
|
|
02a75e5745 | ||
|
|
4e7dffa928 | ||
|
|
dca34d2826 | ||
|
|
9286a45824 | ||
|
|
296a84a356 | ||
|
|
8c153fd636 | ||
|
|
cfb091ced5 | ||
|
|
913cb6ae97 | ||
|
|
56a212652f | ||
|
|
7089a3c79f | ||
|
|
a6a167fe1d | ||
|
|
fd140f0f1b | ||
|
|
142efa8dd0 | ||
|
|
dd12429cca | ||
|
|
9fe137ccba | ||
|
|
8d6793a838 | ||
|
|
f0f96aacf8 | ||
|
|
3672e99d0b | ||
|
|
6f28191422 | ||
|
|
b8c7706fa9 | ||
|
|
b80820c297 | ||
|
|
be8123fcba | ||
|
|
2abff017ef | ||
|
|
7c9b64c879 | ||
|
|
5c0a2d910c | ||
|
|
44e35fc660 | ||
|
|
c06b81c34c | ||
|
|
e4a43a62ca | ||
|
|
3e01b3f572 | ||
|
|
08e791c0ab | ||
|
|
0c2d25bba5 | ||
|
|
c4bf59ddf0 | ||
|
|
88ef6b4176 | ||
|
|
58a1d9b765 | ||
|
|
2f1c8ee8a8 | ||
|
|
ddb951ac5c | ||
|
|
37d334a950 | ||
|
|
cd52fe528c | ||
|
|
27d2caceab | ||
|
|
2f501d19f2 | ||
|
|
dd143d7535 | ||
|
|
ad282e98be | ||
|
|
e70243131f | ||
|
|
79a9957748 | ||
|
|
664342e8b9 | ||
|
|
93d66a384e | ||
|
|
2b31837503 | ||
|
|
399325c6d4 | ||
|
|
bb6848ffbf | ||
|
|
e6320a0ce0 | ||
|
|
12d1e297cf | ||
|
|
f33ab1ce3c | ||
|
|
f9b0e90b64 | ||
|
|
ddf982c56b | ||
|
|
562f22861f | ||
|
|
3b585d3189 | ||
|
|
045467e799 | ||
|
|
0aed962d2b | ||
|
|
2f7e9b8244 | ||
|
|
261c1b725f | ||
|
|
e41bbebd46 | ||
|
|
77d5a58afd | ||
|
|
93eec98d20 | ||
|
|
091077aa33 | ||
|
|
77057fe598 | ||
|
|
7f15155c83 | ||
|
|
c01d870021 | ||
|
|
cc15e45ad2 | ||
|
|
aa4d8a25af | ||
|
|
c43d68577a | ||
|
|
dd6777bad0 | ||
|
|
06518c4646 | ||
|
|
13df9e5f19 | ||
|
|
b9c9fafc5e | ||
|
|
7cd03fe59d | ||
|
|
68c2ea79c0 | ||
|
|
3cd7a38194 | ||
|
|
593cf1bf61 | ||
|
|
db32086b0e | ||
|
|
14ae3aa186 | ||
|
|
5d275c248d | ||
|
|
caebf3a5f8 | ||
|
|
b488eb78b9 | ||
|
|
0e075a7b80 | ||
|
|
33502fbad6 | ||
|
|
22c73ef474 | ||
|
|
c7cb6b6d2d | ||
|
|
dc508a534f | ||
|
|
cbb4a26833 | ||
|
|
ddee83a9fa | ||
|
|
a5a074461d | ||
|
|
9b06ae0c8f | ||
|
|
cfe81e44f7 | ||
|
|
be6d08ae18 | ||
|
|
bb6c60694d | ||
|
|
cd36cbdf58 | ||
|
|
d7c82da11f | ||
|
|
fbf3a2645f | ||
|
|
34ad27f047 | ||
|
|
012202f1f7 | ||
|
|
8c6de822d9 | ||
|
|
9521da857d | ||
|
|
d0557591c3 | ||
|
|
e9875f87c5 | ||
|
|
0dd33f2e12 | ||
|
|
85dfb1be6c | ||
|
|
75a4b9b2b6 | ||
|
|
4d691df9e3 | ||
|
|
c88c32646a | ||
|
|
4c3082ab0c | ||
|
|
fd434f45f9 | ||
|
|
c4a437a7ed | ||
|
|
796636692c | ||
|
|
1b73ce72f6 | ||
|
|
cd3f1c78cd | ||
|
|
8dedf9d091 | ||
|
|
394355d3c1 | ||
|
|
e44dc343f0 | ||
|
|
7723c4a70e | ||
|
|
0537dbc26b | ||
|
|
62133fdcc9 | ||
|
|
af8e101f1b | ||
|
|
eba02f27b8 | ||
|
|
9af74f6c75 | ||
|
|
05e5756172 | ||
|
|
de3348c6bb | ||
|
|
f5341151bb | ||
|
|
c76323298e | ||
|
|
b3eaf07d5d | ||
|
|
92bed36fbd | ||
|
|
6cad802029 | ||
|
|
90348e63ec | ||
|
|
7e586f42e5 | ||
|
|
a640fc495b | ||
|
|
13134b936d | ||
|
|
63a1fe6509 | ||
|
|
dbf0fe69c6 | ||
|
|
8a0fe4a93e | ||
|
|
f88f417a26 | ||
|
|
c273315286 | ||
|
|
469d382646 | ||
|
|
f7d4d11f4e | ||
|
|
91258d0bfc | ||
|
|
addb0b2f44 | ||
|
|
6bb45e8916 | ||
|
|
960871aa12 | ||
|
|
1090d221af | ||
|
|
6148db1fc6 | ||
|
|
4cfbb9765a | ||
|
|
77bcb54189 | ||
|
|
4a0f0a764b | ||
|
|
a1f6940f03 | ||
|
|
0f4e775451 | ||
|
|
b6f07cfd0a | ||
|
|
ede4d98055 | ||
|
|
0a0088d3c7 | ||
|
|
a60f667fd2 | ||
|
|
9b620ff2e6 | ||
|
|
1cbea49773 | ||
|
|
047f87a3eb | ||
|
|
bd823a6e11 | ||
|
|
add3524194 | ||
|
|
7c304e9aa0 | ||
|
|
a84c344b5c | ||
|
|
cc9525fa15 | ||
|
|
a367379062 | ||
|
|
3e111b037e | ||
|
|
a88bb70a49 | ||
|
|
c29a83c1e5 | ||
|
|
1e721e7733 | ||
|
|
65e5883cdb | ||
|
|
66068509ff | ||
|
|
722a5752e2 | ||
|
|
5824810b7d | ||
|
|
1028107c1e | ||
|
|
447a35fe7d | ||
|
|
a9b04231b5 | ||
|
|
21ed2a65fd | ||
|
|
56bdcb43e9 | ||
|
|
d65cf7e026 | ||
|
|
2b45603119 | ||
|
|
fade18bee2 | ||
|
|
0fc5625884 | ||
|
|
2e75794b0d | ||
|
|
221cc5f371 | ||
|
|
353e55b7f6 | ||
|
|
2cdbcfb265 | ||
|
|
65aeb0b85f | ||
|
|
5614b7a1e9 | ||
|
|
bc603a7cef | ||
|
|
b79a2853b6 | ||
|
|
d46753fa28 | ||
|
|
6c08acb9bd | ||
|
|
7f4ae06c9c | ||
|
|
ec88440c2d | ||
|
|
79a9b98ea5 | ||
|
|
045e73bfdc | ||
|
|
7a2bbb38ea | ||
|
|
c16e04df1f | ||
|
|
7a38066382 | ||
|
|
de69ac5bb1 | ||
|
|
26d7ecfe23 | ||
|
|
4cc391ff22 | ||
|
|
733ca6de59 | ||
|
|
7989ded99f | ||
|
|
420042a5cf | ||
|
|
5199693c7c | ||
|
|
3c4b404cd9 | ||
|
|
bb377c86aa | ||
|
|
1e9a7adaef | ||
|
|
1be69d18f3 | ||
|
|
c533144fe7 | ||
|
|
238dfa9172 | ||
|
|
91b5031be3 | ||
|
|
08d4fc7175 | ||
|
|
a13d238a19 | ||
|
|
9a082e063b | ||
|
|
a904c07dc4 | ||
|
|
b8fb6e472a | ||
|
|
c89720f69a | ||
|
|
589a2f1182 | ||
|
|
153313037a | ||
|
|
47e6d70a0b | ||
|
|
88da426e7c | ||
|
|
b46897740f | ||
|
|
80c6e96a41 | ||
|
|
453b90c2aa | ||
|
|
315a12dd58 | ||
|
|
e306530a8e |
1443
mozilla/modules/libreg/xpcom/nsRegistry.cpp
Normal file
1443
mozilla/modules/libreg/xpcom/nsRegistry.cpp
Normal file
File diff suppressed because it is too large
Load Diff
592
mozilla/string/obsolete/nsStr.cpp
Normal file
592
mozilla/string/obsolete/nsStr.cpp
Normal file
@@ -0,0 +1,592 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/******************************************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
This file contains the nsStr data structure.
|
||||
This general purpose buffer management class is used as the basis for our strings.
|
||||
It's benefits include:
|
||||
1. An efficient set of library style functions for manipulating nsStrs
|
||||
2. Support for 1 and 2 byte character strings (which can easily be increased to n)
|
||||
3. Unicode awareness and interoperability.
|
||||
|
||||
*******************************************************************************************/
|
||||
|
||||
#include "nsStr.h"
|
||||
#include "bufferRoutines.h"
|
||||
#include "stdio.h" //only used for printf
|
||||
#include "nsDeque.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
|
||||
static const char* kFoolMsg = "Error: Some fool overwrote the shared buffer.";
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
// The following is a memory agent who knows how to recycled (pool) freed memory...
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
/**************************************************************
|
||||
Define the char* (pooled) deallocator class...
|
||||
**************************************************************/
|
||||
class nsBufferDeallocator: public nsDequeFunctor{
|
||||
public:
|
||||
virtual void* operator()(void* anObject) {
|
||||
char* aCString= (char*)anObject;
|
||||
delete [] aCString;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess10/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
class nsPoolingMemoryAgent : public nsMemoryAgent{
|
||||
public:
|
||||
nsPoolingMemoryAgent() {
|
||||
memset(mPools,0,sizeof(mPools));
|
||||
}
|
||||
|
||||
virtual ~nsPoolingMemoryAgent() {
|
||||
nsBufferDeallocator theDeallocator;
|
||||
int i=0;
|
||||
for(i=0;i<10;i++){
|
||||
if(mPools[i]){
|
||||
mPools[i]->ForEach(theDeallocator); //now delete the buffers
|
||||
}
|
||||
delete mPools[i];
|
||||
mPools[i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
virtual PRBool Alloc(nsStr& aDest,PRUint32 aCount) {
|
||||
|
||||
//we're given the acount value in charunits; we have to scale up by the charsize.
|
||||
int theShift=4;
|
||||
PRUint32 theNewCapacity=eDefaultSize;
|
||||
while(theNewCapacity<aCount){
|
||||
theNewCapacity<<=1;
|
||||
theShift++;
|
||||
}
|
||||
|
||||
aDest.mCapacity=theNewCapacity++;
|
||||
theShift=(theShift<<aDest.mCharSize)-4;
|
||||
if((theShift<12) && (mPools[theShift])){
|
||||
aDest.mStr=(char*)mPools[theShift]->Pop();
|
||||
}
|
||||
if(!aDest.mStr) {
|
||||
//we're given the acount value in charunits; we have to scale up by the charsize.
|
||||
size_t theSize=(theNewCapacity<<aDest.mCharSize);
|
||||
aDest.mStr=new char[theSize];
|
||||
}
|
||||
aDest.mOwnsBuffer=1;
|
||||
return PRBool(aDest.mStr!=0);
|
||||
|
||||
}
|
||||
|
||||
virtual PRBool Free(nsStr& aDest){
|
||||
if(aDest.mStr){
|
||||
if(aDest.mOwnsBuffer){
|
||||
int theShift=1;
|
||||
unsigned int theValue=1;
|
||||
while((theValue<<=1)<aDest.mCapacity){
|
||||
theShift++;
|
||||
}
|
||||
theShift-=4;
|
||||
if(theShift<12){
|
||||
if(!mPools[theShift]){
|
||||
mPools[theShift]=new nsDeque(0);
|
||||
}
|
||||
mPools[theShift]->Push(aDest.mStr);
|
||||
}
|
||||
else delete [] aDest.mStr; //it's too big. Just delete it.
|
||||
}
|
||||
aDest.mStr=0;
|
||||
aDest.mOwnsBuffer=0;
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
nsDeque* mPools[16];
|
||||
};
|
||||
|
||||
static char* gCommonEmptyBuffer=0;
|
||||
/**
|
||||
*
|
||||
* @update gess10/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
char* GetSharedEmptyBuffer() {
|
||||
if(!gCommonEmptyBuffer) {
|
||||
const size_t theDfltSize=5;
|
||||
gCommonEmptyBuffer=new char[theDfltSize];
|
||||
if(gCommonEmptyBuffer){
|
||||
nsCRT::zero(gCommonEmptyBuffer,theDfltSize);
|
||||
gCommonEmptyBuffer[0]=0;
|
||||
}
|
||||
else {
|
||||
printf("%s\n","Memory allocation error!");
|
||||
}
|
||||
}
|
||||
return gCommonEmptyBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess10/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::Initialize(nsStr& aDest,eCharSize aCharSize) {
|
||||
aDest.mStr=GetSharedEmptyBuffer();
|
||||
aDest.mLength=0;
|
||||
aDest.mCapacity=0;
|
||||
aDest.mCharSize=aCharSize;
|
||||
aDest.mOwnsBuffer=0;
|
||||
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess10/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer){
|
||||
aDest.mStr=(aCString) ? aCString : GetSharedEmptyBuffer();
|
||||
aDest.mLength=aLength;
|
||||
aDest.mCapacity=aCapacity;
|
||||
aDest.mCharSize=aCharSize;
|
||||
aDest.mOwnsBuffer=aOwnsBuffer;
|
||||
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess10/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsIMemoryAgent* GetDefaultAgent(void){
|
||||
// static nsPoolingMemoryAgent gDefaultAgent;
|
||||
static nsMemoryAgent gDefaultAgent;
|
||||
return (nsIMemoryAgent*)&gDefaultAgent;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess10/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::Destroy(nsStr& aDest,nsIMemoryAgent* anAgent) {
|
||||
if((aDest.mStr) && (aDest.mStr!=GetSharedEmptyBuffer())) {
|
||||
if(!anAgent)
|
||||
anAgent=GetDefaultAgent();
|
||||
|
||||
if(anAgent) {
|
||||
anAgent->Free(aDest);
|
||||
}
|
||||
else{
|
||||
printf("%s\n","Leak occured in nsStr.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method gets called when the internal buffer needs
|
||||
* to grow to a given size. The original contents are not preserved.
|
||||
* @update gess 3/30/98
|
||||
* @param aNewLength -- new capacity of string in charSize units
|
||||
* @return void
|
||||
*/
|
||||
void nsStr::EnsureCapacity(nsStr& aString,PRUint32 aNewLength,nsIMemoryAgent* anAgent) {
|
||||
if(aNewLength>aString.mCapacity) {
|
||||
nsIMemoryAgent* theAgent=(anAgent) ? anAgent : GetDefaultAgent();
|
||||
theAgent->Realloc(aString,aNewLength);
|
||||
AddNullTerminator(aString);
|
||||
}
|
||||
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when the internal buffer needs
|
||||
* to grow to a given size. The original contents ARE preserved.
|
||||
* @update gess 3/30/98
|
||||
* @param aNewLength -- new capacity of string in charSize units
|
||||
* @return void
|
||||
*/
|
||||
void nsStr::GrowCapacity(nsStr& aDest,PRUint32 aNewLength,nsIMemoryAgent* anAgent) {
|
||||
if(aNewLength>aDest.mCapacity) {
|
||||
nsStr theTempStr;
|
||||
nsStr::Initialize(theTempStr,aDest.mCharSize);
|
||||
|
||||
nsIMemoryAgent* theAgent=(anAgent) ? anAgent : GetDefaultAgent();
|
||||
EnsureCapacity(theTempStr,aNewLength,theAgent);
|
||||
|
||||
if(aDest.mLength) {
|
||||
Append(theTempStr,aDest,0,aDest.mLength,theAgent);
|
||||
}
|
||||
theAgent->Free(aDest);
|
||||
aDest.mStr = theTempStr.mStr;
|
||||
theTempStr.mStr=0; //make sure to null this out so that you don't lose the buffer you just stole...
|
||||
aDest.mLength=theTempStr.mLength;
|
||||
aDest.mCapacity=theTempStr.mCapacity;
|
||||
aDest.mOwnsBuffer=theTempStr.mOwnsBuffer;
|
||||
}
|
||||
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the contents of aDest with aSource, up to aCount of chars.
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr that gets changed.
|
||||
* @param aSource is where chars are copied from
|
||||
* @param aCount is the number of chars copied from aSource
|
||||
*/
|
||||
void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent){
|
||||
if(&aDest!=&aSource){
|
||||
Truncate(aDest,0,anAgent);
|
||||
Append(aDest,aSource,anOffset,aCount,anAgent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method appends the given nsStr to this one. Note that we have to
|
||||
* pay attention to the underlying char-size of both structs.
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr to be manipulated
|
||||
* @param aSource is where char are copied from
|
||||
* @aCount is the number of bytes to be copied
|
||||
*/
|
||||
void nsStr::Append(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent){
|
||||
if(anOffset<aSource.mLength){
|
||||
PRUint32 theRealLen=(aCount<0) ? aSource.mLength : MinInt(aCount,aSource.mLength);
|
||||
PRUint32 theLength=(anOffset+theRealLen<aSource.mLength) ? theRealLen : (aSource.mLength-anOffset);
|
||||
if(0<theLength){
|
||||
if(aDest.mLength+theLength > aDest.mCapacity) {
|
||||
GrowCapacity(aDest,aDest.mLength+theLength,anAgent);
|
||||
}
|
||||
|
||||
//now append new chars, starting at offset
|
||||
(*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDest.mLength,aSource.mStr,anOffset,theLength);
|
||||
|
||||
aDest.mLength+=theLength;
|
||||
}
|
||||
}
|
||||
AddNullTerminator(aDest);
|
||||
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method inserts up to "aCount" chars from a source nsStr into a dest nsStr.
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr that gets changed
|
||||
* @param aDestOffset is where in aDest the insertion is to occur
|
||||
* @param aSource is where chars are copied from
|
||||
* @param aSrcOffset is where in aSource chars are copied from
|
||||
* @param aCount is the number of chars from aSource to be inserted into aDest
|
||||
*/
|
||||
void nsStr::Insert( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUint32 aSrcOffset,PRInt32 aCount,nsIMemoryAgent* anAgent){
|
||||
//there are a few cases for insert:
|
||||
// 1. You're inserting chars into an empty string (assign)
|
||||
// 2. You're inserting onto the end of a string (append)
|
||||
// 3. You're inserting onto the 1..n-1 pos of a string (the hard case).
|
||||
if(0<aSource.mLength){
|
||||
if(aDest.mLength){
|
||||
if(aDestOffset<aDest.mLength){
|
||||
PRInt32 theRealLen=(aCount<0) ? aSource.mLength : MinInt(aCount,aSource.mLength);
|
||||
PRInt32 theLength=(aSrcOffset+theRealLen<aSource.mLength) ? theRealLen : (aSource.mLength-aSrcOffset);
|
||||
|
||||
if(aSrcOffset<aSource.mLength) {
|
||||
//here's the only new case we have to handle.
|
||||
//chars are really being inserted into our buffer...
|
||||
GrowCapacity(aDest,aDest.mLength+theLength,anAgent);
|
||||
|
||||
//shift the chars right by theDelta...
|
||||
(*gShiftChars[aDest.mCharSize][KSHIFTRIGHT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
|
||||
//now insert new chars, starting at offset
|
||||
(*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDestOffset,aSource.mStr,aSrcOffset,theLength);
|
||||
|
||||
//finally, make sure to update the string length...
|
||||
aDest.mLength+=theLength;
|
||||
AddNullTerminator(aDest);
|
||||
|
||||
}//if
|
||||
//else nothing to do!
|
||||
}
|
||||
else Append(aDest,aSource,0,aCount,anAgent);
|
||||
}
|
||||
else Append(aDest,aSource,0,aCount,anAgent);
|
||||
}
|
||||
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method deletes up to aCount chars from aDest
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr to be manipulated
|
||||
* @param aDestOffset is where in aDest deletion is to occur
|
||||
* @param aCount is the number of chars to be deleted in aDest
|
||||
*/
|
||||
void nsStr::Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAgent* anAgent){
|
||||
if(aDestOffset<aDest.mLength){
|
||||
|
||||
PRUint32 theDelta=aDest.mLength-aDestOffset;
|
||||
PRUint32 theLength=(theDelta<aCount) ? theDelta : aCount;
|
||||
|
||||
if(aDestOffset+theLength<aDest.mLength) {
|
||||
|
||||
//if you're here, it means we're cutting chars out of the middle of the string...
|
||||
//so shift the chars left by theLength...
|
||||
(*gShiftChars[aDest.mCharSize][KSHIFTLEFT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
aDest.mLength-=theLength;
|
||||
}
|
||||
else Truncate(aDest,aDestOffset,anAgent);
|
||||
}//if
|
||||
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method truncates the given nsStr at given offset
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr to be truncated
|
||||
* @param aDestOffset is where in aDest truncation is to occur
|
||||
*/
|
||||
void nsStr::Truncate(nsStr& aDest,PRUint32 aDestOffset,nsIMemoryAgent* anAgent){
|
||||
if(aDestOffset<aDest.mLength){
|
||||
aDest.mLength=aDestOffset;
|
||||
AddNullTerminator(aDest);
|
||||
}
|
||||
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess1/7/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::ChangeCase(nsStr& aDest,PRBool aToUpper) {
|
||||
// somehow UnicharUtil return failed, fallback to the old ascii only code
|
||||
gCaseConverters[aDest.mCharSize](aDest.mStr,aDest.mLength,aToUpper);
|
||||
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess1/7/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::StripChars(nsStr& aDest,PRUint32 aDestOffset,PRInt32 aCount,const char* aCharSet){
|
||||
PRUint32 aNewLen=gStripChars[aDest.mCharSize](aDest.mStr,aDestOffset,aCount,aCharSet);
|
||||
aDest.mLength=aNewLen;
|
||||
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess1/7/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing){
|
||||
PRUint32 aNewLen=gTrimChars[aDest.mCharSize](aDest.mStr,aDest.mLength,aSet,aEliminateLeading,aEliminateTrailing);
|
||||
aDest.mLength=aNewLen;
|
||||
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess1/7/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::CompressSet(nsStr& aDest,const char* aSet,PRUint32 aChar,PRBool aEliminateLeading,PRBool aEliminateTrailing){
|
||||
PRUint32 aNewLen=gCompressChars[aDest.mCharSize](aDest.mStr,aDest.mLength,aSet,aChar,aEliminateLeading,aEliminateTrailing);
|
||||
aDest.mLength=aNewLen;
|
||||
NS_ASSERTION(gCommonEmptyBuffer[0]==0,kFoolMsg);
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
Searching methods...
|
||||
**************************************************************/
|
||||
|
||||
|
||||
PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRUint32 anOffset) {
|
||||
if((aDest.mLength>0) && (aTarget.mLength>0) && (anOffset<aTarget.mLength)){
|
||||
|
||||
int32 index=anOffset-1;
|
||||
int32 theMax=aDest.mLength-aTarget.mLength;
|
||||
if((aDest.mLength>0) && (aTarget.mLength>0)){
|
||||
int32 theTargetMax=aTarget.mLength;
|
||||
while(++index<=theMax) {
|
||||
int32 theSubIndex=-1;
|
||||
PRBool matches=PR_TRUE;
|
||||
while((++theSubIndex<theTargetMax) && (matches)){
|
||||
PRUnichar theChar=(aIgnoreCase) ? nsCRT::ToLower(GetCharAt(aDest,index+theSubIndex)) : GetCharAt(aDest,index+theSubIndex);
|
||||
PRUnichar theTargetChar=(aIgnoreCase) ? nsCRT::ToLower(GetCharAt(aTarget,theSubIndex)) : GetCharAt(aTarget,theSubIndex);
|
||||
matches=PRBool(theChar==theTargetChar);
|
||||
}
|
||||
if(matches) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}//if
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess1/7/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 nsStr::FindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) {
|
||||
PRInt32 result=gFindChars[aDest.mCharSize](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 nsStr::FindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset) {
|
||||
PRUint32 index=anOffset-1;
|
||||
PRInt32 thePos;
|
||||
|
||||
while(++index<aDest.mLength) {
|
||||
PRUnichar theChar=GetCharAt(aDest,index);
|
||||
thePos=gFindChars[aSet.mCharSize](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase);
|
||||
if(kNotFound!=thePos)
|
||||
return index;
|
||||
} //while
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
Reverse Searching methods...
|
||||
**************************************************************/
|
||||
|
||||
|
||||
PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRUint32 anOffset) {
|
||||
PRInt32 index=(anOffset ? anOffset : aDest.mLength-aTarget.mLength+1);
|
||||
PRInt32 result=kNotFound;
|
||||
|
||||
if((aDest.mLength>0) && (aTarget.mLength>0)){
|
||||
|
||||
nsStr theCopy;
|
||||
nsStr::Initialize(theCopy,eOneByte);
|
||||
nsStr::Assign(theCopy,aTarget,0,aTarget.mLength,0);
|
||||
if(aIgnoreCase){
|
||||
nsStr::ChangeCase(theCopy,PR_FALSE); //force to lowercase
|
||||
}
|
||||
|
||||
int32 theTargetMax=theCopy.mLength;
|
||||
while(index--) {
|
||||
int32 theSubIndex=-1;
|
||||
PRBool matches=PR_TRUE;
|
||||
if(anOffset+theCopy.mLength<=aDest.mLength) {
|
||||
while((++theSubIndex<theTargetMax) && (matches)){
|
||||
PRUnichar theDestChar=(aIgnoreCase) ? nsCRT::ToLower(GetCharAt(aDest,index+theSubIndex)) : GetCharAt(aDest,index+theSubIndex);
|
||||
PRUnichar theTargetChar=GetCharAt(theCopy,theSubIndex);
|
||||
matches=PRBool(theDestChar==theTargetChar);
|
||||
} //while
|
||||
} //if
|
||||
if(matches) {
|
||||
result=index;
|
||||
break;
|
||||
}
|
||||
} //while
|
||||
nsStr::Destroy(theCopy,0);
|
||||
}//if
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess1/7/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) {
|
||||
PRInt32 result=gRFindChars[aDest.mCharSize](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset) {
|
||||
PRUint32 offset=aDest.mLength-anOffset;
|
||||
PRInt32 thePos;
|
||||
|
||||
while(--offset>=0) {
|
||||
PRUnichar theChar=GetCharAt(aDest,offset);
|
||||
thePos=gRFindChars[aSet.mCharSize](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase);
|
||||
if(kNotFound!=thePos)
|
||||
return offset;
|
||||
} //while
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess11/12/98
|
||||
* @param
|
||||
* @return aDest<aSource=-1;aDest==aSource==0;aDest>aSource=1
|
||||
*/
|
||||
PRInt32 nsStr::Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase) {
|
||||
int minlen=(aSource.mLength<aDest.mLength) ? aSource.mLength : aDest.mLength;
|
||||
|
||||
if(0==minlen) {
|
||||
if ((aDest.mLength == 0) && (aSource.mLength == 0))
|
||||
return 0;
|
||||
if (aDest.mLength == 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int maxlen=(aSource.mLength<aDest.mLength) ? aDest.mLength : aSource.mLength;
|
||||
PRInt32 result=(*gCompare[aDest.mCharSize][aSource.mCharSize])(aDest.mStr,aSource.mStr,maxlen,aIgnoreCase);
|
||||
return result;
|
||||
}
|
||||
|
||||
333
mozilla/string/obsolete/nsStr.h
Normal file
333
mozilla/string/obsolete/nsStr.h
Normal file
@@ -0,0 +1,333 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
1. There are two philosophies to building string classes:
|
||||
A. Hide the underlying buffer & offer API's allow indirect iteration
|
||||
B. Reveal underlying buffer, risk corruption, but gain performance
|
||||
|
||||
We chose the option B for performance reasons.
|
||||
|
||||
2 Our internal buffer always holds capacity+1 bytes.
|
||||
|
||||
The nsStr struct is a simple structure (no methods) that contains
|
||||
the necessary info to be described as a string. This simple struct
|
||||
is manipulated by the static methods provided in this class.
|
||||
(Which effectively makes this a library that works on structs).
|
||||
|
||||
There are also object-based versions called nsString and nsAutoString
|
||||
which use nsStr but makes it look at feel like an object.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
#ifndef _nsStr
|
||||
#define _nsStr
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
enum eCharSize {eOneByte=0,eTwoByte=1};
|
||||
#define kDefaultCharSize eTwoByte
|
||||
const PRInt32 kNotFound = -1;
|
||||
|
||||
|
||||
class nsIMemoryAgent;
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
struct nsStr {
|
||||
|
||||
/**
|
||||
* This method initializes an nsStr for use
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the nsStr to be initialized
|
||||
* @param aCharSize tells us the requested char size (1 or 2 bytes)
|
||||
*/
|
||||
static void Initialize(nsStr& aDest,eCharSize aCharSize);
|
||||
|
||||
/**
|
||||
* This method initializes an nsStr for use
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the nsStr to be initialized
|
||||
* @param aCharSize tells us the requested char size (1 or 2 bytes)
|
||||
*/
|
||||
static void Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer);
|
||||
|
||||
/**
|
||||
* This method destroys the given nsStr, and *MAY*
|
||||
* deallocate it's memory depending on the setting
|
||||
* of the internal mOwnsBUffer flag.
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the nsStr to be manipulated
|
||||
* @param anAgent is the allocator to be used to the nsStr
|
||||
*/
|
||||
static void Destroy(nsStr& aDest,nsIMemoryAgent* anAgent=0);
|
||||
|
||||
/**
|
||||
* These methods are where memory allocation/reallocation occur.
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the nsStr to be manipulated
|
||||
* @param anAgent is the allocator to be used on the nsStr
|
||||
* @return
|
||||
*/
|
||||
static void EnsureCapacity(nsStr& aString,PRUint32 aNewLength,nsIMemoryAgent* anAgent=0);
|
||||
static void GrowCapacity(nsStr& aString,PRUint32 aNewLength,nsIMemoryAgent* anAgent=0);
|
||||
|
||||
/**
|
||||
* These methods are used to append content to the given nsStr
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param aSource is the buffer to be copied from
|
||||
* @param anOffset tells us where in source to start copying
|
||||
* @param aCount tells us the (max) # of chars to copy
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void Append(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent=0);
|
||||
|
||||
/**
|
||||
* These methods are used to assign contents of a source string to dest string
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param aSource is the buffer to be copied from
|
||||
* @param anOffset tells us where in source to start copying
|
||||
* @param aCount tells us the (max) # of chars to copy
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent=0);
|
||||
|
||||
/**
|
||||
* These methods are used to insert content from source string to the dest nsStr
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param aDestOffset tells us where in dest to start insertion
|
||||
* @param aSource is the buffer to be copied from
|
||||
* @param aSrcOffset tells us where in source to start copying
|
||||
* @param aCount tells us the (max) # of chars to insert
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void Insert( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUint32 aSrcOffset,PRInt32 aCount,nsIMemoryAgent* anAgent=0);
|
||||
|
||||
/**
|
||||
* This method deletes chars from the given str.
|
||||
* The given allocator may choose to resize the str as well.
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be deleted from
|
||||
* @param aDestOffset tells us where in dest to start deleting
|
||||
* @param aCount tells us the (max) # of chars to delete
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAgent* anAgent=0);
|
||||
|
||||
/**
|
||||
* This method is used to truncate the given string.
|
||||
* The given allocator may choose to resize the str as well (but it's not likely).
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param aDestOffset tells us where in dest to start insertion
|
||||
* @param aSource is the buffer to be copied from
|
||||
* @param aSrcOffset tells us where in source to start copying
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void Truncate(nsStr& aDest,PRUint32 aDestOffset,nsIMemoryAgent* anAgent=0);
|
||||
|
||||
/**
|
||||
* This method is used to perform a case conversion on the given string
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be case shifted
|
||||
* @param toUpper tells us to go upper vs. lower
|
||||
*/
|
||||
static void ChangeCase(nsStr& aDest,PRBool aToUpper);
|
||||
|
||||
/**
|
||||
* This method removes chars (given in aSet) from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param aDestOffset is starting pos in buffer for manipulation
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aSet tells us which chars to remove from given buffer
|
||||
*/
|
||||
static void StripChars(nsStr& aDest,PRUint32 aDestOffset,PRInt32 aCount,const char* aCharSet);
|
||||
|
||||
/**
|
||||
* This method trims chars (given in aSet) from the edges of given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the buffer to be manipulated
|
||||
* @param aSet tells us which chars to remove from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
*/
|
||||
static void Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing);
|
||||
|
||||
/**
|
||||
* This method compresses duplicate runs of a given char from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the buffer to be manipulated
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aChar is the replacement char
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
*/
|
||||
static void CompressSet(nsStr& aDest,const char* aSet,PRUint32 aChar,PRBool aEliminateLeading,PRBool aEliminateTrailing);
|
||||
|
||||
/**
|
||||
* This method compares the data bewteen two nsStr's
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
static PRInt32 Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase);
|
||||
|
||||
/**
|
||||
* These methods scan the given string for 1 or more chars in a given direction
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be searched to
|
||||
* @param aSource (or aChar) is the substr we're looking to find
|
||||
* @param aIgnoreCase tells us whether to search in a case-sensitive manner
|
||||
* @param anOffset tells us where in the dest string to start searching
|
||||
* @return the index of the source (substr) in dest, or -1 (kNotFound) if not found.
|
||||
*/
|
||||
static PRInt32 FindSubstr(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRUint32 anOffset);
|
||||
static PRInt32 FindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset);
|
||||
static PRInt32 FindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset);
|
||||
|
||||
static PRInt32 RFindSubstr(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRUint32 anOffset);
|
||||
static PRInt32 RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset);
|
||||
static PRInt32 RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset);
|
||||
|
||||
|
||||
PRUint32 mLength;
|
||||
PRUint32 mCapacity;
|
||||
eCharSize mCharSize;
|
||||
PRBool mOwnsBuffer;
|
||||
|
||||
union {
|
||||
char* mStr;
|
||||
PRUnichar* mUStr;
|
||||
};
|
||||
};
|
||||
|
||||
/**************************************************************
|
||||
A couple of tiny helper methods used in the string classes.
|
||||
**************************************************************/
|
||||
|
||||
inline PRInt32 MinInt(PRInt32 anInt1,PRInt32 anInt2){
|
||||
return (anInt1<anInt2) ? anInt1 : anInt2;
|
||||
}
|
||||
|
||||
inline PRInt32 MaxInt(PRInt32 anInt1,PRInt32 anInt2){
|
||||
return (anInt1<anInt2) ? anInt2 : anInt1;
|
||||
}
|
||||
|
||||
inline void AddNullTerminator(nsStr& aDest) {
|
||||
if(eTwoByte==aDest.mCharSize)
|
||||
aDest.mUStr[aDest.mLength]=0;
|
||||
else aDest.mStr[aDest.mLength]=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to access a given char in the given string
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param anIndex tells us where in dest to get the char from
|
||||
* @return the given char, or 0 if anIndex is out of range
|
||||
*/
|
||||
inline PRUnichar GetCharAt(const nsStr& aDest,PRUint32 anIndex){
|
||||
if(anIndex<aDest.mLength) {
|
||||
return (eTwoByte==aDest.mCharSize) ? aDest.mUStr[anIndex] : aDest.mStr[anIndex];
|
||||
}//if
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
class nsIMemoryAgent {
|
||||
public:
|
||||
virtual PRBool Alloc(nsStr& aString,PRUint32 aCount)=0;
|
||||
virtual PRBool Realloc(nsStr& aString,PRUint32 aCount)=0;
|
||||
virtual PRBool Free(nsStr& aString)=0;
|
||||
};
|
||||
|
||||
class nsMemoryAgent : public nsIMemoryAgent {
|
||||
protected:
|
||||
enum eDelta{eDefaultSize=16};
|
||||
public:
|
||||
|
||||
virtual PRBool Alloc(nsStr& aDest,PRUint32 aCount) {
|
||||
|
||||
//we're given the acount value in charunits; now scale up to next multiple.
|
||||
PRUint32 theNewCapacity=eDefaultSize;
|
||||
while(theNewCapacity<aCount){
|
||||
theNewCapacity<<=1;
|
||||
}
|
||||
|
||||
aDest.mCapacity=theNewCapacity++;
|
||||
size_t theSize=(theNewCapacity<<aDest.mCharSize);
|
||||
aDest.mStr=new char[theSize];
|
||||
aDest.mOwnsBuffer=1;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
virtual PRBool Free(nsStr& aDest){
|
||||
if(aDest.mStr){
|
||||
if(aDest.mOwnsBuffer){
|
||||
delete [] aDest.mStr;
|
||||
}
|
||||
aDest.mStr=0;
|
||||
aDest.mOwnsBuffer=0;
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
virtual PRBool Realloc(nsStr& aDest,PRUint32 aCount){
|
||||
Free(aDest);
|
||||
return Alloc(aDest,aCount);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
char* GetSharedEmptyBuffer();
|
||||
nsIMemoryAgent* GetDefaultAgent(void);
|
||||
|
||||
#endif
|
||||
|
||||
2520
mozilla/string/obsolete/nsString.cpp
Normal file
2520
mozilla/string/obsolete/nsString.cpp
Normal file
File diff suppressed because it is too large
Load Diff
819
mozilla/string/obsolete/nsString.h
Normal file
819
mozilla/string/obsolete/nsString.h
Normal file
@@ -0,0 +1,819 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
A. There are two philosophies to building string classes:
|
||||
1. Hide the underlying buffer & offer API's allow indirect iteration
|
||||
2. Reveal underlying buffer, risk corruption, but gain performance
|
||||
|
||||
We chose the second option for performance reasons.
|
||||
|
||||
B Our internal buffer always holds capacity+1 bytes.
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
#ifndef _nsString1
|
||||
#define _nsString1
|
||||
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "nscore.h"
|
||||
#include "nsIAtom.h"
|
||||
#include <iostream.h>
|
||||
#include <stdio.h>
|
||||
#include "nsStr.h"
|
||||
|
||||
#include "nsString2.h" //get new string class
|
||||
|
||||
class nsISizeOfHandler;
|
||||
|
||||
class NS_COM nsString1 {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor. Note that we actually allocate a small buffer
|
||||
* to begin with. This is because the "philosophy" of the string class
|
||||
* was to allow developers direct access to the underlying buffer for
|
||||
* performance reasons.
|
||||
*/
|
||||
nsString1();
|
||||
|
||||
/**
|
||||
* This constructor accepts an isolatin string
|
||||
* @param an ascii is a ptr to a 1-byte cstr
|
||||
*/
|
||||
nsString1(const char* aCString);
|
||||
|
||||
/**
|
||||
* This is our copy constructor
|
||||
* @param reference to another nsString1
|
||||
*/
|
||||
nsString1(const nsString1&);
|
||||
|
||||
/**
|
||||
* Constructor from a unicode string
|
||||
* @param anicodestr pts to a unicode string
|
||||
*/
|
||||
nsString1(const PRUnichar* aUnicode);
|
||||
|
||||
/**
|
||||
* Virtual Destructor
|
||||
*/
|
||||
virtual ~nsString1();
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the length of this string
|
||||
* @return string length
|
||||
*/
|
||||
PRInt32 Length() const { return mLength; }
|
||||
|
||||
|
||||
/**
|
||||
* Sets the new length of the string.
|
||||
* @param aLength is new string length.
|
||||
* @return nada
|
||||
*/
|
||||
void SetLength(PRInt32 aLength);
|
||||
|
||||
/**
|
||||
* This method truncates this string to given length.
|
||||
*
|
||||
* @param anIndex -- new length of string
|
||||
* @return nada
|
||||
*/
|
||||
void Truncate(PRInt32 anIndex=0);
|
||||
|
||||
|
||||
/**
|
||||
* This method gets called when the internal buffer needs
|
||||
* to grow to a given size.
|
||||
* @param aNewLength -- new capacity of string
|
||||
* @return void
|
||||
*/
|
||||
virtual void EnsureCapacityFor(PRInt32 aNewLength);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param
|
||||
*/
|
||||
virtual void SizeOf(nsISizeOfHandler* aHandler) const;
|
||||
|
||||
/**
|
||||
* Determine whether or not the characters in this
|
||||
* string are in sorted order.
|
||||
*
|
||||
* @return TRUE if ordered.
|
||||
*/
|
||||
PRBool IsOrdered(void) const;
|
||||
|
||||
/**
|
||||
* Determine whether or not this string has a length of 0
|
||||
*
|
||||
* @return TRUE if empty.
|
||||
*/
|
||||
PRBool IsEmpty(void) const {
|
||||
return PRBool(0==mLength);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Accessor methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Retrieve pointer to internal string value
|
||||
* @return PRUnichar* to internal string
|
||||
*/
|
||||
const PRUnichar* GetUnicode(void) const;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
operator const PRUnichar*() const;
|
||||
|
||||
/**
|
||||
* Retrieve unicode char at given index
|
||||
* @param offset into string
|
||||
* @return PRUnichar* to internal string
|
||||
*/
|
||||
//PRUnichar operator()(PRInt32 anIndex) const;
|
||||
|
||||
/**
|
||||
* Retrieve reference to unicode char at given index
|
||||
* @param offset into string
|
||||
* @return PRUnichar& from internal string
|
||||
*/
|
||||
PRUnichar& operator[](PRInt32 anIndex) const;
|
||||
|
||||
/**
|
||||
* Retrieve reference to unicode char at given index
|
||||
* @param offset into string
|
||||
* @return PRUnichar& from internal string
|
||||
*/
|
||||
PRUnichar& CharAt(PRInt32 anIndex) const;
|
||||
|
||||
/**
|
||||
* Retrieve reference to first unicode char in string
|
||||
* @return PRUnichar from internal string
|
||||
*/
|
||||
PRUnichar& First() const;
|
||||
|
||||
/**
|
||||
* Retrieve reference to last unicode char in string
|
||||
* @return PRUnichar from internal string
|
||||
*/
|
||||
PRUnichar& Last() const;
|
||||
|
||||
PRBool SetCharAt(PRUnichar aChar,PRInt32 anIndex);
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
String creation methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Create a new string by appending given string to this
|
||||
* @param aString -- 2nd string to be appended
|
||||
* @return new string
|
||||
*/
|
||||
nsString1 operator+(const nsString1& aString);
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given buffer.
|
||||
* @param aCString is a ptr to cstring to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsString1 operator+(const char* aCString);
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given char.
|
||||
* @param aChar is a char to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsString1 operator+(char aChar);
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given buffer.
|
||||
* @param aStr unichar buffer to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsString1 operator+(const PRUnichar* aBuffer);
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given char.
|
||||
* @param aChar is a unichar to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsString1 operator+(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* Converts all chars in internal string to lower
|
||||
*/
|
||||
void ToLowerCase();
|
||||
|
||||
/**
|
||||
* Converts all chars in given string to lower
|
||||
*/
|
||||
void ToLowerCase(nsString1& aString) const;
|
||||
|
||||
/**
|
||||
* Converts all chars in given string to upper
|
||||
*/
|
||||
void ToUpperCase();
|
||||
|
||||
/**
|
||||
* Converts all chars in given string to UCS2
|
||||
* which ensure that the lower 256 chars are correct.
|
||||
*/
|
||||
void ToUCS2(PRInt32 aStartOffset);
|
||||
|
||||
/**
|
||||
* Converts all chars in internal string to upper
|
||||
*/
|
||||
void ToUpperCase(nsString1& aString) const;
|
||||
|
||||
/**
|
||||
* Creates a duplicate clone (ptr) of this string.
|
||||
* @return ptr to clone of this string
|
||||
*/
|
||||
nsString1* ToNewString() const;
|
||||
|
||||
/**
|
||||
* Creates an ascii clone of this string
|
||||
* NOTE: This string is allocated with new; YOU MUST deallocate with delete[]!
|
||||
* @return ptr to new c-String string
|
||||
*/
|
||||
char* ToNewCString() const;
|
||||
|
||||
/**
|
||||
* Copies data from internal buffer onto given char* buffer
|
||||
* @param aBuf is the buffer where data is stored
|
||||
* @param aBuflength is the max # of chars to move to buffer
|
||||
* @return ptr to given buffer
|
||||
*/
|
||||
char* ToCString(char* aBuf,PRInt32 aBufLength) const;
|
||||
|
||||
/**
|
||||
* Copies contents of this onto given string.
|
||||
* @param aString to hold copy of this
|
||||
* @return nada.
|
||||
*/
|
||||
void Copy(nsString1& aString) const;
|
||||
|
||||
/**
|
||||
* Creates an unichar clone of this string
|
||||
* @return ptr to new unichar string
|
||||
*/
|
||||
PRUnichar* ToNewUnicode() const;
|
||||
|
||||
/**
|
||||
* Perform string to float conversion.
|
||||
* @param aErrorCode will contain error if one occurs
|
||||
* @return float rep of string value
|
||||
*/
|
||||
float ToFloat(PRInt32* aErrorCode) const;
|
||||
|
||||
/**
|
||||
* Perform string to int conversion.
|
||||
* @param aErrorCode will contain error if one occurs
|
||||
* @return int rep of string value
|
||||
*/
|
||||
PRInt32 ToInteger(PRInt32* aErrorCode,PRInt32 aRadix=10) const;
|
||||
|
||||
/**********************************************************************
|
||||
String manipulation methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* assign given PRUnichar* to this string
|
||||
* @param aStr: buffer to be assigned to this
|
||||
* @param alength is the length of the given str (or -1)
|
||||
if you want me to determine its length
|
||||
* @return this
|
||||
*/
|
||||
nsString1& SetString(const PRUnichar* aStr,PRInt32 aLength=-1);
|
||||
nsString1& SetString(const char* aCString,PRInt32 aLength=-1);
|
||||
nsString1& SetString(const nsString1& aString);
|
||||
|
||||
/**
|
||||
* assign given string to this one
|
||||
* @param aString: string to be added to this
|
||||
* @return this
|
||||
*/
|
||||
nsString1& operator=(const nsString1& aString);
|
||||
|
||||
/**
|
||||
* assign given char* to this string
|
||||
* @param aCString: buffer to be assigned to this
|
||||
* @return this
|
||||
*/
|
||||
nsString1& operator=(const char* aCString);
|
||||
|
||||
/**
|
||||
* assign given char to this string
|
||||
* @param aChar: char to be assignd to this
|
||||
* @return this
|
||||
*/
|
||||
nsString1& operator=(char aChar);
|
||||
|
||||
/**
|
||||
* assign given unichar* to this string
|
||||
* @param aBuffer: unichar buffer to be assigned to this
|
||||
* @return this
|
||||
*/
|
||||
nsString1& operator=(const PRUnichar* aBuffer);
|
||||
|
||||
/**
|
||||
* assign given char to this string
|
||||
* @param aChar: char to be assignd to this
|
||||
* @return this
|
||||
*/
|
||||
nsString1& operator=(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* append given string to this string
|
||||
* @param aString : string to be appended to this
|
||||
* @return this
|
||||
*/
|
||||
nsString1& operator+=(const nsString1& aString);
|
||||
|
||||
/**
|
||||
* append given buffer to this string
|
||||
* @param aCString: buffer to be appended to this
|
||||
* @return this
|
||||
*/
|
||||
nsString1& operator+=(const char* aCString);
|
||||
|
||||
/**
|
||||
* append given buffer to this string
|
||||
* @param aBuffer: buffer to be appended to this
|
||||
* @return this
|
||||
*/
|
||||
nsString1& operator+=(const PRUnichar* aBuffer);
|
||||
|
||||
/**
|
||||
* append given char to this string
|
||||
* @param aChar: char to be appended to this
|
||||
* @return this
|
||||
*/
|
||||
nsString1& operator+=(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* append given string to this string
|
||||
* @param aString : string to be appended to this
|
||||
* @param alength is the length of the given str (or -1)
|
||||
if you want me to determine its length
|
||||
* @return this
|
||||
*/
|
||||
nsString1& Append(const nsString1& aString,PRInt32 aLength=-1);
|
||||
|
||||
/**
|
||||
* append given string to this string
|
||||
* @param aString : string to be appended to this
|
||||
* @param alength is the length of the given str (or -1)
|
||||
if you want me to determine its length
|
||||
* @return this
|
||||
*/
|
||||
nsString1& Append(const char* aCString,PRInt32 aLength=-1);
|
||||
|
||||
/**
|
||||
* append given string to this string
|
||||
* @param aString : string to be appended to this
|
||||
* @return this
|
||||
*/
|
||||
nsString1& Append(char aChar);
|
||||
|
||||
/**
|
||||
* append given unichar buffer to this string
|
||||
* @param aString : string to be appended to this
|
||||
* @param alength is the length of the given str (or -1)
|
||||
if you want me to determine its length
|
||||
* @return this
|
||||
*/
|
||||
nsString1& Append(const PRUnichar* aBuffer,PRInt32 aLength=-1);
|
||||
|
||||
/**
|
||||
* append given unichar character to this string
|
||||
* @param aChar is the char to be appended to this
|
||||
* @return this
|
||||
*/
|
||||
nsString1& Append(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* Append an integer onto this string
|
||||
* @param aInteger is the int to be appended
|
||||
* @param aRadix specifies 8,10,16
|
||||
* @return this
|
||||
*/
|
||||
nsString1& Append(PRInt32 aInteger,PRInt32 aRadix); //radix=8,10 or 16
|
||||
|
||||
/**
|
||||
* Append a float value onto this string
|
||||
* @param aFloat is the float to be appended
|
||||
* @return this
|
||||
*/
|
||||
nsString1& Append(float aFloat);
|
||||
|
||||
/*
|
||||
* Copies n characters from this string to given string,
|
||||
* starting at the leftmost offset.
|
||||
*
|
||||
*
|
||||
* @param aCopy -- Receiving string
|
||||
* @param aCount -- number of chars to copy
|
||||
* @return number of chars copied
|
||||
*/
|
||||
PRInt32 Left(nsString1& aCopy,PRInt32 aCount) const;
|
||||
|
||||
/*
|
||||
* Copies n characters from this string to given string,
|
||||
* starting at the given offset.
|
||||
*
|
||||
*
|
||||
* @param aCopy -- Receiving string
|
||||
* @param aCount -- number of chars to copy
|
||||
* @param anOffset -- position where copying begins
|
||||
* @return number of chars copied
|
||||
*/
|
||||
PRInt32 Mid(nsString1& aCopy,PRInt32 anOffset,PRInt32 aCount) const;
|
||||
|
||||
/*
|
||||
* Copies n characters from this string to given string,
|
||||
* starting at rightmost char.
|
||||
*
|
||||
*
|
||||
* @param aCopy -- Receiving string
|
||||
* @param aCount -- number of chars to copy
|
||||
* @return number of chars copied
|
||||
*/
|
||||
PRInt32 Right(nsString1& aCopy,PRInt32 aCount) const;
|
||||
|
||||
/*
|
||||
* This method inserts n chars from given string into this
|
||||
* string at str[anOffset].
|
||||
*
|
||||
* @param aCopy -- String to be inserted into this
|
||||
* @param anOffset -- insertion position within this str
|
||||
* @param aCount -- number of chars to be copied from aCopy
|
||||
* @return number of chars inserted into this.
|
||||
*/
|
||||
PRInt32 Insert(const nsString1& aCopy,PRInt32 anOffset,PRInt32 aCount=-1);
|
||||
|
||||
/**
|
||||
* Insert a single unicode char into this string at
|
||||
* a specified offset.
|
||||
*
|
||||
* @param aChar char to be inserted into this string
|
||||
* @param anOffset is insert pos in str
|
||||
* @return the number of chars inserted into this string
|
||||
*/
|
||||
PRInt32 Insert(PRUnichar aChar,PRInt32 anOffset);
|
||||
|
||||
/*
|
||||
* This method is used to cut characters in this string
|
||||
* starting at anOffset, continuing for aCount chars.
|
||||
*
|
||||
* @param anOffset -- start pos for cut operation
|
||||
* @param aCount -- number of chars to be cut
|
||||
* @return *this
|
||||
*/
|
||||
nsString1& Cut(PRInt32 anOffset,PRInt32 aCount);
|
||||
|
||||
/**
|
||||
* This method is used to remove all occurances of the
|
||||
* characters found in aSet from this string.
|
||||
*
|
||||
* @param aSet -- characters to be cut from this
|
||||
* @return *this
|
||||
*/
|
||||
nsString1& StripChars(const char* aSet);
|
||||
|
||||
/**
|
||||
* This method is used to replace all occurances of the
|
||||
* given source char with the given dest char
|
||||
*
|
||||
* @param
|
||||
* @return *this
|
||||
*/
|
||||
nsString1& ReplaceChar(PRUnichar aSourceChar, PRUnichar aDestChar);
|
||||
|
||||
/**
|
||||
* This method strips whitespace throughout the string
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
nsString1& StripWhitespace();
|
||||
|
||||
/**
|
||||
* This method trims characters found in aTrimSet from
|
||||
* either end of the underlying string.
|
||||
*
|
||||
* @param aTrimSet -- contains chars to be trimmed from
|
||||
* both ends
|
||||
* @return this
|
||||
*/
|
||||
nsString1& Trim(const char* aSet,
|
||||
PRBool aEliminateLeading=PR_TRUE,
|
||||
PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**
|
||||
* This method strips whitespace from string.
|
||||
* You can control whether whitespace is yanked from
|
||||
* start and end of string as well.
|
||||
*
|
||||
* @param aEliminateLeading controls stripping of leading ws
|
||||
* @param aEliminateTrailing controls stripping of trailing ws
|
||||
* @return this
|
||||
*/
|
||||
nsString1& CompressWhitespace( PRBool aEliminateLeading=PR_TRUE,
|
||||
PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**
|
||||
* Determine if given char is a valid space character
|
||||
*
|
||||
* @param aChar is character to be tested
|
||||
* @return TRUE if is valid space char
|
||||
*/
|
||||
static PRBool IsSpace(PRUnichar ch);
|
||||
|
||||
/**
|
||||
* Determine if given char in valid alpha range
|
||||
*
|
||||
* @param aChar is character to be tested
|
||||
* @return TRUE if in alpha range
|
||||
*/
|
||||
static PRBool IsAlpha(PRUnichar ch);
|
||||
|
||||
/**
|
||||
* Determine if given char is valid digit
|
||||
*
|
||||
* @param aChar is character to be tested
|
||||
* @return TRUE if char is a valid digit
|
||||
*/
|
||||
static PRBool IsDigit(PRUnichar ch);
|
||||
|
||||
/**********************************************************************
|
||||
Searching methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Search for given character within this string.
|
||||
* This method does so by using a binary search,
|
||||
* so your string HAD BETTER BE ORDERED!
|
||||
*
|
||||
* @param aChar is the unicode char to be found
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 BinarySearch(PRUnichar aChar) const;
|
||||
|
||||
/**
|
||||
* Search for given substring within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 Find(const char* aString) const;
|
||||
PRInt32 Find(const PRUnichar* aString) const;
|
||||
PRInt32 Find(const nsString1& aString) const;
|
||||
|
||||
/**
|
||||
* Search for given char within this string
|
||||
*
|
||||
* @param aChar - char to be found
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 Find(PRUnichar aChar,PRInt32 offset=0) const;
|
||||
|
||||
/**
|
||||
* This method searches this string for the first character
|
||||
* found in the given string
|
||||
* @param aString contains set of chars to be found
|
||||
* @param anOffset tells us where to start searching in this
|
||||
* @return -1 if not found, else the offset in this
|
||||
*/
|
||||
PRInt32 FindCharInSet(const char* aString,PRInt32 anOffset=0) const;
|
||||
PRInt32 FindCharInSet(nsString1& aString,PRInt32 anOffset=0) const;
|
||||
|
||||
/**
|
||||
* This method searches this string for the last character
|
||||
* found in the given string
|
||||
* @param aString contains set of chars to be found
|
||||
* @param anOffset tells us where to start searching in this
|
||||
* @return -1 if not found, else the offset in this
|
||||
*/
|
||||
PRInt32 RFindCharInSet(const char* aString,PRInt32 anOffset=0) const;
|
||||
PRInt32 RFindCharInSet(nsString1& aString,PRInt32 anOffset=0) const;
|
||||
|
||||
|
||||
/**
|
||||
* This methods scans the string backwards, looking for the given string
|
||||
* @param aString is substring to be sought in this
|
||||
* @param aIgnoreCase tells us whether or not to do caseless compare
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 RFind(const char* aCString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 RFind(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 RFind(const nsString1& aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
|
||||
/**
|
||||
* This methods scans the string backwards, looking for the given char
|
||||
* @param char is the char to be sought in this
|
||||
* @param aIgnoreCase tells us whether or not to do caseless compare
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 RFind(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
|
||||
/**********************************************************************
|
||||
Comparison methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Compares a given string type to this string.
|
||||
* @update gess 7/27/98
|
||||
* @param S is the string to be compared
|
||||
* @param aIgnoreCase tells us how to treat case
|
||||
* @return -1,0,1
|
||||
*/
|
||||
virtual PRInt32 Compare(const nsString1 &aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
virtual PRInt32 Compare(const char *aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
|
||||
virtual PRInt32 Compare(const PRUnichar *aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
|
||||
|
||||
/**
|
||||
* These methods compare a given string type to this one
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator==(const nsString1 &aString) const;
|
||||
PRBool operator==(const char *aString) const;
|
||||
PRBool operator==(const PRUnichar* aString) const;
|
||||
PRBool operator==(PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods perform a !compare of a given string type to this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE
|
||||
*/
|
||||
PRBool operator!=(const nsString1 &aString) const;
|
||||
PRBool operator!=(const char *aString) const;
|
||||
PRBool operator!=(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is < than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator<(const nsString1 &aString) const;
|
||||
PRBool operator<(const char *aString) const;
|
||||
PRBool operator<(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is > than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator>(const nsString1 &S) const;
|
||||
PRBool operator>(const char *aCString) const;
|
||||
PRBool operator>(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is <= than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator<=(const nsString1 &S) const;
|
||||
PRBool operator<=(const char *aCString) const;
|
||||
PRBool operator<=(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is >= than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator>=(const nsString1 &S) const;
|
||||
PRBool operator>=(const char* aCString) const;
|
||||
PRBool operator>=(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* Compare this to given string; note that we compare full strings here.
|
||||
* The optional length argument just lets us know how long the given string is.
|
||||
* If you provide a length, it is compared to length of this string as an
|
||||
* optimization.
|
||||
*
|
||||
* @param aString -- the string to compare to this
|
||||
* @param aLength -- optional length of given string.
|
||||
* @return TRUE if equal
|
||||
*/
|
||||
PRBool Equals(const nsString1& aString) const;
|
||||
PRBool Equals(const char* aString,PRInt32 aLength=-1) const;
|
||||
PRBool Equals(const nsIAtom *aAtom) const;
|
||||
|
||||
|
||||
/**
|
||||
* Compares to unichar string ptrs to each other
|
||||
* @param s1 is a ptr to a unichar buffer
|
||||
* @param s2 is a ptr to a unichar buffer
|
||||
* @return TRUE if they match
|
||||
*/
|
||||
PRBool Equals(const PRUnichar* s1, const PRUnichar* s2) const;
|
||||
|
||||
/**
|
||||
* Compare this to given string; note that we compare full strings here.
|
||||
* The optional length argument just lets us know how long the given string is.
|
||||
* If you provide a length, it is compared to length of this string as an
|
||||
* optimization.
|
||||
*
|
||||
* @param aString -- the string to compare to this
|
||||
* @param aLength -- optional length of given string.
|
||||
* @return TRUE if equal
|
||||
*/
|
||||
PRBool EqualsIgnoreCase(const nsString1& aString) const;
|
||||
PRBool EqualsIgnoreCase(const char* aString,PRInt32 aLength=-1) const;
|
||||
PRBool EqualsIgnoreCase(const nsIAtom *aAtom) const;
|
||||
|
||||
/**
|
||||
* Compares to unichar string ptrs to each other without respect to case
|
||||
* @param s1 is a ptr to a unichar buffer
|
||||
* @param s2 is a ptr to a unichar buffer
|
||||
* @return TRUE if they match
|
||||
*/
|
||||
PRBool EqualsIgnoreCase(const PRUnichar* s1, const PRUnichar* s2) const;
|
||||
|
||||
|
||||
static void SelfTest();
|
||||
virtual void DebugDump(ostream& aStream) const;
|
||||
|
||||
protected:
|
||||
|
||||
typedef PRUnichar chartype;
|
||||
|
||||
chartype* mStr;
|
||||
PRInt32 mLength;
|
||||
PRInt32 mCapacity;
|
||||
#ifdef RICKG_DEBUG
|
||||
static PRBool mSelfTested;
|
||||
#endif
|
||||
};
|
||||
|
||||
ostream& operator<<(ostream& os,nsString1& aString);
|
||||
extern NS_COM int fputs(const nsString1& aString, FILE* out);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A version of nsString1 which is designed to be used as an automatic
|
||||
* variable. It attempts to operate out of a fixed size internal
|
||||
* buffer until too much data is added; then a dynamic buffer is
|
||||
* allocated and grown as necessary.
|
||||
*/
|
||||
// XXX template this with a parameter for the size of the buffer?
|
||||
class NS_COM nsAutoString1 : public nsString1 {
|
||||
public:
|
||||
nsAutoString1();
|
||||
nsAutoString1(const nsString1& other);
|
||||
nsAutoString1(const nsAutoString1& other);
|
||||
nsAutoString1(PRUnichar aChar);
|
||||
nsAutoString1(const char* aCString);
|
||||
nsAutoString1(const PRUnichar* us, PRInt32 uslen = -1);
|
||||
virtual ~nsAutoString1();
|
||||
|
||||
nsAutoString1& operator=(const nsString1& aString) {nsString1::operator=(aString); return *this;}
|
||||
nsAutoString1& operator=(const nsAutoString1& aString) {nsString1::operator=(aString); return *this;}
|
||||
nsAutoString1& operator=(const char* aCString) {nsString1::operator=(aCString); return *this;}
|
||||
nsAutoString1& operator=(char aChar) {nsString1::operator=(aChar); return *this;}
|
||||
nsAutoString1& operator=(const PRUnichar* aBuffer) {nsString1::operator=(aBuffer); return *this;}
|
||||
nsAutoString1& operator=(PRUnichar aChar) {nsString1::operator=(aChar); return *this;}
|
||||
|
||||
virtual void SizeOf(nsISizeOfHandler* aHandler) const;
|
||||
|
||||
static void SelfTest();
|
||||
|
||||
protected:
|
||||
virtual void EnsureCapacityFor(PRInt32 aNewLength);
|
||||
|
||||
chartype mBuf[32];
|
||||
};
|
||||
|
||||
ostream& operator<<(ostream& os,nsAutoString1& aString);
|
||||
|
||||
#endif
|
||||
|
||||
2410
mozilla/string/obsolete/nsString2.cpp
Normal file
2410
mozilla/string/obsolete/nsString2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
827
mozilla/string/obsolete/nsString2.h
Normal file
827
mozilla/string/obsolete/nsString2.h
Normal file
@@ -0,0 +1,827 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
This version of the nsString class offers many improvements over the
|
||||
original version:
|
||||
1. Wide and narrow chars
|
||||
2. Allocators
|
||||
3. Much smarter autostrings
|
||||
4. Subsumable strings
|
||||
5. Memory pools and recycling
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
#ifndef _nsString2
|
||||
#define _nsString2
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "nscore.h"
|
||||
#include <iostream.h>
|
||||
#include <stdio.h>
|
||||
#include "nsCRT.h"
|
||||
|
||||
#include "nsStr.h"
|
||||
#include <iostream.h>
|
||||
#include <stdio.h>
|
||||
#include "nsIAtom.h"
|
||||
|
||||
class nsISizeOfHandler;
|
||||
|
||||
|
||||
#define nsString2 nsString
|
||||
#define nsAutoString2 nsAutoString
|
||||
|
||||
#define kRadix10 (10)
|
||||
#define kRadix16 (16)
|
||||
#define kAutoDetect (100)
|
||||
#define kRadixUnknown (kAutoDetect+1)
|
||||
|
||||
|
||||
class NS_COM nsSubsumeStr;
|
||||
class NS_COM nsString2 : public nsStr {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor. Note that we actually allocate a small buffer
|
||||
* to begin with. This is because the "philosophy" of the string class
|
||||
* was to allow developers direct access to the underlying buffer for
|
||||
* performance reasons.
|
||||
*/
|
||||
nsString2(eCharSize aCharSize=kDefaultCharSize,nsIMemoryAgent* anAgent=0);
|
||||
|
||||
|
||||
/**
|
||||
* This constructor accepts an isolatin string
|
||||
* @param aCString is a ptr to a 1-byte cstr
|
||||
*/
|
||||
nsString2(const char* aCString,eCharSize aCharSize=kDefaultCharSize,nsIMemoryAgent* anAgent=0);
|
||||
|
||||
/**
|
||||
* This constructor accepts a unichar string
|
||||
* @param aCString is a ptr to a 2-byte cstr
|
||||
*/
|
||||
nsString2(const PRUnichar* aString,eCharSize aCharSize=kDefaultCharSize,nsIMemoryAgent* anAgent=0);
|
||||
|
||||
/**
|
||||
* This is a copy constructor that accepts an nsStr
|
||||
* @param reference to another nsString2
|
||||
*/
|
||||
nsString2(const nsStr&,eCharSize aCharSize=kDefaultCharSize,nsIMemoryAgent* anAgent=0);
|
||||
|
||||
/**
|
||||
* This is our copy constructor
|
||||
* @param reference to another nsString2
|
||||
*/
|
||||
nsString2(const nsString2& aString);
|
||||
|
||||
/**
|
||||
* This constructor takes a subsumestr
|
||||
* @param reference to subsumestr
|
||||
*/
|
||||
nsString2(nsSubsumeStr& aSubsumeStr);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*
|
||||
*/
|
||||
virtual ~nsString2();
|
||||
|
||||
/**
|
||||
* Retrieve the length of this string
|
||||
* @return string length
|
||||
*/
|
||||
inline PRInt32 Length() const { return (PRInt32)mLength; }
|
||||
|
||||
/**
|
||||
* Retrieve the size of this string
|
||||
* @return string length
|
||||
*/
|
||||
virtual void SizeOf(nsISizeOfHandler* aHandler) const;
|
||||
|
||||
|
||||
/**
|
||||
* Call this method if you want to force a different string capacity
|
||||
* @update gess7/30/98
|
||||
* @param aLength -- contains new length for mStr
|
||||
* @return
|
||||
*/
|
||||
void SetLength(PRUint32 aLength) {
|
||||
SetCapacity(aLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new length of the string.
|
||||
* @param aLength is new string length.
|
||||
* @return nada
|
||||
*/
|
||||
void SetCapacity(PRUint32 aLength);
|
||||
/**
|
||||
* This method truncates this string to given length.
|
||||
*
|
||||
* @param anIndex -- new length of string
|
||||
* @return nada
|
||||
*/
|
||||
void Truncate(PRInt32 anIndex=0);
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether or not the characters in this
|
||||
* string are in sorted order.
|
||||
*
|
||||
* @return TRUE if ordered.
|
||||
*/
|
||||
PRBool IsOrdered(void) const;
|
||||
|
||||
/**
|
||||
* Determine whether or not the characters in this
|
||||
* string are in store as 1 or 2 byte (unicode) strings.
|
||||
*
|
||||
* @return TRUE if ordered.
|
||||
*/
|
||||
PRBool IsUnicode(void) const {
|
||||
PRBool result=PRBool(mCharSize==eTwoByte);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether or not this string has a length of 0
|
||||
*
|
||||
* @return TRUE if empty.
|
||||
*/
|
||||
PRBool IsEmpty(void) const {
|
||||
return PRBool(0==mLength);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Accessor methods...
|
||||
*********************************************************************/
|
||||
|
||||
const char* GetBuffer(void) const;
|
||||
const PRUnichar* GetUnicode(void) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
PRUnichar operator[](PRUint32 anIndex) const;
|
||||
PRUnichar CharAt(PRUint32 anIndex) const;
|
||||
PRUnichar First(void) const;
|
||||
PRUnichar Last(void) const;
|
||||
|
||||
PRBool SetCharAt(PRUnichar aChar,PRUint32 anIndex);
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
String creation methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Create a new string by appending given string to this
|
||||
* @param aString -- 2nd string to be appended
|
||||
* @return new string
|
||||
*/
|
||||
nsSubsumeStr operator+(const nsStr& aString);
|
||||
|
||||
/**
|
||||
* Create a new string by appending given string to this
|
||||
* @param aString -- 2nd string to be appended
|
||||
* @return new string
|
||||
*/
|
||||
nsSubsumeStr operator+(const nsString2& aString);
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given buffer.
|
||||
* @param aCString is a ptr to cstring to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsSubsumeStr operator+(const char* aCString);
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given wide buffer.
|
||||
* @param aString is a ptr to UC-string to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsSubsumeStr operator+(const PRUnichar* aString);
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given char.
|
||||
* @param aChar is a char to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsSubsumeStr operator+(char aChar);
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given char.
|
||||
* @param aChar is a unichar to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsSubsumeStr operator+(PRUnichar aChar);
|
||||
|
||||
/**********************************************************************
|
||||
Lexomorphic transforms...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Converts all chars in given string to UCS2
|
||||
* which ensure that the lower 256 chars are correct.
|
||||
*/
|
||||
void ToUCS2(PRUint32 aStartOffset);
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase
|
||||
* @update gess 7/27/98
|
||||
*/
|
||||
void ToLowerCase();
|
||||
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase, and
|
||||
* stores them in aOut
|
||||
* @update gess 7/27/98
|
||||
* @param aOut is a string to contain result
|
||||
*/
|
||||
void ToLowerCase(nsString2& aString) const;
|
||||
|
||||
/**
|
||||
* Converts chars in this to uppercase
|
||||
* @update gess 7/27/98
|
||||
*/
|
||||
void ToUpperCase();
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase, and
|
||||
* stores them in a given output string
|
||||
* @update gess 7/27/98
|
||||
* @param aOut is a string to contain result
|
||||
*/
|
||||
void ToUpperCase(nsString2& aString) const;
|
||||
|
||||
|
||||
/**
|
||||
* This method is used to remove all occurances of the
|
||||
* characters found in aSet from this string.
|
||||
*
|
||||
* @param aSet -- characters to be cut from this
|
||||
* @return *this
|
||||
*/
|
||||
nsString2& StripChars(const char* aSet);
|
||||
|
||||
/**
|
||||
* This method strips whitespace throughout the string
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
nsString2& StripWhitespace();
|
||||
|
||||
/**
|
||||
* swaps occurence of 1 string for another
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
nsString2& ReplaceChar(PRUnichar aSourceChar,PRUnichar aDestChar);
|
||||
|
||||
/**
|
||||
* This method trims characters found in aTrimSet from
|
||||
* either end of the underlying string.
|
||||
*
|
||||
* @param aTrimSet -- contains chars to be trimmed from
|
||||
* both ends
|
||||
* @return this
|
||||
*/
|
||||
nsString2& Trim(const char* aSet,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**
|
||||
* This method strips whitespace from string.
|
||||
* You can control whether whitespace is yanked from
|
||||
* start and end of string as well.
|
||||
*
|
||||
* @param aEliminateLeading controls stripping of leading ws
|
||||
* @param aEliminateTrailing controls stripping of trailing ws
|
||||
* @return this
|
||||
*/
|
||||
nsString2& CompressSet(const char* aSet, char aChar, PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**
|
||||
* This method strips whitespace from string.
|
||||
* You can control whether whitespace is yanked from
|
||||
* start and end of string as well.
|
||||
*
|
||||
* @param aEliminateLeading controls stripping of leading ws
|
||||
* @param aEliminateTrailing controls stripping of trailing ws
|
||||
* @return this
|
||||
*/
|
||||
nsString2& CompressWhitespace( PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**********************************************************************
|
||||
string conversion methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* This method constructs a new nsString2 on the stack that is a copy
|
||||
* of this string.
|
||||
*
|
||||
*/
|
||||
nsString2* ToNewString() const;
|
||||
|
||||
/**
|
||||
* Creates an ISOLatin1 clone of this string
|
||||
* @return ptr to new isolatin1 string
|
||||
*/
|
||||
char* ToNewCString() const;
|
||||
|
||||
/**
|
||||
* Creates a unicode clone of this string
|
||||
* @return ptr to new unicode string
|
||||
*/
|
||||
PRUnichar* ToNewUnicode() const;
|
||||
|
||||
/**
|
||||
* Copies data from internal buffer onto given char* buffer
|
||||
* @param aBuf is the buffer where data is stored
|
||||
* @param aBuflength is the max # of chars to move to buffer
|
||||
* @return ptr to given buffer
|
||||
*/
|
||||
char* ToCString(char* aBuf,PRUint32 aBufLength,PRUint32 anOffset=0) const;
|
||||
|
||||
/**
|
||||
* Perform string to float conversion.
|
||||
* @param aErrorCode will contain error if one occurs
|
||||
* @return float rep of string value
|
||||
*/
|
||||
float ToFloat(PRInt32* aErrorCode) const;
|
||||
|
||||
/**
|
||||
* Try to derive the radix from the value contained in this string
|
||||
* @return kRadix10, kRadix16 or kAutoDetect (meaning unknown)
|
||||
*/
|
||||
PRUint32 DetermineRadix(void);
|
||||
|
||||
/**
|
||||
* Perform string to int conversion.
|
||||
* @param aErrorCode will contain error if one occurs
|
||||
* @return int rep of string value
|
||||
*/
|
||||
PRInt32 ToInteger(PRInt32* aErrorCode,PRUint32 aRadix=kRadix10) const;
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
String manipulation methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Functionally equivalent to assign or operator=
|
||||
*
|
||||
*/
|
||||
nsString2& SetString(const char* aString,PRInt32 aLength=-1) {return Assign(aString,aLength);}
|
||||
nsString2& SetString(const PRUnichar* aString,PRInt32 aLength=-1) {return Assign(aString,aLength);}
|
||||
nsString2& SetString(const nsString2& aString,PRInt32 aLength=-1) {return Assign(aString,aLength);}
|
||||
|
||||
/**
|
||||
* assign given string to this string
|
||||
* @param aStr: buffer to be assigned to this
|
||||
* @param alength is the length of the given str (or -1)
|
||||
if you want me to determine its length
|
||||
* @return this
|
||||
*/
|
||||
nsString2& Assign(const nsString2& aString,PRInt32 aCount=-1);
|
||||
nsString2& Assign(const nsStr& aString,PRInt32 aCount=-1);
|
||||
nsString2& Assign(const char* aString,PRInt32 aCount=-1);
|
||||
nsString2& Assign(const PRUnichar* aString,PRInt32 aCount=-1);
|
||||
nsString2& Assign(char aChar);
|
||||
nsString2& Assign(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* here come a bunch of assignment operators...
|
||||
* @param aString: string to be added to this
|
||||
* @return this
|
||||
*/
|
||||
nsString2& operator=(const nsString2& aString) {return Assign(aString);}
|
||||
nsString2& operator=(const nsStr& aString) {return Assign(aString);}
|
||||
nsString2& operator=(char aChar) {return Assign(aChar);}
|
||||
nsString2& operator=(PRUnichar aChar) {return Assign(aChar);}
|
||||
nsString2& operator=(const char* aCString) {return Assign(aCString);}
|
||||
nsString2& operator=(const PRUnichar* aString) {return Assign(aString);}
|
||||
#ifdef AIX
|
||||
nsString2& operator=(const nsSubsumeStr& aSubsumeString); // AIX requires a const here
|
||||
#else
|
||||
nsString2& operator=(nsSubsumeStr& aSubsumeString);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Here's a bunch of append mehtods for varying types...
|
||||
* @param aString : string to be appended to this
|
||||
* @return this
|
||||
*/
|
||||
nsString2& operator+=(const nsStr& aString){return Append(aString,aString.mLength);}
|
||||
nsString2& operator+=(const nsString2& aString){return Append(aString,aString.mLength);}
|
||||
nsString2& operator+=(const char* aCString) {return Append(aCString);}
|
||||
//nsString2& operator+=(char aChar){return Append(aChar);}
|
||||
nsString2& operator+=(const PRUnichar* aUCString) {return Append(aUCString);}
|
||||
nsString2& operator+=(PRUnichar aChar){return Append(aChar);}
|
||||
|
||||
/*
|
||||
* Appends n characters from given string to this,
|
||||
* This version computes the length of your given string
|
||||
*
|
||||
* @param aString is the source to be appended to this
|
||||
* @return number of chars copied
|
||||
*/
|
||||
nsString2& Append(const nsStr& aString) {return Append(aString,aString.mLength);}
|
||||
nsString2& Append(const nsString2& aString) {return Append(aString,aString.mLength);}
|
||||
|
||||
|
||||
/*
|
||||
* Appends n characters from given string to this,
|
||||
*
|
||||
* @param aString is the source to be appended to this
|
||||
* @param aCount -- number of chars to copy
|
||||
* @return number of chars copied
|
||||
*/
|
||||
nsString2& Append(const nsStr& aString,PRInt32 aCount);
|
||||
nsString2& Append(const nsString2& aString,PRInt32 aCount);
|
||||
nsString2& Append(const char* aString,PRInt32 aCount=-1);
|
||||
nsString2& Append(const PRUnichar* aString,PRInt32 aCount=-1);
|
||||
nsString2& Append(char aChar);
|
||||
nsString2& Append(PRUnichar aChar);
|
||||
nsString2& Append(PRInt32 aInteger,PRInt32 aRadix=10); //radix=8,10 or 16
|
||||
nsString2& Append(float aFloat);
|
||||
|
||||
/*
|
||||
* Copies n characters from this string to given string,
|
||||
* starting at the leftmost offset.
|
||||
*
|
||||
*
|
||||
* @param aCopy -- Receiving string
|
||||
* @param aCount -- number of chars to copy
|
||||
* @return number of chars copied
|
||||
*/
|
||||
PRUint32 Left(nsString2& aCopy,PRInt32 aCount) const;
|
||||
|
||||
/*
|
||||
* Copies n characters from this string to given string,
|
||||
* starting at the given offset.
|
||||
*
|
||||
*
|
||||
* @param aCopy -- Receiving string
|
||||
* @param aCount -- number of chars to copy
|
||||
* @param anOffset -- position where copying begins
|
||||
* @return number of chars copied
|
||||
*/
|
||||
PRUint32 Mid(nsString2& aCopy,PRUint32 anOffset,PRInt32 aCount) const;
|
||||
|
||||
/*
|
||||
* Copies n characters from this string to given string,
|
||||
* starting at rightmost char.
|
||||
*
|
||||
*
|
||||
* @param aCopy -- Receiving string
|
||||
* @param aCount -- number of chars to copy
|
||||
* @return number of chars copied
|
||||
*/
|
||||
PRUint32 Right(nsString2& aCopy,PRInt32 aCount) const;
|
||||
|
||||
/*
|
||||
* This method inserts n chars from given string into this
|
||||
* string at str[anOffset].
|
||||
*
|
||||
* @param aCopy -- String to be inserted into this
|
||||
* @param anOffset -- insertion position within this str
|
||||
* @param aCount -- number of chars to be copied from aCopy
|
||||
* @return number of chars inserted into this.
|
||||
*/
|
||||
nsString2& Insert(const nsString2& aCopy,PRUint32 anOffset,PRInt32 aCount=-1);
|
||||
|
||||
/**
|
||||
* Insert a given string into this string at
|
||||
* a specified offset.
|
||||
*
|
||||
* @param aString* to be inserted into this string
|
||||
* @param anOffset is insert pos in str
|
||||
* @return the number of chars inserted into this string
|
||||
*/
|
||||
nsString2& Insert(const char* aChar,PRUint32 anOffset,PRInt32 aCount=-1);
|
||||
nsString2& Insert(const PRUnichar* aChar,PRUint32 anOffset,PRInt32 aCount=-1);
|
||||
|
||||
/**
|
||||
* Insert a single char into this string at
|
||||
* a specified offset.
|
||||
*
|
||||
* @param character to be inserted into this string
|
||||
* @param anOffset is insert pos in str
|
||||
* @return the number of chars inserted into this string
|
||||
*/
|
||||
//nsString2& Insert(char aChar,PRUint32 anOffset);
|
||||
nsString2& Insert(PRUnichar aChar,PRUint32 anOffset);
|
||||
|
||||
/*
|
||||
* This method is used to cut characters in this string
|
||||
* starting at anOffset, continuing for aCount chars.
|
||||
*
|
||||
* @param anOffset -- start pos for cut operation
|
||||
* @param aCount -- number of chars to be cut
|
||||
* @return *this
|
||||
*/
|
||||
nsString2& Cut(PRUint32 anOffset,PRInt32 aCount);
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Searching methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Search for given character within this string.
|
||||
* This method does so by using a binary search,
|
||||
* so your string HAD BETTER BE ORDERED!
|
||||
*
|
||||
* @param aChar is the unicode char to be found
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 BinarySearch(PRUnichar aChar) const;
|
||||
|
||||
/**
|
||||
* Search for given substring within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 Find(const nsString2& aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 Find(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 Find(const char* aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 Find(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 Find(PRUnichar aChar,PRUint32 offset=0,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
|
||||
/**
|
||||
* This method searches this string for the first character
|
||||
* found in the given string
|
||||
* @param aString contains set of chars to be found
|
||||
* @param anOffset tells us where to start searching in this
|
||||
* @return -1 if not found, else the offset in this
|
||||
*/
|
||||
PRInt32 FindCharInSet(const char* aString,PRUint32 anOffset=0) const;
|
||||
PRInt32 FindCharInSet(const PRUnichar* aString,PRUint32 anOffset=0) const;
|
||||
PRInt32 FindCharInSet(const nsString2& aString,PRUint32 anOffset=0) const;
|
||||
|
||||
/**
|
||||
* This method searches this string for the last character
|
||||
* found in the given string
|
||||
* @param aString contains set of chars to be found
|
||||
* @param anOffset tells us where to start searching in this
|
||||
* @return -1 if not found, else the offset in this
|
||||
*/
|
||||
PRInt32 RFindCharInSet(const char* aString,PRUint32 anOffset=0) const;
|
||||
PRInt32 RFindCharInSet(const PRUnichar* aString,PRUint32 anOffset=0) const;
|
||||
PRInt32 RFindCharInSet(const nsString2& aString,PRUint32 anOffset=0) const;
|
||||
|
||||
|
||||
/**
|
||||
* This methods scans the string backwards, looking for the given string
|
||||
* @param aString is substring to be sought in this
|
||||
* @param aIgnoreCase tells us whether or not to do caseless compare
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 RFind(const char* aCString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 RFind(const nsString2& aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 RFind(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 RFind(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 RFind(PRUnichar aChar,PRUint32 offset=0,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
|
||||
/**********************************************************************
|
||||
Comparison methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Compares a given string type to this string.
|
||||
* @update gess 7/27/98
|
||||
* @param S is the string to be compared
|
||||
* @param aIgnoreCase tells us how to treat case
|
||||
* @return -1,0,1
|
||||
*/
|
||||
virtual PRInt32 Compare(const nsString2& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
|
||||
virtual PRInt32 Compare(const nsStr &aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
|
||||
virtual PRInt32 Compare(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
|
||||
virtual PRInt32 Compare(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
|
||||
|
||||
/**
|
||||
* These methods compare a given string type to this one
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator==(const nsString2 &aString) const;
|
||||
PRBool operator==(const nsStr &aString) const;
|
||||
PRBool operator==(const char *aString) const;
|
||||
PRBool operator==(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods perform a !compare of a given string type to this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE
|
||||
*/
|
||||
PRBool operator!=(const nsString2 &aString) const;
|
||||
PRBool operator!=(const nsStr &aString) const;
|
||||
PRBool operator!=(const char* aString) const;
|
||||
PRBool operator!=(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is < than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator<(const nsString2 &aString) const;
|
||||
PRBool operator<(const nsStr &aString) const;
|
||||
PRBool operator<(const char* aString) const;
|
||||
PRBool operator<(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is > than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator>(const nsString2 &aString) const;
|
||||
PRBool operator>(const nsStr &S) const;
|
||||
PRBool operator>(const char* aString) const;
|
||||
PRBool operator>(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is <= than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator<=(const nsString2 &aString) const;
|
||||
PRBool operator<=(const nsStr &S) const;
|
||||
PRBool operator<=(const char* aString) const;
|
||||
PRBool operator<=(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is >= than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator>=(const nsString2 &aString) const;
|
||||
PRBool operator>=(const nsStr &S) const;
|
||||
PRBool operator>=(const char* aString) const;
|
||||
PRBool operator>=(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* Compare this to given string; note that we compare full strings here.
|
||||
* The optional length argument just lets us know how long the given string is.
|
||||
* If you provide a length, it is compared to length of this string as an
|
||||
* optimization.
|
||||
*
|
||||
* @param aString -- the string to compare to this
|
||||
* @param aLength -- optional length of given string.
|
||||
* @return TRUE if equal
|
||||
*/
|
||||
PRBool Equals(const nsString2 &aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRBool Equals(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRBool Equals(const char* aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRBool Equals(const char* aString,PRUint32 aCount,PRBool aIgnoreCase) const;
|
||||
PRBool Equals(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRBool Equals(const PRUnichar* aString,PRUint32 aCount,PRBool aIgnoreCase) const;
|
||||
PRBool Equals(const nsIAtom* anAtom,PRBool aIgnoreCase) const;
|
||||
PRBool Equals(const PRUnichar* s1, const PRUnichar* s2,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
|
||||
PRBool EqualsIgnoreCase(const nsString2& aString) const;
|
||||
PRBool EqualsIgnoreCase(const char* aString,PRInt32 aLength=-1) const;
|
||||
PRBool EqualsIgnoreCase(const nsIAtom *aAtom) const;
|
||||
PRBool EqualsIgnoreCase(const PRUnichar* s1, const PRUnichar* s2) const;
|
||||
|
||||
|
||||
/**
|
||||
* Determine if given char is a valid space character
|
||||
*
|
||||
* @param aChar is character to be tested
|
||||
* @return TRUE if is valid space char
|
||||
*/
|
||||
static PRBool IsSpace(PRUnichar ch);
|
||||
|
||||
/**
|
||||
* Determine if given char in valid alpha range
|
||||
*
|
||||
* @param aChar is character to be tested
|
||||
* @return TRUE if in alpha range
|
||||
*/
|
||||
static PRBool IsAlpha(PRUnichar ch);
|
||||
|
||||
/**
|
||||
* Determine if given char is valid digit
|
||||
*
|
||||
* @param aChar is character to be tested
|
||||
* @return TRUE if char is a valid digit
|
||||
*/
|
||||
static PRBool IsDigit(PRUnichar ch);
|
||||
|
||||
static void Recycle(nsString2* aString);
|
||||
static nsString2* CreateString(eCharSize aCharSize=eTwoByte);
|
||||
|
||||
virtual void DebugDump(ostream& aStream) const;
|
||||
|
||||
nsIMemoryAgent* mAgent;
|
||||
|
||||
};
|
||||
|
||||
extern NS_COM int fputs(const nsString2& aString, FILE* out);
|
||||
ostream& operator<<(ostream& aStream,const nsString2& aString);
|
||||
|
||||
|
||||
/**************************************************************
|
||||
Here comes the AutoString class which uses internal memory
|
||||
(typically found on the stack) for its default buffer.
|
||||
If the buffer needs to grow, it gets reallocated on the heap.
|
||||
**************************************************************/
|
||||
|
||||
class NS_COM nsAutoString2 : public nsString2 {
|
||||
public:
|
||||
|
||||
nsAutoString2(eCharSize aCharSize=kDefaultCharSize);
|
||||
nsAutoString2(nsStr& anExtBuffer,const char* aCString);
|
||||
|
||||
|
||||
nsAutoString2(const char* aCString,eCharSize aCharSize=kDefaultCharSize);
|
||||
nsAutoString2(char* aCString,PRInt32 aCapacity=-1,eCharSize aCharSize=kDefaultCharSize,PRBool assumeOwnership=PR_FALSE);
|
||||
nsAutoString2(const PRUnichar* aString,eCharSize aCharSize=kDefaultCharSize);
|
||||
nsAutoString2(PRUnichar* aString,PRInt32 aCapacity=-1,eCharSize aCharSize=kDefaultCharSize,PRBool assumeOwnership=PR_FALSE);
|
||||
|
||||
nsAutoString2(const nsStr& aString,eCharSize aCharSize=kDefaultCharSize);
|
||||
nsAutoString2(const nsString2& aString,eCharSize aCharSize=kDefaultCharSize);
|
||||
nsAutoString2(const nsAutoString2& aString,eCharSize aCharSize=kDefaultCharSize);
|
||||
#ifdef AIX
|
||||
nsAutoString2(const nsSubsumeStr& aSubsumeStr); // AIX requires a const
|
||||
#else
|
||||
nsAutoString2(nsSubsumeStr& aSubsumeStr);
|
||||
#endif // AIX
|
||||
nsAutoString2(PRUnichar aChar,eCharSize aCharSize=kDefaultCharSize);
|
||||
virtual ~nsAutoString2();
|
||||
|
||||
nsAutoString2& operator=(const nsString2& aString) {nsString2::operator=(aString); return *this;}
|
||||
nsAutoString2& operator=(const nsStr& aString) {nsString2::Assign(aString); return *this;}
|
||||
nsAutoString2& operator=(const nsAutoString2& aString) {nsString2::operator=(aString); return *this;}
|
||||
nsAutoString2& operator=(const char* aCString) {nsString2::operator=(aCString); return *this;}
|
||||
nsAutoString2& operator=(char aChar) {nsString2::operator=(aChar); return *this;}
|
||||
nsAutoString2& operator=(const PRUnichar* aBuffer) {nsString2::operator=(aBuffer); return *this;}
|
||||
nsAutoString2& operator=(PRUnichar aChar) {nsString2::operator=(aChar); return *this;}
|
||||
|
||||
/**
|
||||
* Retrieve the size of this string
|
||||
* @return string length
|
||||
*/
|
||||
virtual void SizeOf(nsISizeOfHandler* aHandler) const;
|
||||
|
||||
char mBuffer[32];
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
The subsumestr class is very unusual.
|
||||
It differs from a normal string in that it doesn't use normal
|
||||
copy semantics when another string is assign to this.
|
||||
Instead, it "steals" the contents of the source string.
|
||||
|
||||
This is very handy for returning nsString classes as part of
|
||||
an operator+(...) for example, in that it cuts down the number
|
||||
of copy operations that must occur.
|
||||
|
||||
You should probably not use this class unless you really know
|
||||
what you're doing.
|
||||
***************************************************************/
|
||||
class NS_COM nsSubsumeStr : public nsString2 {
|
||||
public:
|
||||
nsSubsumeStr(nsString2& aString);
|
||||
nsSubsumeStr(nsStr& aString);
|
||||
nsSubsumeStr(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
nsSubsumeStr(char* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
|
||||
***************************************************************/
|
||||
class NS_COM nsCAutoString: public nsAutoString{
|
||||
public:
|
||||
nsCAutoString(const nsString2& aString);
|
||||
operator const char*() const;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
167
mozilla/string/obsolete/nsXPIDLString.cpp
Normal file
167
mozilla/string/obsolete/nsXPIDLString.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsDebug.h"
|
||||
#include "nsIAllocator.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "plstr.h"
|
||||
|
||||
// If the allocator changes, fix it here.
|
||||
#define XPIDL_STRING_ALLOC(__len) ((PRUnichar*) nsAllocator::Alloc((__len) * sizeof(PRUnichar)))
|
||||
#define XPIDL_CSTRING_ALLOC(__len) ((char*) nsAllocator::Alloc((__len) * sizeof(char)))
|
||||
#define XPIDL_FREE(__ptr) (nsAllocator::Free(__ptr))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsXPIDLString
|
||||
|
||||
nsXPIDLString::nsXPIDLString()
|
||||
: mBufOwner(PR_FALSE),
|
||||
mBuf(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
nsXPIDLString::~nsXPIDLString()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
}
|
||||
|
||||
|
||||
nsXPIDLString::operator const PRUnichar*()
|
||||
{
|
||||
return mBuf;
|
||||
}
|
||||
|
||||
|
||||
PRUnichar*
|
||||
nsXPIDLString::Copy(const PRUnichar* aString)
|
||||
{
|
||||
NS_ASSERTION(aString, "null ptr");
|
||||
if (! aString)
|
||||
return 0;
|
||||
|
||||
PRInt32 len = 0;
|
||||
|
||||
{
|
||||
const PRUnichar* p = aString;
|
||||
while (*p++)
|
||||
len++;
|
||||
}
|
||||
|
||||
PRUnichar* result = XPIDL_STRING_ALLOC(len + 1);
|
||||
if (result) {
|
||||
PRUnichar* q = result;
|
||||
while (*aString) {
|
||||
*q = *aString;
|
||||
q++;
|
||||
aString++;
|
||||
}
|
||||
*q = '\0';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PRUnichar**
|
||||
nsXPIDLString::StartAssignmentByValue()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
mBuf = 0;
|
||||
mBufOwner = PR_TRUE;
|
||||
return &mBuf;
|
||||
}
|
||||
|
||||
|
||||
const PRUnichar**
|
||||
nsXPIDLString::StartAssignmentByReference()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
mBuf = 0;
|
||||
mBufOwner = PR_FALSE;
|
||||
return (const PRUnichar**) &mBuf;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsXPIDLCString
|
||||
|
||||
nsXPIDLCString::nsXPIDLCString()
|
||||
: mBufOwner(PR_FALSE),
|
||||
mBuf(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
nsXPIDLCString::~nsXPIDLCString()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
}
|
||||
|
||||
|
||||
nsXPIDLCString::operator const char*()
|
||||
{
|
||||
return mBuf;
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
nsXPIDLCString::Copy(const char* aCString)
|
||||
{
|
||||
NS_ASSERTION(aCString, "null ptr");
|
||||
if (! aCString)
|
||||
return 0;
|
||||
|
||||
PRInt32 len = PL_strlen(aCString);
|
||||
char* result = XPIDL_CSTRING_ALLOC(len + 1);
|
||||
if (result)
|
||||
PL_strcpy(result, aCString);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
char**
|
||||
nsXPIDLCString::StartAssignmentByValue()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
mBuf = 0;
|
||||
mBufOwner = PR_TRUE;
|
||||
return &mBuf;
|
||||
}
|
||||
|
||||
|
||||
const char**
|
||||
nsXPIDLCString::StartAssignmentByReference()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
mBuf = 0;
|
||||
mBufOwner = PR_FALSE;
|
||||
return (const char**) &mBuf;
|
||||
}
|
||||
|
||||
|
||||
300
mozilla/string/obsolete/nsXPIDLString.h
Normal file
300
mozilla/string/obsolete/nsXPIDLString.h
Normal file
@@ -0,0 +1,300 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
A set of string wrapper classes that ease transition to use of XPIDL
|
||||
interfaces. nsXPIDLString and nsXPIDLCString are to XPIDL `wstring'
|
||||
and `string' out params as nsCOMPtr is to generic XPCOM interface
|
||||
pointers. They help you deal with object ownership.
|
||||
|
||||
Consider the following interface:
|
||||
|
||||
interface nsIFoo {
|
||||
attribute string Bar;
|
||||
};
|
||||
|
||||
This will generate the following C++ header file:
|
||||
|
||||
class nsIFoo {
|
||||
NS_IMETHOD SetBar(const PRUnichar* aValue);
|
||||
NS_IMETHOD GetBar(PRUnichar* *aValue);
|
||||
};
|
||||
|
||||
The GetBar() method will allocate a copy of the nsIFoo object's
|
||||
"bar" attribute, and leave you to deal with freeing it:
|
||||
|
||||
nsIFoo* aFoo; // assume we get this somehow
|
||||
PRUnichar* bar;
|
||||
aFoo->GetFoo(&bar);
|
||||
// Use bar here...
|
||||
printf("bar is %s!\n", bar);
|
||||
delete[] bar;
|
||||
|
||||
(Strictly speaking, the `delete[] bar' should use the proper XPCOM
|
||||
de-allocator; we'll ignore that for now.)
|
||||
|
||||
This makes your life harder, because you need to convolute your code
|
||||
to ensure that you don't leak `bar'.
|
||||
|
||||
Enter nsXPIDLString, which manages the ownership of the allocated
|
||||
string, and automatically destroys it when the nsXPIDLString goes
|
||||
out of scope:
|
||||
|
||||
nsIFoo* aFoo;
|
||||
nsXPIDLString bar;
|
||||
aFoo->GetFoo( getter_Copies(bar) );
|
||||
// Use bar here...
|
||||
printf("bar is %s!\n", (const char*) bar);
|
||||
// no need to remember to delete[].
|
||||
|
||||
Like nsCOMPtr, nsXPIDLString uses some syntactic sugar to make it
|
||||
painfully clear exactly what the code expects. You need to wrap an
|
||||
nsXPIDLString object with either `getter_Copies()' or
|
||||
`getter_Shares()' before passing it to a getter: these tell the
|
||||
nsXPIDLString how ownership is being handled.
|
||||
|
||||
In the case of `getter_Copies()', the callee is allocating a copy
|
||||
(which is usually the case). In the case of `getter_Shares()', the
|
||||
callee is returning a const reference to `the real deal' (this can
|
||||
be done using the [shared] attribute in XPIDL).
|
||||
|
||||
*/
|
||||
|
||||
#ifndef nsXPIDLString_h__
|
||||
#define nsXPIDLString_h__
|
||||
|
||||
#include "nsCom.h"
|
||||
#include "prtypes.h"
|
||||
|
||||
#ifndef __PRUNICHAR__
|
||||
#define __PRUNICHAR__
|
||||
typedef PRUint16 PRUnichar;
|
||||
#endif /* __PRUNICHAR__ */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsXPIDLString
|
||||
//
|
||||
// A wrapper for Unicode strings. With the |getter_Copies()| and
|
||||
// |getter_Shares()| helper functions, this can be used instead of
|
||||
// the "naked" |PRUnichar*| interface for |wstring| parameters in
|
||||
// XPIDL interfaces.
|
||||
//
|
||||
|
||||
class NS_COM nsXPIDLString {
|
||||
private:
|
||||
PRUnichar* mBuf;
|
||||
PRBool mBufOwner;
|
||||
|
||||
PRUnichar** StartAssignmentByValue();
|
||||
const PRUnichar** StartAssignmentByReference();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct a new, uninitialized wrapper for a Unicode string.
|
||||
*/
|
||||
nsXPIDLString();
|
||||
|
||||
virtual ~nsXPIDLString();
|
||||
|
||||
/**
|
||||
* Return a reference to the immutable Unicode string.
|
||||
*/
|
||||
operator const PRUnichar*();
|
||||
|
||||
/**
|
||||
* Make a copy of the Unicode string. Use this function in the
|
||||
* callee to ensure that the correct memory allocator is used.
|
||||
*/
|
||||
static PRUnichar* Copy(const PRUnichar* aString);
|
||||
|
||||
// A helper class for assignment-by-value. This class is an
|
||||
// implementation detail and should not be considered part of the
|
||||
// public interface.
|
||||
class NS_COM GetterCopies {
|
||||
private:
|
||||
nsXPIDLString& mXPIDLString;
|
||||
|
||||
public:
|
||||
GetterCopies(nsXPIDLString& aXPIDLString)
|
||||
: mXPIDLString(aXPIDLString) {}
|
||||
|
||||
operator PRUnichar**() {
|
||||
return mXPIDLString.StartAssignmentByValue();
|
||||
}
|
||||
|
||||
friend GetterCopies getter_Copies(nsXPIDLString& aXPIDLString);
|
||||
};
|
||||
|
||||
friend class GetterCopies;
|
||||
|
||||
// A helper class for assignment-by-reference. This class is an
|
||||
// implementation detail and should not be considered part of the
|
||||
// public interface.
|
||||
class NS_COM GetterShares {
|
||||
private:
|
||||
nsXPIDLString& mXPIDLString;
|
||||
|
||||
public:
|
||||
GetterShares(nsXPIDLString& aXPIDLString)
|
||||
: mXPIDLString(aXPIDLString) {}
|
||||
|
||||
operator const PRUnichar**() {
|
||||
return mXPIDLString.StartAssignmentByReference();
|
||||
}
|
||||
|
||||
friend GetterShares getter_Shares(nsXPIDLString& aXPIDLString);
|
||||
};
|
||||
|
||||
friend class GetterShares;
|
||||
|
||||
private:
|
||||
// not to be implemented
|
||||
nsXPIDLString(nsXPIDLString& /* aXPIDLString */) {}
|
||||
nsXPIDLString& operator =(nsXPIDLString& /* aXPIDLString */) { return *this; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Use this function to "wrap" the nsXPIDLString object that is to
|
||||
* receive an |out| value.
|
||||
*/
|
||||
inline nsXPIDLString::GetterCopies
|
||||
getter_Copies(nsXPIDLString& aXPIDLString)
|
||||
{
|
||||
return nsXPIDLString::GetterCopies(aXPIDLString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this function to "wrap" the nsXPIDLString object that is to
|
||||
* receive a |[shared] out| value.
|
||||
*/
|
||||
inline nsXPIDLString::GetterShares
|
||||
getter_Shares(nsXPIDLString& aXPIDLString)
|
||||
{
|
||||
return nsXPIDLString::GetterShares(aXPIDLString);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsXPIDLCString
|
||||
//
|
||||
// A wrapper for Unicode strings. With the |getter_Copies()| and
|
||||
// |getter_Shares()| helper functions, this can be used instead of
|
||||
// the "naked" |char*| interface for |string| parameters in XPIDL
|
||||
// interfaces.
|
||||
//
|
||||
|
||||
class NS_COM nsXPIDLCString {
|
||||
private:
|
||||
char* mBuf;
|
||||
PRBool mBufOwner;
|
||||
|
||||
char** StartAssignmentByValue();
|
||||
const char** StartAssignmentByReference();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct a new, uninitialized wrapper for a single-byte string.
|
||||
*/
|
||||
nsXPIDLCString();
|
||||
|
||||
virtual ~nsXPIDLCString();
|
||||
|
||||
/**
|
||||
* Return a reference to the immutable single-byte string.
|
||||
*/
|
||||
operator const char*();
|
||||
|
||||
/**
|
||||
* Make a copy of the single-byte string. Use this function in the
|
||||
* callee to ensure that the correct memory allocator is used.
|
||||
*/
|
||||
static char* Copy(const char* aString);
|
||||
|
||||
// A helper class for assignment-by-value. This class is an
|
||||
// implementation detail and should not be considered part of the
|
||||
// public interface.
|
||||
class NS_COM GetterCopies {
|
||||
private:
|
||||
nsXPIDLCString& mXPIDLString;
|
||||
|
||||
public:
|
||||
GetterCopies(nsXPIDLCString& aXPIDLString)
|
||||
: mXPIDLString(aXPIDLString) {}
|
||||
|
||||
operator char**() {
|
||||
return mXPIDLString.StartAssignmentByValue();
|
||||
}
|
||||
|
||||
friend GetterCopies getter_Copies(nsXPIDLCString& aXPIDLString);
|
||||
};
|
||||
|
||||
friend class GetterCopies;
|
||||
|
||||
// A helper class for assignment-by-reference. This class is an
|
||||
// implementation detail and should not be considered part of the
|
||||
// public interface.
|
||||
class NS_COM GetterShares {
|
||||
private:
|
||||
nsXPIDLCString& mXPIDLString;
|
||||
|
||||
public:
|
||||
GetterShares(nsXPIDLCString& aXPIDLString)
|
||||
: mXPIDLString(aXPIDLString) {}
|
||||
|
||||
operator const char**() {
|
||||
return mXPIDLString.StartAssignmentByReference();
|
||||
}
|
||||
|
||||
friend GetterShares getter_Shares(nsXPIDLCString& aXPIDLString);
|
||||
};
|
||||
|
||||
friend class GetterShares;
|
||||
|
||||
private:
|
||||
// not to be implemented
|
||||
nsXPIDLCString(nsXPIDLCString& /* aXPIDLString */) {}
|
||||
nsXPIDLCString& operator =(nsXPIDLCString& /* aXPIDLCString */) { return *this; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Use this function to "wrap" the nsXPIDLCString object that is to
|
||||
* receive an |out| value.
|
||||
*/
|
||||
inline nsXPIDLCString::GetterCopies
|
||||
getter_Copies(nsXPIDLCString& aXPIDLString)
|
||||
{
|
||||
return nsXPIDLCString::GetterCopies(aXPIDLString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Use this function to "wrap" the nsXPIDLCString object that is to
|
||||
* receive a |[shared] out| value.
|
||||
*/
|
||||
inline nsXPIDLCString::GetterShares
|
||||
getter_Shares(nsXPIDLCString& aXPIDLString)
|
||||
{
|
||||
return nsXPIDLCString::GetterShares(aXPIDLString);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // nsXPIDLString_h__
|
||||
41
mozilla/xpcom/Makefile.in
Normal file
41
mozilla/xpcom/Makefile.in
Normal file
@@ -0,0 +1,41 @@
|
||||
#!gmake
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ..
|
||||
topsrcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
srcdir = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS= typelib \
|
||||
base \
|
||||
ds \
|
||||
io \
|
||||
components \
|
||||
threads \
|
||||
reflect \
|
||||
proxy \
|
||||
build \
|
||||
tools \
|
||||
sample \
|
||||
$(NULL)
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += tests
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
6027
mozilla/xpcom/base/IIDS.h
Normal file
6027
mozilla/xpcom/base/IIDS.h
Normal file
File diff suppressed because it is too large
Load Diff
12
mozilla/xpcom/base/MANIFEST
Normal file
12
mozilla/xpcom/base/MANIFEST
Normal file
@@ -0,0 +1,12 @@
|
||||
nsAgg.h
|
||||
nsIAllocator.h
|
||||
nsCOMPtr.h
|
||||
nsCom.h
|
||||
nsDebug.h
|
||||
nsError.h
|
||||
nsID.h
|
||||
nsIID.h
|
||||
nsIPtr.h
|
||||
nsISupportsUtils.h
|
||||
nsTraceRefcnt.h
|
||||
nscore.h
|
||||
2
mozilla/xpcom/base/MANIFEST_IDL
Normal file
2
mozilla/xpcom/base/MANIFEST_IDL
Normal file
@@ -0,0 +1,2 @@
|
||||
nsISupports.idl
|
||||
nsrootidl.idl
|
||||
73
mozilla/xpcom/base/Makefile.in
Normal file
73
mozilla/xpcom/base/Makefile.in
Normal file
@@ -0,0 +1,73 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
LIBRARY_NAME = xpcombase_s
|
||||
|
||||
MODULE = xpcom
|
||||
XPIDL_MODULE = xpcom_base
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsrootidl.idl \
|
||||
nsISupports.idl \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsAllocator.cpp \
|
||||
nsDebug.cpp \
|
||||
nsTraceRefcnt.cpp \
|
||||
nsCOMPtr.cpp \
|
||||
nsID.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
nsAgg.h \
|
||||
nsIAllocator.h \
|
||||
nsCOMPtr.h \
|
||||
nsCom.h \
|
||||
nsDebug.h \
|
||||
nsError.h \
|
||||
nsID.h \
|
||||
nsIID.h \
|
||||
nsIPtr.h \
|
||||
nsISupportsUtils.h \
|
||||
nsTraceRefcnt.h \
|
||||
nscore.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
DEFINES += -D_IMPL_NS_COM
|
||||
|
||||
REQUIRES = xpcom
|
||||
|
||||
MKSHLIB :=
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
override NO_SHARED_LIB=1
|
||||
override NO_STATIC_LIB=
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
81
mozilla/xpcom/base/makefile.win
Normal file
81
mozilla/xpcom/base/makefile.win
Normal file
@@ -0,0 +1,81 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
DEPTH=..\..
|
||||
MODULE = xpcom
|
||||
|
||||
################################################################################
|
||||
## exports
|
||||
|
||||
EXPORTS = \
|
||||
nsAgg.h \
|
||||
nsIAllocator.h \
|
||||
nsCOMPtr.h \
|
||||
nsCom.h \
|
||||
nsDebug.h \
|
||||
nsError.h \
|
||||
nsID.h \
|
||||
nsIID.h \
|
||||
nsIPtr.h \
|
||||
nsISupportsUtils.h \
|
||||
nsTraceRefcnt.h \
|
||||
nscore.h \
|
||||
$(NULL)
|
||||
|
||||
XPIDL_MODULE = xpcom_base
|
||||
|
||||
XPIDLSRCS = \
|
||||
.\nsrootidl.idl \
|
||||
.\nsISupports.idl \
|
||||
$(NULL)
|
||||
|
||||
################################################################################
|
||||
## library
|
||||
|
||||
#MAKE_OBJ_TYPE = DLL
|
||||
#LIBNAME = .\$(OBJDIR)\xpcombase
|
||||
#DLL = $(LIBNAME).dll
|
||||
|
||||
LIBRARY_NAME=xpcombase_s
|
||||
|
||||
LINCS = \
|
||||
-I$(PUBLIC)\xpcom \
|
||||
$(NULL)
|
||||
|
||||
LCFLAGS = -D_IMPL_NS_COM -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
CPP_OBJS = \
|
||||
.\$(OBJDIR)\nsDebug.obj \
|
||||
.\$(OBJDIR)\nsAllocator.obj \
|
||||
.\$(OBJDIR)\nsCOMPtr.obj \
|
||||
.\$(OBJDIR)\nsID.obj \
|
||||
.\$(OBJDIR)\nsTraceRefcnt.obj \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
#libs:: $(DLL)
|
||||
# $(MAKE_INSTALL) $(LIBNAME).$(DLL_SUFFIX) $(DIST)\bin
|
||||
# $(MAKE_INSTALL) $(LIBNAME).$(LIB_SUFFIX) $(DIST)\lib
|
||||
|
||||
libs:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
170
mozilla/xpcom/base/nsAgg.h
Normal file
170
mozilla/xpcom/base/nsAgg.h
Normal file
@@ -0,0 +1,170 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsAgg_h___
|
||||
#define nsAgg_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
/**
|
||||
* Outer objects can implement nsIOuter if they choose, allowing them to
|
||||
* get notification if their inner objects (children) are effectively freed.
|
||||
* This allows them to reset any state associated with the inner object and
|
||||
* potentially unload it.
|
||||
*/
|
||||
class nsIOuter : public nsISupports {
|
||||
public:
|
||||
|
||||
/**
|
||||
* This method is called whenever an inner object's refcount is about to
|
||||
* become zero and the inner object should be released by the outer. This
|
||||
* allows the outer to clean up any state associated with the inner and
|
||||
* potentially unload the inner object. This method should call
|
||||
* inner->Release().
|
||||
*/
|
||||
NS_IMETHOD
|
||||
ReleaseInner(nsISupports* inner) = 0;
|
||||
|
||||
};
|
||||
|
||||
#define NS_IOUTER_IID \
|
||||
{ /* ea0bf9f0-3d67-11d2-8163-006008119d7a */ \
|
||||
0xea0bf9f0, \
|
||||
0x3d67, \
|
||||
0x11d2, \
|
||||
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Put this in your class's declaration:
|
||||
#define NS_DECL_AGGREGATED \
|
||||
NS_DECL_ISUPPORTS \
|
||||
\
|
||||
protected: \
|
||||
\
|
||||
/* You must implement this operation instead of the nsISupports */ \
|
||||
/* methods if you inherit from nsAggregated. */ \
|
||||
NS_IMETHOD \
|
||||
AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr); \
|
||||
\
|
||||
class Internal : public nsISupports { \
|
||||
public: \
|
||||
\
|
||||
Internal() {} \
|
||||
\
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, \
|
||||
void** aInstancePtr); \
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void); \
|
||||
NS_IMETHOD_(nsrefcnt) Release(void); \
|
||||
\
|
||||
}; \
|
||||
\
|
||||
friend class Internal; \
|
||||
\
|
||||
nsISupports* fOuter; \
|
||||
Internal fAggregated; \
|
||||
\
|
||||
nsISupports* GetInner(void) { return &fAggregated; } \
|
||||
\
|
||||
public: \
|
||||
|
||||
|
||||
// Put this in your class's constructor:
|
||||
#define NS_INIT_AGGREGATED(outer) \
|
||||
PR_BEGIN_MACRO \
|
||||
NS_INIT_REFCNT(); \
|
||||
fOuter = outer; \
|
||||
PR_END_MACRO
|
||||
|
||||
|
||||
// Put this in your class's implementation file:
|
||||
#define NS_IMPL_AGGREGATED(_class) \
|
||||
NS_IMETHODIMP \
|
||||
_class::QueryInterface(const nsIID& aIID, void** aInstancePtr) \
|
||||
{ \
|
||||
/* try our own interfaces first before delegating to outer */ \
|
||||
nsresult rslt = AggregatedQueryInterface(aIID, aInstancePtr); \
|
||||
if (rslt != NS_OK && fOuter) \
|
||||
return fOuter->QueryInterface(aIID, aInstancePtr); \
|
||||
else \
|
||||
return rslt; \
|
||||
} \
|
||||
\
|
||||
NS_IMETHODIMP_(nsrefcnt) \
|
||||
_class::AddRef(void) \
|
||||
{ \
|
||||
++mRefCnt; /* keep track of our refcount as well as outer's */ \
|
||||
if (fOuter) \
|
||||
return NS_ADDREF(fOuter); \
|
||||
else \
|
||||
return mRefCnt; \
|
||||
} \
|
||||
\
|
||||
NS_IMETHODIMP_(nsrefcnt) \
|
||||
_class::Release(void) \
|
||||
{ \
|
||||
if (fOuter) { \
|
||||
nsISupports* outer = fOuter; /* in case we release ourself */ \
|
||||
nsIOuter* outerIntf; \
|
||||
static NS_DEFINE_IID(kIOuterIID, NS_IOUTER_IID); \
|
||||
if (mRefCnt == 1 && \
|
||||
outer->QueryInterface(kIOuterIID, \
|
||||
(void**)&outerIntf) == NS_OK) { \
|
||||
outerIntf->ReleaseInner(GetInner()); \
|
||||
outerIntf->Release(); \
|
||||
} \
|
||||
else \
|
||||
--mRefCnt; /* keep track of our refcount as well as outer's */ \
|
||||
return outer->Release(); \
|
||||
} \
|
||||
else { \
|
||||
if (--mRefCnt == 0) { \
|
||||
delete this; \
|
||||
return 0; \
|
||||
} \
|
||||
return mRefCnt; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
NS_IMETHODIMP \
|
||||
_class::Internal::QueryInterface(const nsIID& aIID, void** aInstancePtr) \
|
||||
{ \
|
||||
_class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
|
||||
return agg->AggregatedQueryInterface(aIID, aInstancePtr); \
|
||||
} \
|
||||
\
|
||||
NS_IMETHODIMP_(nsrefcnt) \
|
||||
_class::Internal::AddRef(void) \
|
||||
{ \
|
||||
_class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
|
||||
return ++agg->mRefCnt; \
|
||||
} \
|
||||
\
|
||||
NS_IMETHODIMP_(nsrefcnt) \
|
||||
_class::Internal::Release(void) \
|
||||
{ \
|
||||
_class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
|
||||
if (--agg->mRefCnt == 0) { \
|
||||
delete agg; \
|
||||
return 0; \
|
||||
} \
|
||||
return agg->mRefCnt; \
|
||||
} \
|
||||
|
||||
#endif /* nsAgg_h___ */
|
||||
179
mozilla/xpcom/base/nsAllocator.cpp
Normal file
179
mozilla/xpcom/base/nsAllocator.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of nsIAllocator using NSPR
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "nsAllocator.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include <string.h> /* for memcpy */
|
||||
|
||||
nsAllocatorImpl::nsAllocatorImpl(nsISupports* outer)
|
||||
{
|
||||
NS_INIT_AGGREGATED(outer);
|
||||
}
|
||||
|
||||
nsAllocatorImpl::~nsAllocatorImpl(void)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_AGGREGATED(nsAllocatorImpl);
|
||||
|
||||
NS_METHOD
|
||||
nsAllocatorImpl::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (aIID.Equals(nsIAllocator::GetIID()) ||
|
||||
aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID())) {
|
||||
*aInstancePtr = (void*) this;
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsAllocatorImpl::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
|
||||
{
|
||||
if (outer && !aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID()))
|
||||
return NS_NOINTERFACE; // XXX right error?
|
||||
nsAllocatorImpl* mm = new nsAllocatorImpl(outer);
|
||||
if (mm == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mm->AddRef();
|
||||
if (aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID()))
|
||||
*aInstancePtr = mm->GetInner();
|
||||
else
|
||||
*aInstancePtr = mm;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_METHOD_(void*)
|
||||
nsAllocatorImpl::Alloc(PRUint32 size)
|
||||
{
|
||||
return PR_Malloc(size);
|
||||
}
|
||||
|
||||
NS_METHOD_(void*)
|
||||
nsAllocatorImpl::Realloc(void* ptr, PRUint32 size)
|
||||
{
|
||||
return PR_Realloc(ptr, size);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsAllocatorImpl::Free(void* ptr)
|
||||
{
|
||||
PR_Free(ptr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsAllocatorImpl::HeapMinimize(void)
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
// This used to live in the memory allocators no Mac, but does no more
|
||||
// Needs to be hooked up in the new world.
|
||||
// CallCacheFlushers(0x7fffffff);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#if 0
|
||||
nsAllocatorFactory::nsAllocatorFactory(void)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsAllocatorFactory::~nsAllocatorFactory(void)
|
||||
{
|
||||
}
|
||||
|
||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
||||
NS_IMPL_ISUPPORTS(nsAllocatorFactory, kIFactoryIID);
|
||||
|
||||
NS_METHOD
|
||||
nsAllocatorFactory::CreateInstance(nsISupports *aOuter,
|
||||
REFNSIID aIID,
|
||||
void **aResult)
|
||||
{
|
||||
return nsAllocatorImpl::Create(aOuter, aIID, aResult);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsAllocatorFactory::LockFactory(PRBool aLock)
|
||||
{
|
||||
return NS_OK; // XXX what?
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* Public shortcuts to the shared allocator's methods
|
||||
* (all these methods are class statics)
|
||||
*/
|
||||
|
||||
// public:
|
||||
void* nsAllocator::Alloc(PRUint32 size)
|
||||
{
|
||||
if(!EnsureAllocator()) return NULL;
|
||||
return mAllocator->Alloc(size);
|
||||
}
|
||||
|
||||
void* nsAllocator::Realloc(void* ptr, PRUint32 size)
|
||||
{
|
||||
if(!EnsureAllocator()) return NULL;
|
||||
return mAllocator->Realloc(ptr, size);
|
||||
}
|
||||
|
||||
void nsAllocator::Free(void* ptr)
|
||||
{
|
||||
if(!EnsureAllocator()) return;
|
||||
mAllocator->Free(ptr);
|
||||
}
|
||||
|
||||
void nsAllocator::HeapMinimize()
|
||||
{
|
||||
if(!EnsureAllocator()) return;
|
||||
mAllocator->HeapMinimize();
|
||||
}
|
||||
|
||||
void* nsAllocator::Clone(const void* ptr, PRUint32 size)
|
||||
{
|
||||
if(!ptr || !EnsureAllocator()) return NULL;
|
||||
void* p = mAllocator->Alloc(size);
|
||||
if(p) memcpy(p, ptr, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
// private:
|
||||
|
||||
nsIAllocator* nsAllocator::mAllocator = NULL;
|
||||
|
||||
PRBool nsAllocator::FetchAllocator()
|
||||
{
|
||||
nsAllocatorImpl::Create(NULL, nsIAllocator::GetIID(), (void**)&mAllocator);
|
||||
NS_ASSERTION(mAllocator, "failed to get Allocator!");
|
||||
return (PRBool) mAllocator;
|
||||
}
|
||||
92
mozilla/xpcom/base/nsAllocator.h
Normal file
92
mozilla/xpcom/base/nsAllocator.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of nsIAllocator using NSPR
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef nsAllocator_h__
|
||||
#define nsAllocator_h__
|
||||
|
||||
#include "nsIAllocator.h"
|
||||
#include "prmem.h"
|
||||
#include "nsAgg.h"
|
||||
#include "nsIFactory.h"
|
||||
|
||||
class nsAllocatorImpl : public nsIAllocator {
|
||||
public:
|
||||
static const nsCID& CID() { static nsCID cid = NS_ALLOCATOR_CID; return cid; }
|
||||
|
||||
/**
|
||||
* Allocates a block of memory of a particular size.
|
||||
*
|
||||
* @param size - the size of the block to allocate
|
||||
* @result the block of memory
|
||||
*/
|
||||
NS_IMETHOD_(void*) Alloc(PRUint32 size);
|
||||
|
||||
/**
|
||||
* Reallocates a block of memory to a new size.
|
||||
*
|
||||
* @param ptr - the block of memory to reallocate
|
||||
* @param size - the new size
|
||||
* @result the rellocated block of memory
|
||||
*/
|
||||
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size);
|
||||
|
||||
/**
|
||||
* Frees a block of memory.
|
||||
*
|
||||
* @param ptr - the block of memory to free
|
||||
*/
|
||||
NS_IMETHOD Free(void* ptr);
|
||||
|
||||
/**
|
||||
* Attempts to shrink the heap.
|
||||
*/
|
||||
NS_IMETHOD HeapMinimize(void);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsAllocatorImpl(nsISupports* outer);
|
||||
virtual ~nsAllocatorImpl(void);
|
||||
|
||||
NS_DECL_AGGREGATED
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#if 0
|
||||
class nsAllocatorFactory : public nsIFactory {
|
||||
public:
|
||||
NS_IMETHOD CreateInstance(nsISupports *aOuter,
|
||||
REFNSIID aIID,
|
||||
void **aResult);
|
||||
|
||||
NS_IMETHOD LockFactory(PRBool aLock);
|
||||
|
||||
nsAllocatorFactory(void);
|
||||
virtual ~nsAllocatorFactory(void);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#endif // nsAllocator_h__
|
||||
65
mozilla/xpcom/base/nsCOMPtr.cpp
Normal file
65
mozilla/xpcom/base/nsCOMPtr.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#ifdef NSCAP_FEATURE_FACTOR_DESTRUCTOR
|
||||
nsCOMPtr_base::~nsCOMPtr_base()
|
||||
{
|
||||
if ( mRawPtr )
|
||||
NSCAP_RELEASE(mRawPtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsCOMPtr_base::assign_with_AddRef( nsISupports* rawPtr )
|
||||
{
|
||||
if ( rawPtr )
|
||||
NSCAP_ADDREF(rawPtr);
|
||||
if ( mRawPtr )
|
||||
NSCAP_RELEASE(mRawPtr);
|
||||
mRawPtr = rawPtr;
|
||||
}
|
||||
|
||||
void
|
||||
nsCOMPtr_base::assign_with_QueryInterface( nsISupports* rawPtr, const nsIID& iid, nsresult* result )
|
||||
{
|
||||
nsresult status = NS_ERROR_NULL_POINTER;
|
||||
if ( !rawPtr || !NS_SUCCEEDED( status = rawPtr->QueryInterface(iid, NSCAP_REINTERPRET_CAST(void**, &rawPtr)) ) )
|
||||
rawPtr = 0;
|
||||
|
||||
if ( mRawPtr )
|
||||
NSCAP_RELEASE(mRawPtr);
|
||||
|
||||
mRawPtr = rawPtr;
|
||||
|
||||
if ( result )
|
||||
*result = status;
|
||||
}
|
||||
|
||||
void**
|
||||
nsCOMPtr_base::begin_assignment()
|
||||
{
|
||||
if ( mRawPtr )
|
||||
{
|
||||
NSCAP_RELEASE(mRawPtr);
|
||||
mRawPtr = 0;
|
||||
}
|
||||
|
||||
return NSCAP_REINTERPRET_CAST(void**, &mRawPtr);
|
||||
}
|
||||
732
mozilla/xpcom/base/nsCOMPtr.h
Normal file
732
mozilla/xpcom/base/nsCOMPtr.h
Normal file
@@ -0,0 +1,732 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsCOMPtr_h___
|
||||
#define nsCOMPtr_h___
|
||||
|
||||
|
||||
|
||||
// Wrapping includes can speed up compiles (see "Large Scale C++ Software Design")
|
||||
#ifndef nsDebug_h___
|
||||
#include "nsDebug.h"
|
||||
// for |NS_PRECONDITION|
|
||||
#endif
|
||||
|
||||
#ifndef nsISupports_h___
|
||||
#include "nsISupports.h"
|
||||
// for |nsresult|, |NS_ADDREF|, et al
|
||||
#endif
|
||||
|
||||
/*
|
||||
Public things defined in this file:
|
||||
|
||||
T* rawTptr;
|
||||
class nsCOMPtr<T> nsCOMPtr<T> smartTptr;
|
||||
|
||||
null_nsCOMPtr() smartTptr = null_nsCOMPtr();
|
||||
|
||||
do_QueryInterface( nsISupports* ) smartTptr = do_QueryInterface(other_ptr);
|
||||
do_QueryInterface( nsISupports*, nsresult* ) smartTptr = do_QueryInterface(other_ptr, &status);
|
||||
|
||||
dont_QueryInterface( T* ) smartTptr = dont_QueryInterface(rawTptr);
|
||||
|
||||
getter_AddRefs( nsCOMPtr<T>& )
|
||||
getter_AddRefs( T* )
|
||||
dont_AddRef( T* )
|
||||
|
||||
CallQueryInterface( nsISupports*, T** )
|
||||
CallQueryInterface( nsISupports*, nsCOMPtr<T>* )
|
||||
*/
|
||||
|
||||
/*
|
||||
Having problems?
|
||||
|
||||
See the User Manual at:
|
||||
<http://www.meer.net/ScottCollins/doc/nsCOMPtr.html>, or
|
||||
<http://www.mozilla.org/projects/xpcom/nsCOMPtr.html>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
TO DO...
|
||||
|
||||
+ Improve internal documentation
|
||||
+ mention *&
|
||||
+ alternatives for comparison
|
||||
+ do_QueryInterface
|
||||
*/
|
||||
|
||||
/*
|
||||
WARNING:
|
||||
This file defines several macros for internal use only. These macros begin with the
|
||||
prefix |NSCAP_|. Do not use these macros in your own code. They are for internal use
|
||||
only for cross-platform compatibility, and are subject to change without notice.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Set up some |#define|s to turn off a couple of troublesome C++ features.
|
||||
Interestingly, none of the compilers barf on template stuff. These are set up automatically
|
||||
by the autoconf system for all Unixes. (Temporarily, I hope) I have to define them
|
||||
myself for Mac and Windows.
|
||||
*/
|
||||
|
||||
// under Metrowerks (Mac), we don't have autoconf yet
|
||||
#ifdef __MWERKS__
|
||||
#define HAVE_CPP_USING
|
||||
#define HAVE_CPP_EXPLICIT
|
||||
#define HAVE_CPP_NEW_CASTS
|
||||
#define HAVE_CPP_BOOL
|
||||
#endif
|
||||
|
||||
// under VC++ (Windows), we don't have autoconf yet
|
||||
#ifdef _MSC_VER
|
||||
#define HAVE_CPP_EXPLICIT
|
||||
#define HAVE_CPP_USING
|
||||
#define HAVE_CPP_NEW_CASTS
|
||||
|
||||
#if (_MSC_VER<1100)
|
||||
// before 5.0, VC++ couldn't handle explicit
|
||||
#undef HAVE_CPP_EXPLICIT
|
||||
#elif (_MSC_VER==1100)
|
||||
// VC++5.0 has an internal compiler error (sometimes) without this
|
||||
#undef HAVE_CPP_USING
|
||||
#endif
|
||||
|
||||
#define NSCAP_FEATURE_INLINE_STARTASSIGNMENT
|
||||
// under VC++, we win by inlining StartAssignment
|
||||
#endif
|
||||
|
||||
#define NSCAP_FEATURE_ALLOW_RAW_POINTERS
|
||||
#define NSCAP_FEATURE_ALLOW_COMPARISONS
|
||||
#define NSCAP_FEATURE_FACTOR_DESTRUCTOR
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
#define NSCAP_FEATURE_TEST_DONTQUERY_CASES
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
If the compiler doesn't support |explicit|, we'll just make it go away, trusting
|
||||
that the builds under compilers that do have it will keep us on the straight and narrow.
|
||||
*/
|
||||
#ifndef HAVE_CPP_EXPLICIT
|
||||
#define explicit
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CPP_BOOL
|
||||
typedef bool NSCAP_BOOL;
|
||||
#else
|
||||
typedef PRBool NSCAP_BOOL;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CPP_NEW_CASTS
|
||||
#define NSCAP_STATIC_CAST(T,x) static_cast<T>(x)
|
||||
#define NSCAP_REINTERPRET_CAST(T,x) reinterpret_cast<T>(x)
|
||||
#else
|
||||
#define NSCAP_STATIC_CAST(T,x) ((T)(x))
|
||||
#define NSCAP_REINTERPRET_CAST(T,x) ((T)(x))
|
||||
#endif
|
||||
|
||||
#ifdef NSCAP_FEATURE_DEBUG_MACROS
|
||||
#define NSCAP_ADDREF(ptr) NS_ADDREF(ptr)
|
||||
#define NSCAP_RELEASE(ptr) NS_RELEASE(ptr)
|
||||
#else
|
||||
#define NSCAP_ADDREF(ptr) (ptr)->AddRef()
|
||||
#define NSCAP_RELEASE(ptr) (ptr)->Release()
|
||||
#endif
|
||||
|
||||
/*
|
||||
WARNING:
|
||||
VC++4.2 is very picky. To compile under VC++4.2, the classes must be defined
|
||||
in an order that satisfies:
|
||||
|
||||
nsDerivedSafe < nsCOMPtr
|
||||
nsDontAddRef < nsCOMPtr
|
||||
nsCOMPtr < nsGetterAddRefs
|
||||
|
||||
The other compilers probably won't complain, so please don't reorder these
|
||||
classes, on pain of breaking 4.2 compatibility.
|
||||
*/
|
||||
|
||||
|
||||
template <class T>
|
||||
class nsDerivedSafe : public T
|
||||
/*
|
||||
No client should ever see or have to type the name of this class. It is the
|
||||
artifact that makes it a compile-time error to call |AddRef| and |Release|
|
||||
on a |nsCOMPtr|. DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.
|
||||
|
||||
See |nsCOMPtr::operator->|, |nsCOMPtr::operator*|, et al.
|
||||
*/
|
||||
{
|
||||
private:
|
||||
#ifdef HAVE_CPP_USING
|
||||
using T::AddRef;
|
||||
using T::Release;
|
||||
#else
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
#endif
|
||||
|
||||
void operator delete( void*, size_t ); // NOT TO BE IMPLEMENTED
|
||||
// declaring |operator delete| private makes calling delete on an interface pointer a compile error
|
||||
|
||||
nsDerivedSafe<T>& operator=( const nsDerivedSafe<T>& ); // NOT TO BE IMPLEMENTED
|
||||
// you may not call |operator=()| through a dereferenced |nsCOMPtr|, because you'd get the wrong one
|
||||
};
|
||||
|
||||
#if !defined(HAVE_CPP_USING) && defined(NEED_CPP_UNUSED_IMPLEMENTATIONS)
|
||||
template <class T>
|
||||
nsrefcnt
|
||||
nsDerivedSafe<T>::AddRef()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
nsrefcnt
|
||||
nsDerivedSafe<T>::Release()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
struct nsDontQueryInterface
|
||||
/*
|
||||
...
|
||||
|
||||
DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |dont_QueryInterface()| instead.
|
||||
*/
|
||||
{
|
||||
explicit
|
||||
nsDontQueryInterface( T* aRawPtr )
|
||||
: mRawPtr(aRawPtr)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
T* mRawPtr;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
const nsDontQueryInterface<T>
|
||||
dont_QueryInterface( T* aRawPtr )
|
||||
{
|
||||
return nsDontQueryInterface<T>(aRawPtr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct nsQueryInterface
|
||||
/*
|
||||
...
|
||||
|
||||
DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |do_QueryInterface()| instead.
|
||||
*/
|
||||
{
|
||||
explicit
|
||||
nsQueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
|
||||
: mRawPtr(aRawPtr),
|
||||
mErrorPtr(error)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
nsISupports* mRawPtr;
|
||||
nsresult* mErrorPtr;
|
||||
};
|
||||
|
||||
inline
|
||||
const nsQueryInterface
|
||||
do_QueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
|
||||
{
|
||||
return nsQueryInterface(aRawPtr, error);
|
||||
}
|
||||
|
||||
#ifdef NSCAP_FEATURE_ALLOW_RAW_POINTERS
|
||||
|
||||
#define null_nsCOMPtr() (0)
|
||||
|
||||
#else
|
||||
|
||||
inline
|
||||
const nsQueryInterface
|
||||
null_nsCOMPtr()
|
||||
/*
|
||||
You can use this to assign |NULL| into an |nsCOMPtr|, e.g.,
|
||||
|
||||
myPtr = null_nsCOMPtr();
|
||||
*/
|
||||
{
|
||||
typedef nsISupports* nsISupports_Ptr;
|
||||
return nsQueryInterface(nsISupports_Ptr(0));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
struct nsDontAddRef
|
||||
/*
|
||||
...cooperates with |nsCOMPtr| to allow you to assign in a pointer _without_
|
||||
|AddRef|ing it. You would rarely use this directly, but rather through the
|
||||
machinery of |getter_AddRefs| in the argument list to functions that |AddRef|
|
||||
their results before returning them to the caller.
|
||||
|
||||
DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| or
|
||||
|dont_AddRef()| instead.
|
||||
|
||||
See also |getter_AddRefs()|, |dont_AddRef()|, and |class nsGetterAddRefs|.
|
||||
*/
|
||||
{
|
||||
explicit
|
||||
nsDontAddRef( T* aRawPtr )
|
||||
: mRawPtr(aRawPtr)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
T* mRawPtr;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
const nsDontAddRef<T>
|
||||
getter_AddRefs( T* aRawPtr )
|
||||
/*
|
||||
...makes typing easier, because it deduces the template type, e.g.,
|
||||
you write |dont_AddRef(fooP)| instead of |nsDontAddRef<IFoo>(fooP)|.
|
||||
*/
|
||||
{
|
||||
return nsDontAddRef<T>(aRawPtr);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
const nsDontAddRef<T>
|
||||
dont_AddRef( T* aRawPtr )
|
||||
{
|
||||
return nsDontAddRef<T>(aRawPtr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
class nsCOMPtr_base
|
||||
/*
|
||||
...factors implementation for all template versions of |nsCOMPtr|.
|
||||
*/
|
||||
{
|
||||
public:
|
||||
|
||||
nsCOMPtr_base( nsISupports* rawPtr = 0 )
|
||||
: mRawPtr(rawPtr)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
#ifdef NSCAP_FEATURE_FACTOR_DESTRUCTOR
|
||||
NS_EXPORT ~nsCOMPtr_base();
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
~nsCOMPtr_base()
|
||||
{
|
||||
if ( mRawPtr )
|
||||
NSCAP_RELEASE(mRawPtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_EXPORT void assign_with_AddRef( nsISupports* );
|
||||
NS_EXPORT void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* );
|
||||
NS_EXPORT void** begin_assignment();
|
||||
|
||||
protected:
|
||||
nsISupports* mRawPtr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
class nsCOMPtr : private nsCOMPtr_base
|
||||
/*
|
||||
...
|
||||
*/
|
||||
{
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
#if 0
|
||||
typedef nsDerivedSafe<T>* safe_ptr_t;
|
||||
typedef T* safe_ptr_t;
|
||||
#endif
|
||||
|
||||
#ifndef NSCAP_FEATURE_FACTOR_DESTRUCTOR
|
||||
~nsCOMPtr()
|
||||
{
|
||||
if ( mRawPtr )
|
||||
NSCAP_RELEASE(mRawPtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr()
|
||||
// : nsCOMPtr_base(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
nsCOMPtr( const nsQueryInterface& aSmartPtr )
|
||||
// : nsCOMPtr_base(0)
|
||||
{
|
||||
assign_with_QueryInterface(aSmartPtr.mRawPtr, nsCOMTypeInfo<T>::GetIID(), aSmartPtr.mErrorPtr);
|
||||
}
|
||||
|
||||
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
|
||||
void
|
||||
Assert_NoQueryNeeded()
|
||||
{
|
||||
if ( !mRawPtr )
|
||||
return;
|
||||
T* query_result = 0;
|
||||
nsresult status = CallQueryInterface(mRawPtr, &query_result);
|
||||
NS_ASSERTION(query_result == mRawPtr, "QueryInterface needed");
|
||||
if ( NS_SUCCEEDED(status) )
|
||||
NSCAP_RELEASE(query_result);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr( const nsDontAddRef<T>& aSmartPtr )
|
||||
: nsCOMPtr_base(aSmartPtr.mRawPtr)
|
||||
{
|
||||
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
|
||||
Assert_NoQueryNeeded();
|
||||
#endif
|
||||
}
|
||||
|
||||
nsCOMPtr( const nsDontQueryInterface<T>& aSmartPtr )
|
||||
: nsCOMPtr_base(aSmartPtr.mRawPtr)
|
||||
{
|
||||
if ( mRawPtr )
|
||||
NSCAP_ADDREF(mRawPtr);
|
||||
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
|
||||
Assert_NoQueryNeeded();
|
||||
#endif
|
||||
}
|
||||
|
||||
nsCOMPtr( const nsCOMPtr<T>& aSmartPtr )
|
||||
: nsCOMPtr_base(aSmartPtr.mRawPtr)
|
||||
{
|
||||
if ( mRawPtr )
|
||||
NSCAP_ADDREF(mRawPtr);
|
||||
}
|
||||
|
||||
#ifdef NSCAP_FEATURE_ALLOW_RAW_POINTERS
|
||||
nsCOMPtr( T* aRawPtr )
|
||||
: nsCOMPtr_base(aRawPtr)
|
||||
{
|
||||
if ( mRawPtr )
|
||||
NSCAP_ADDREF(mRawPtr);
|
||||
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
|
||||
Assert_NoQueryNeeded();
|
||||
#endif
|
||||
}
|
||||
|
||||
nsCOMPtr<T>&
|
||||
operator=( T* rhs )
|
||||
{
|
||||
assign_with_AddRef(rhs);
|
||||
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
|
||||
Assert_NoQueryNeeded();
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<T>&
|
||||
operator=( const nsQueryInterface& rhs )
|
||||
{
|
||||
assign_with_QueryInterface(rhs.mRawPtr, nsCOMTypeInfo<T>::GetIID(), rhs.mErrorPtr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsCOMPtr<T>&
|
||||
operator=( const nsDontAddRef<T>& rhs )
|
||||
{
|
||||
if ( mRawPtr )
|
||||
NSCAP_RELEASE(mRawPtr);
|
||||
mRawPtr = rhs.mRawPtr;
|
||||
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
|
||||
Assert_NoQueryNeeded();
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsCOMPtr<T>&
|
||||
operator=( const nsDontQueryInterface<T>& rhs )
|
||||
{
|
||||
assign_with_AddRef(rhs.mRawPtr);
|
||||
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
|
||||
Assert_NoQueryNeeded();
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsCOMPtr<T>&
|
||||
operator=( const nsCOMPtr<T>& rhs )
|
||||
{
|
||||
assign_with_AddRef(rhs.mRawPtr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsDerivedSafe<T>*
|
||||
get() const
|
||||
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
|
||||
{
|
||||
return NSCAP_REINTERPRET_CAST(nsDerivedSafe<T>*, mRawPtr);
|
||||
}
|
||||
|
||||
nsDerivedSafe<T>*
|
||||
operator->() const
|
||||
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
|
||||
{
|
||||
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator->().");
|
||||
return get();
|
||||
}
|
||||
|
||||
nsDerivedSafe<T>&
|
||||
operator*() const
|
||||
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
|
||||
{
|
||||
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator*().");
|
||||
return *get();
|
||||
}
|
||||
|
||||
operator nsDerivedSafe<T>*() const
|
||||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
#if 0
|
||||
private:
|
||||
friend class nsGetterAddRefs<T>;
|
||||
|
||||
/*
|
||||
In a perfect world, the following member function, |StartAssignment|, would be private.
|
||||
It is and should be only accessed by the closely related class |nsGetterAddRefs<T>|.
|
||||
|
||||
Unfortunately, some compilers---most notably VC++5.0---fail to grok the
|
||||
friend declaration above or in any alternate acceptable form. So, physically
|
||||
it will be public (until our compilers get smarter); but it is not to be
|
||||
considered part of the logical public interface.
|
||||
*/
|
||||
#endif
|
||||
|
||||
T**
|
||||
StartAssignment()
|
||||
{
|
||||
#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
|
||||
return NSCAP_REINTERPRET_CAST(T**, begin_assignment());
|
||||
#else
|
||||
if ( mRawPtr )
|
||||
NSCAP_RELEASE(mRawPtr);
|
||||
mRawPtr = 0;
|
||||
return NSCAP_REINTERPRET_CAST(T**, &mRawPtr);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
class nsGetterAddRefs
|
||||
/*
|
||||
...
|
||||
|
||||
This class is designed to be used for anonymous temporary objects in the
|
||||
argument list of calls that return COM interface pointers, e.g.,
|
||||
|
||||
nsCOMPtr<IFoo> fooP;
|
||||
...->QueryInterface(iid, getter_AddRefs(fooP))
|
||||
|
||||
DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| instead.
|
||||
|
||||
When initialized with a |nsCOMPtr|, as in the example above, it returns
|
||||
a |void**| (or |T**| if needed) that the outer call (|QueryInterface| in this
|
||||
case) can fill in.
|
||||
*/
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
nsGetterAddRefs( nsCOMPtr<T>& aSmartPtr )
|
||||
: mTargetSmartPtr(aSmartPtr)
|
||||
{
|
||||
// nothing else to do
|
||||
}
|
||||
|
||||
operator void**()
|
||||
{
|
||||
return NSCAP_REINTERPRET_CAST(void**, mTargetSmartPtr.StartAssignment());
|
||||
}
|
||||
|
||||
T*&
|
||||
operator*()
|
||||
{
|
||||
return *(mTargetSmartPtr.StartAssignment());
|
||||
}
|
||||
|
||||
operator T**()
|
||||
{
|
||||
return mTargetSmartPtr.StartAssignment();
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<T>& mTargetSmartPtr;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
nsGetterAddRefs<T>
|
||||
getter_AddRefs( nsCOMPtr<T>& aSmartPtr )
|
||||
/*
|
||||
Used around a |nsCOMPtr| when
|
||||
...makes the class |nsGetterAddRefs<T>| invisible.
|
||||
*/
|
||||
{
|
||||
return nsGetterAddRefs<T>(aSmartPtr);
|
||||
}
|
||||
|
||||
|
||||
#ifdef NSCAP_FEATURE_ALLOW_COMPARISONS
|
||||
|
||||
class NSCAP_Zero;
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
NSCAP_BOOL
|
||||
operator==( const nsCOMPtr<T>& lhs, const nsCOMPtr<U>& rhs )
|
||||
{
|
||||
return NSCAP_STATIC_CAST(const void*, lhs.get()) == NSCAP_STATIC_CAST(const void*, rhs.get());
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
NSCAP_BOOL
|
||||
operator==( const nsCOMPtr<T>& lhs, const U* rhs )
|
||||
{
|
||||
return NSCAP_STATIC_CAST(const void*, lhs.get()) == NSCAP_STATIC_CAST(const void*, rhs);
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
NSCAP_BOOL
|
||||
operator==( const U* lhs, const nsCOMPtr<T>& rhs )
|
||||
{
|
||||
return NSCAP_STATIC_CAST(const void*, lhs) == NSCAP_STATIC_CAST(const void*, rhs.get());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
NSCAP_BOOL
|
||||
operator==( const nsCOMPtr<T>& lhs, NSCAP_Zero* rhs )
|
||||
// specifically to allow |smartPtr == 0|
|
||||
{
|
||||
return NSCAP_STATIC_CAST(const void*, lhs.get()) == NSCAP_REINTERPRET_CAST(const void*, rhs);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
NSCAP_BOOL
|
||||
operator==( NSCAP_Zero* lhs, const nsCOMPtr<T>& rhs )
|
||||
// specifically to allow |0 == smartPtr|
|
||||
{
|
||||
return NSCAP_REINTERPRET_CAST(const void*, lhs) == NSCAP_STATIC_CAST(const void*, rhs.get());
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
NSCAP_BOOL
|
||||
operator!=( const nsCOMPtr<T>& lhs, const nsCOMPtr<U>& rhs )
|
||||
{
|
||||
return NSCAP_STATIC_CAST(const void*, lhs.get()) != NSCAP_STATIC_CAST(const void*, rhs.get());
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
NSCAP_BOOL
|
||||
operator!=( const nsCOMPtr<T>& lhs, const U* rhs )
|
||||
{
|
||||
return NSCAP_STATIC_CAST(const void*, lhs.get()) != NSCAP_STATIC_CAST(const void*, rhs);
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
NSCAP_BOOL
|
||||
operator!=( const U* lhs, const nsCOMPtr<T>& rhs )
|
||||
{
|
||||
return NSCAP_STATIC_CAST(const void*, lhs) != NSCAP_STATIC_CAST(const void*, rhs.get());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
NSCAP_BOOL
|
||||
operator!=( const nsCOMPtr<T>& lhs, NSCAP_Zero* rhs )
|
||||
// specifically to allow |smartPtr != 0|
|
||||
{
|
||||
return NSCAP_STATIC_CAST(const void*, lhs.get()) != NSCAP_REINTERPRET_CAST(const void*, rhs);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
NSCAP_BOOL
|
||||
operator!=( NSCAP_Zero* lhs, const nsCOMPtr<T>& rhs )
|
||||
// specifically to allow |0 != smartPtr|
|
||||
{
|
||||
return NSCAP_REINTERPRET_CAST(const void*, lhs) != NSCAP_STATIC_CAST(const void*, rhs.get());
|
||||
}
|
||||
|
||||
inline
|
||||
NSCAP_BOOL
|
||||
SameCOMIdentity( nsISupports* lhs, nsISupports* rhs )
|
||||
{
|
||||
return nsCOMPtr<nsISupports>( do_QueryInterface(lhs) ) == nsCOMPtr<nsISupports>( do_QueryInterface(rhs) );
|
||||
}
|
||||
|
||||
#endif // defined(NSCAP_FEATURE_ALLOW_COMPARISONS)
|
||||
|
||||
|
||||
template <class DestinationType>
|
||||
inline
|
||||
nsresult
|
||||
CallQueryInterface( nsISupports* aSource, nsCOMPtr<DestinationType>* aDestination )
|
||||
// a type-safe shortcut for calling the |QueryInterface()| member function
|
||||
{
|
||||
return CallQueryInterface(aSource, getter_AddRefs(*aDestination));
|
||||
// this calls the _other_ |CallQueryInterface|
|
||||
}
|
||||
|
||||
|
||||
#endif // !defined(nsCOMPtr_h___)
|
||||
229
mozilla/xpcom/base/nsCom.h
Normal file
229
mozilla/xpcom/base/nsCom.h
Normal file
@@ -0,0 +1,229 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsCom_h__
|
||||
#define nsCom_h__
|
||||
|
||||
/*
|
||||
* API Import/Export macros
|
||||
*/
|
||||
|
||||
#ifdef _IMPL_NS_COM
|
||||
#ifdef XP_PC
|
||||
#define NS_COM _declspec(dllexport)
|
||||
#elif defined(XP_MAC)
|
||||
#define NS_COM __declspec(export)
|
||||
#else /* !XP_PC */
|
||||
#define NS_COM
|
||||
#endif /* !XP_PC */
|
||||
#else /* !_IMPL_NS_COM */
|
||||
#ifdef XP_PC
|
||||
#define NS_COM _declspec(dllimport)
|
||||
#else /* !XP_PC */
|
||||
#define NS_COM
|
||||
#endif /* !XP_PC */
|
||||
#endif /* !_IMPL_NS_COM */
|
||||
|
||||
/*
|
||||
* DLL Export macro
|
||||
*/
|
||||
|
||||
#if defined(XP_PC)
|
||||
|
||||
#define NS_EXPORT _declspec(dllexport)
|
||||
#define NS_EXPORT_(type) _declspec(dllexport) type __stdcall
|
||||
|
||||
#define NS_IMETHOD_(type) virtual type __stdcall
|
||||
#define NS_IMETHOD virtual nsresult __stdcall
|
||||
#define NS_IMETHODIMP_(type) type __stdcall
|
||||
#define NS_IMETHODIMP nsresult __stdcall
|
||||
|
||||
#define NS_METHOD_(type) type __stdcall
|
||||
#define NS_METHOD nsresult __stdcall
|
||||
|
||||
#define NS_CALLBACK_(_type, _name) _type (__stdcall * _name)
|
||||
#define NS_CALLBACK(_name) nsresult (__stdcall * _name)
|
||||
|
||||
#elif defined(XP_MAC)
|
||||
|
||||
#define NS_EXPORT __declspec(export)
|
||||
#define NS_EXPORT_(type) __declspec(export) type
|
||||
|
||||
#define NS_IMETHOD_(type) virtual type
|
||||
#define NS_IMETHOD virtual nsresult
|
||||
#define NS_IMETHODIMP_(type) type
|
||||
#define NS_IMETHODIMP nsresult
|
||||
|
||||
#define NS_METHOD_(type) type
|
||||
#define NS_METHOD nsresult
|
||||
|
||||
#define NS_CALLBACK_(_type, _name) _type (* _name)
|
||||
#define NS_CALLBACK(_name) nsresult (* _name)
|
||||
|
||||
#else /* !XP_PC && !XP_MAC */
|
||||
|
||||
#define NS_EXPORT
|
||||
#define NS_EXPORT_(type) type
|
||||
|
||||
#define NS_IMETHOD_(type) virtual type
|
||||
#define NS_IMETHOD virtual nsresult
|
||||
#define NS_IMETHODIMP_(type) type
|
||||
#define NS_IMETHODIMP nsresult
|
||||
|
||||
#define NS_METHOD_(type) type
|
||||
#define NS_METHOD nsresult
|
||||
|
||||
#define NS_CALLBACK_(_type, _name) _type (* _name)
|
||||
#define NS_CALLBACK(_name) nsresult (* _name)
|
||||
|
||||
#endif /* !XP_PC */
|
||||
|
||||
/* use these functions to associate get/set methods with a
|
||||
C++ member variable
|
||||
*/
|
||||
|
||||
#define NS_METHOD_GETTER(_method, _type, _member) \
|
||||
_method(_type* aResult) \
|
||||
{\
|
||||
if (!aResult) return NS_ERROR_NULL_POINTER; \
|
||||
*aResult = _member; \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
#define NS_METHOD_SETTER(_method, _type, _member) \
|
||||
_method(_type aResult) \
|
||||
{ \
|
||||
_member = aResult; \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
/*
|
||||
* special for strings to get/set char* strings
|
||||
* using PL_strdup and PR_FREEIF
|
||||
*/
|
||||
#define NS_METHOD_GETTER_STR(_method,_member) \
|
||||
_method(char* *aString)\
|
||||
{\
|
||||
if (!aString) return NS_ERROR_NULL_POINTER; \
|
||||
*aString = PL_strdup(_member); \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
#define NS_METHOD_SETTER_STR(_method, _member) \
|
||||
_method(char *aString)\
|
||||
{\
|
||||
PR_FREEIF(_member);\
|
||||
if (aString) _member = PL_strdup(aString); \
|
||||
else _member = nsnull;\
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
/* Getter/Setter macros.
|
||||
Usage:
|
||||
NS_IMPL_[CLASS_]GETTER[_<type>](method, [type,] member);
|
||||
NS_IMPL_[CLASS_]SETTER[_<type>](method, [type,] member);
|
||||
NS_IMPL_[CLASS_]GETSET[_<type>]([class, ]postfix, [type,] member);
|
||||
|
||||
where:
|
||||
CLASS_ - implementation is inside a class definition
|
||||
(otherwise the class name is needed)
|
||||
Do NOT use in publicly exported header files, because
|
||||
the implementation may be included many times over.
|
||||
Instead, use the non-CLASS_ version.
|
||||
_<type> - For more complex (STR, IFACE) data types
|
||||
(otherwise the simple data type is needed)
|
||||
method - name of the method, such as GetWidth or SetColor
|
||||
type - simple data type if required
|
||||
member - class member variable such as m_width or mColor
|
||||
class - the class name, such as Window or MyObject
|
||||
postfix - Method part after Get/Set such as "Width" for "GetWidth"
|
||||
|
||||
Example:
|
||||
class Window {
|
||||
public:
|
||||
NS_IMPL_CLASS_GETSET(Width, int, m_width);
|
||||
NS_IMPL_CLASS_GETTER_STR(GetColor, m_color);
|
||||
NS_IMETHOD SetColor(char *color);
|
||||
|
||||
private:
|
||||
int m_width; // read/write
|
||||
char *m_color; // readonly
|
||||
};
|
||||
|
||||
// defined outside of class
|
||||
NS_IMPL_SETTER_STR(Window::GetColor, m_color);
|
||||
|
||||
Questions/Comments to alecf@netscape.com
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Getter/Setter implementation within a class definition
|
||||
*/
|
||||
|
||||
/* simple data types */
|
||||
#define NS_IMPL_CLASS_GETTER(_method, _type, _member) \
|
||||
NS_IMETHOD NS_METHOD_GETTER(_method, _type, _member)
|
||||
|
||||
#define NS_IMPL_CLASS_SETTER(_method, _type, _member) \
|
||||
NS_IMETHOD NS_METHOD_SETTER(_method, _type, _member)
|
||||
|
||||
#define NS_IMPL_CLASS_GETSET(_postfix, _type, _member) \
|
||||
NS_IMPL_CLASS_GETTER(Get##_postfix, _type, _member) \
|
||||
NS_IMPL_CLASS_SETTER(Set##_postfix, _type, _member)
|
||||
|
||||
/* strings */
|
||||
#define NS_IMPL_CLASS_GETTER_STR(_method, _member) \
|
||||
NS_IMETHOD NS_METHOD_GETTER_STR(_method, _member)
|
||||
|
||||
#define NS_IMPL_CLASS_SETTER_STR(_method, _member) \
|
||||
NS_IMETHOD NS_METHOD_SETTER_STR(_method, _member)
|
||||
|
||||
#define NS_IMPL_CLASS_GETSET_STR(_postfix, _member) \
|
||||
NS_IMPL_CLASS_GETTER_STR(Get##_postfix, _member) \
|
||||
NS_IMPL_CLASS_SETTER_STR(Set##_postfix, _member)
|
||||
|
||||
/* Getter/Setter implementation outside of a class definition */
|
||||
|
||||
/* simple data types */
|
||||
#define NS_IMPL_GETTER(_method, _type, _member) \
|
||||
NS_IMETHODIMP NS_METHOD_GETTER(_method, _type, _member)
|
||||
|
||||
#define NS_IMPL_SETTER(_method, _type, _member) \
|
||||
NS_IMETHODIMP NS_METHOD_SETTER(_method, _type, _member)
|
||||
|
||||
#define NS_IMPL_GETSET(_class, _postfix, _type, _member) \
|
||||
NS_IMPL_GETTER(_class::Get##_postfix, _type, _member) \
|
||||
NS_IMPL_SETTER(_class::Set##_postfix, _type, _member)
|
||||
|
||||
/* strings */
|
||||
#define NS_IMPL_GETTER_STR(_method, _member) \
|
||||
NS_IMETHODIMP NS_METHOD_GETTER_STR(_method, _member)
|
||||
|
||||
#define NS_IMPL_SETTER_STR(_method, _member) \
|
||||
NS_IMETHODIMP NS_METHOD_SETTER_STR(_method, _member)
|
||||
|
||||
#define NS_IMPL_GETSET_STR(_class, _postfix, _member) \
|
||||
NS_IMPL_GETTER_STR(_class::Get##_postfix, _member) \
|
||||
NS_IMPL_SETTER_STR(_class::Set##_postfix, _member)
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
205
mozilla/xpcom/base/nsDebug.cpp
Normal file
205
mozilla/xpcom/base/nsDebug.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsDebug.h"
|
||||
#include "prlog.h"
|
||||
#include "prinit.h"
|
||||
|
||||
#if defined(XP_BEOS)
|
||||
/* For DEBUGGER macros */
|
||||
#include <Debug.h>
|
||||
#endif
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
/* for abort() */
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#elif defined(XP_MAC)
|
||||
#define TEMP_MAC_HACK
|
||||
|
||||
//------------------------
|
||||
#ifdef TEMP_MAC_HACK
|
||||
#include <MacTypes.h>
|
||||
#include <Processes.h>
|
||||
#include <string.h>
|
||||
|
||||
// TEMPORARY UNTIL WE HAVE MACINTOSH ENVIRONMENT VARIABLES THAT CAN TURN ON
|
||||
// LOGGING ON MACINTOSH
|
||||
// At this moment, NSPR's logging is a no-op on Macintosh.
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#undef PR_LOG
|
||||
#undef PR_LogFlush
|
||||
#define PR_LOG(module,level,args) dprintf args
|
||||
#define PR_LogFlush()
|
||||
static void dprintf(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
Str255 buffer;
|
||||
|
||||
va_start(ap, format);
|
||||
buffer[0] = vsnprintf((char *)buffer + 1, sizeof(buffer) - 1, format, ap);
|
||||
va_end(ap);
|
||||
if (strstr(format, "Warning: ") == format)
|
||||
printf("¥¥¥%s\n", (char*)buffer + 1);
|
||||
else
|
||||
DebugStr(buffer);
|
||||
}
|
||||
#endif // TEMP_MAC_HACK
|
||||
//------------------------
|
||||
#elif defined(XP_UNIX)
|
||||
#include<stdlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of the nsDebug methods. Note that this code is
|
||||
* always compiled in, in case some other module that uses it is
|
||||
* compiled with debugging even if this library is not.
|
||||
*/
|
||||
|
||||
static PRLogModuleInfo* gDebugLog;
|
||||
|
||||
static void InitLog(void)
|
||||
{
|
||||
if (0 == gDebugLog) {
|
||||
gDebugLog = PR_NewLogModule("nsDebug");
|
||||
gDebugLog->level = PR_LOG_DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
NS_COM void nsDebug::Abort(const char* aFile, PRIntn aLine)
|
||||
{
|
||||
InitLog();
|
||||
PR_LOG(gDebugLog, PR_LOG_ERROR,
|
||||
("Abort: at file %s, line %d", aFile, aLine));
|
||||
PR_LogFlush();
|
||||
#if defined(_WIN32)
|
||||
long* __p = (long*) 0x7;
|
||||
*__p = 0x7;
|
||||
#elif defined(XP_MAC)
|
||||
ExitToShell();
|
||||
#elif defined(XP_UNIX)
|
||||
PR_Abort();
|
||||
#elif defined(XP_BEOS)
|
||||
{
|
||||
char buf[2000];
|
||||
sprintf(buf, "Abort: at file %s, line %d", aFile, aLine);
|
||||
DEBUGGER(buf);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_COM void nsDebug::Break(const char* aFile, PRIntn aLine)
|
||||
{
|
||||
#ifndef TEMP_MAC_HACK
|
||||
InitLog();
|
||||
PR_LOG(gDebugLog, PR_LOG_ERROR,
|
||||
("Break: at file %s, line %d", aFile, aLine));
|
||||
PR_LogFlush();
|
||||
#if defined(_WIN32)
|
||||
::DebugBreak();
|
||||
#elif defined(XP_UNIX) && !defined(UNIX_CRASH_ON_ASSERT)
|
||||
fprintf(stderr, "\07"); fflush(stderr);
|
||||
#elif defined(XP_BEOS)
|
||||
{
|
||||
char buf[2000];
|
||||
sprintf(buf, "Break: at file %s, line %d", aFile, aLine);
|
||||
DEBUGGER(buf);
|
||||
}
|
||||
#else
|
||||
Abort(aFile, aLine);
|
||||
#endif
|
||||
#endif // TEMP_MAC_HACK
|
||||
}
|
||||
|
||||
NS_COM void nsDebug::PreCondition(const char* aStr, const char* aExpr,
|
||||
const char* aFile, PRIntn aLine)
|
||||
{
|
||||
InitLog();
|
||||
PR_LOG(gDebugLog, PR_LOG_ERROR,
|
||||
("PreCondition: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
|
||||
aFile, aLine));
|
||||
Break(aFile, aLine);
|
||||
}
|
||||
|
||||
NS_COM void nsDebug::PostCondition(const char* aStr, const char* aExpr,
|
||||
const char* aFile, PRIntn aLine)
|
||||
{
|
||||
InitLog();
|
||||
PR_LOG(gDebugLog, PR_LOG_ERROR,
|
||||
("PostCondition: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
|
||||
aFile, aLine));
|
||||
Break(aFile, aLine);
|
||||
}
|
||||
|
||||
NS_COM void nsDebug::Assertion(const char* aStr, const char* aExpr,
|
||||
const char* aFile, PRIntn aLine)
|
||||
{
|
||||
InitLog();
|
||||
PR_LOG(gDebugLog, PR_LOG_ERROR,
|
||||
("Assertion: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
|
||||
aFile, aLine));
|
||||
#if defined(XP_UNIX)
|
||||
fprintf(stderr, "Assertion: \"%s\" (%s) at file %s, line %d\n", aStr, aExpr,
|
||||
aFile, aLine);
|
||||
#endif
|
||||
Break(aFile, aLine);
|
||||
}
|
||||
|
||||
NS_COM void nsDebug::NotYetImplemented(const char* aMessage,
|
||||
const char* aFile, PRIntn aLine)
|
||||
{
|
||||
InitLog();
|
||||
PR_LOG(gDebugLog, PR_LOG_ERROR,
|
||||
("NotYetImplemented: \"%s\" at file %s, line %d", aMessage,
|
||||
aFile, aLine));
|
||||
Break(aFile, aLine);
|
||||
}
|
||||
|
||||
NS_COM void nsDebug::NotReached(const char* aMessage,
|
||||
const char* aFile, PRIntn aLine)
|
||||
{
|
||||
InitLog();
|
||||
PR_LOG(gDebugLog, PR_LOG_ERROR,
|
||||
("NotReached: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
|
||||
Break(aFile, aLine);
|
||||
}
|
||||
|
||||
NS_COM void nsDebug::Error(const char* aMessage,
|
||||
const char* aFile, PRIntn aLine)
|
||||
{
|
||||
InitLog();
|
||||
PR_LOG(gDebugLog, PR_LOG_ERROR,
|
||||
("Error: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
|
||||
Break(aFile, aLine);
|
||||
}
|
||||
|
||||
NS_COM void nsDebug::Warning(const char* aMessage,
|
||||
const char* aFile, PRIntn aLine)
|
||||
{
|
||||
InitLog();
|
||||
PR_LOG(gDebugLog, PR_LOG_ERROR,
|
||||
("Warning: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
|
||||
PR_LogFlush();
|
||||
}
|
||||
183
mozilla/xpcom/base/nsDebug.h
Normal file
183
mozilla/xpcom/base/nsDebug.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsDebug_h___
|
||||
#define nsDebug_h___
|
||||
|
||||
#include "nsCom.h"
|
||||
#include "prtypes.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define NS_DEBUG
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Namespace for debugging methods. Note that your code must use the
|
||||
* macros defined later in this file so that the debug code can be
|
||||
* conditionally compiled out.
|
||||
*/
|
||||
|
||||
/* in case this is included by a C file */
|
||||
#ifdef __cplusplus
|
||||
|
||||
class nsDebug {
|
||||
public:
|
||||
// XXX add in log controls here
|
||||
// XXX probably want printf type arguments
|
||||
|
||||
/**
|
||||
* Abort the executing program. This works on all architectures.
|
||||
*/
|
||||
static NS_COM void Abort(const char* aFile, PRIntn aLine);
|
||||
|
||||
/**
|
||||
* Break the executing program into the debugger.
|
||||
*/
|
||||
static NS_COM void Break(const char* aFile, PRIntn aLine);
|
||||
|
||||
/**
|
||||
* Log a pre-condition message to the debug log
|
||||
*/
|
||||
static NS_COM void PreCondition(const char* aStr, const char* aExpr,
|
||||
const char* aFile, PRIntn aLine);
|
||||
|
||||
/**
|
||||
* Log a post-condition message to the debug log
|
||||
*/
|
||||
static NS_COM void PostCondition(const char* aStr, const char* aExpr,
|
||||
const char* aFile, PRIntn aLine);
|
||||
|
||||
/**
|
||||
* Log an assertion message to the debug log
|
||||
*/
|
||||
static NS_COM void Assertion(const char* aStr, const char* aExpr,
|
||||
const char* aFile, PRIntn aLine);
|
||||
|
||||
/**
|
||||
* Log a not-yet-implemented message to the debug log
|
||||
*/
|
||||
static NS_COM void NotYetImplemented(const char* aMessage,
|
||||
const char* aFile, PRIntn aLine);
|
||||
|
||||
/**
|
||||
* Log a not-reached message to the debug log
|
||||
*/
|
||||
static NS_COM void NotReached(const char* aMessage,
|
||||
const char* aFile, PRIntn aLine);
|
||||
|
||||
/**
|
||||
* Log an error message to the debug log. This call returns.
|
||||
*/
|
||||
static NS_COM void Error(const char* aMessage,
|
||||
const char* aFile, PRIntn aLine);
|
||||
|
||||
/**
|
||||
* Log a warning message to the debug log.
|
||||
*/
|
||||
static NS_COM void Warning(const char* aMessage,
|
||||
const char* aFile, PRIntn aLine);
|
||||
};
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
/**
|
||||
* Test a precondition for truth. If the expression is not true then
|
||||
* trigger a program failure.
|
||||
*/
|
||||
#define NS_PRECONDITION(expr,str) \
|
||||
if (!(expr)) \
|
||||
nsDebug::PreCondition(str, #expr, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Test an assertion for truth. If the expression is not true then
|
||||
* trigger a program failure.
|
||||
*/
|
||||
#define NS_ASSERTION(expr,str) \
|
||||
if (!(expr)) \
|
||||
nsDebug::Assertion(str, #expr, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Test an assertion for truth. If the expression is not true then
|
||||
* trigger a program failure. The expression will still be
|
||||
* executed in release mode.
|
||||
*/
|
||||
#define NS_VERIFY(expr,str) \
|
||||
if (!(expr)) \
|
||||
nsDebug::Assertion(str, #expr, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Test a post-condition for truth. If the expression is not true then
|
||||
* trigger a program failure.
|
||||
*/
|
||||
#define NS_POSTCONDITION(expr,str) \
|
||||
if (!(expr)) \
|
||||
nsDebug::PostCondition(str, #expr, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* This macros triggers a program failure if executed. It indicates that
|
||||
* an attempt was made to execute some unimplimented functionality.
|
||||
*/
|
||||
#define NS_NOTYETIMPLEMENTED(str) \
|
||||
nsDebug::NotYetImplemented(str, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* This macros triggers a program failure if executed. It indicates that
|
||||
* an attempt was made to execute some unimplimented functionality.
|
||||
*/
|
||||
#define NS_NOTREACHED(str) \
|
||||
nsDebug::NotReached(str, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Log an error message.
|
||||
*/
|
||||
#define NS_ERROR(str) \
|
||||
nsDebug::Error(str, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Log a warning message.
|
||||
*/
|
||||
#define NS_WARNING(str) \
|
||||
nsDebug::Warning(str, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Trigger an abort
|
||||
*/
|
||||
#define NS_ABORT() \
|
||||
nsDebug::Abort(__FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Cause a break
|
||||
*/
|
||||
#define NS_BREAK() \
|
||||
nsDebug::Break(__FILE__, __LINE__)
|
||||
|
||||
#else /* NS_DEBUG */
|
||||
|
||||
#define NS_PRECONDITION(expr,str) {}
|
||||
#define NS_ASSERTION(expr,str) {}
|
||||
#define NS_VERIFY(expr,str) expr
|
||||
#define NS_POSTCONDITION(expr,str) {}
|
||||
#define NS_NOTYETIMPLEMENTED(str) {}
|
||||
#define NS_NOTREACHED(str) {}
|
||||
#define NS_ERROR(str) {}
|
||||
#define NS_WARNING(str) {}
|
||||
#define NS_ABORT() {}
|
||||
#define NS_BREAK() {}
|
||||
|
||||
#endif /* ! NS_DEBUG */
|
||||
#endif /* __cplusplus */
|
||||
#endif /* nsDebug_h___ */
|
||||
189
mozilla/xpcom/base/nsError.h
Normal file
189
mozilla/xpcom/base/nsError.h
Normal file
@@ -0,0 +1,189 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsError_h
|
||||
#define nsError_h
|
||||
|
||||
#ifndef prtypes_h___
|
||||
#include "prtypes.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Generic result data type
|
||||
*/
|
||||
|
||||
typedef PRUint32 nsresult;
|
||||
|
||||
/*
|
||||
* To add error code to your module, you need to do the following:
|
||||
*
|
||||
* 1) Add a module offset code. Add yours to the bottom of the list
|
||||
* right below this comment, adding 1.
|
||||
*
|
||||
* 2) In your module, define a header file which uses one of the
|
||||
* NE_ERROR_GENERATExxxxxx macros. Some examples below:
|
||||
*
|
||||
* #define NS_ERROR_MYMODULE_MYERROR1 NS_ERROR_GENERATE(NS_ERROR_SEVERITY_ERROR,NS_ERROR_MODULE_MYMODULE,1)
|
||||
* #define NS_ERROR_MYMODULE_MYERROR2 NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_MYMODULE,2)
|
||||
* #define NS_ERROR_MYMODULE_MYERROR3 NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_MYMODULE,3)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @name Standard Module Offset Code. Each Module should identify a unique number
|
||||
* and then all errors associated with that module become offsets from the
|
||||
* base associated with that module id. There are 16 bits of code bits for
|
||||
* each module.
|
||||
*/
|
||||
|
||||
#define NS_ERROR_MODULE_XPCOM 1
|
||||
#define NS_ERROR_MODULE_BASE 2
|
||||
#define NS_ERROR_MODULE_GFX 3
|
||||
#define NS_ERROR_MODULE_WIDGET 4
|
||||
#define NS_ERROR_MODULE_CALENDAR 5
|
||||
#define NS_ERROR_MODULE_NETWORK 6
|
||||
#define NS_ERROR_MODULE_PLUGINS 7
|
||||
#define NS_ERROR_MODULE_LAYOUT 8
|
||||
#define NS_ERROR_MODULE_HTMLPARSER 9
|
||||
#define NS_ERROR_MODULE_RDF 10
|
||||
#define NS_ERROR_MODULE_UCONV 11
|
||||
#define NS_ERROR_MODULE_REG 12
|
||||
#define NS_ERROR_MODULE_FILES 13
|
||||
|
||||
#define NS_ERROR_MODULE_MAILNEWS 16
|
||||
#define NS_ERROR_MODULE_EDITOR 17
|
||||
|
||||
/**
|
||||
* @name Standard Error Handling Macros
|
||||
*/
|
||||
|
||||
#define NS_FAILED(_nsresult) ((_nsresult) & 0x80000000)
|
||||
#define NS_SUCCEEDED(_nsresult) (!((_nsresult) & 0x80000000))
|
||||
|
||||
/**
|
||||
* @name Severity Code. This flag identifies the level of warning
|
||||
*/
|
||||
|
||||
#define NS_ERROR_SEVERITY_SUCCESS 0
|
||||
#define NS_ERROR_SEVERITY_ERROR 1
|
||||
|
||||
/**
|
||||
* @name Mozilla Code. This flag separates consumers of mozilla code
|
||||
* from the native platform
|
||||
*/
|
||||
|
||||
#define NS_ERROR_MODULE_BASE_OFFSET 0x45
|
||||
|
||||
/**
|
||||
* @name Standard Error Generating Macros
|
||||
*/
|
||||
|
||||
#define NS_ERROR_GENERATE(sev,module,code) \
|
||||
((nsresult) (((PRUint32)(sev)<<31) | ((PRUint32)(module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | ((PRUint32)(code))) )
|
||||
|
||||
#define NS_ERROR_GENERATE_SUCCESS(module,code) \
|
||||
((nsresult) (((PRUint32)(NS_ERROR_SEVERITY_SUCCESS)<<31) | ((PRUint32)(module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | ((PRUint32)(code))) )
|
||||
|
||||
#define NS_ERROR_GENERATE_FAILURE(module,code) \
|
||||
((nsresult) (((PRUint32)(NS_ERROR_SEVERITY_ERROR)<<31) | ((PRUint32)(module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | ((PRUint32)(code))) )
|
||||
|
||||
/**
|
||||
* @name Standard Macros for retrieving error bits
|
||||
*/
|
||||
|
||||
#define NS_ERROR_GET_CODE(err) ((err) & 0xffff)
|
||||
#define NS_ERROR_GET_MODULE(err) (((((err) >> 16) - NS_ERROR_MODULE_BASE_OFFSET) & 0x1fff))
|
||||
#define NS_ERROR_GET_SEVERITY(err) (((err) >> 31) & 0x1)
|
||||
|
||||
/**
|
||||
* @name Standard return values
|
||||
*/
|
||||
|
||||
/*@{*/
|
||||
|
||||
/* Standard "it worked" return value */
|
||||
#define NS_OK 0
|
||||
|
||||
/* The backwards COM false */
|
||||
#define NS_COMFALSE 1
|
||||
|
||||
#define NS_ERROR_BASE ((nsresult) 0xC1F30000)
|
||||
|
||||
/* Returned when an instance is not initialized */
|
||||
#define NS_ERROR_NOT_INITIALIZED (NS_ERROR_BASE + 1)
|
||||
|
||||
/* Returned when an instance is already initialized */
|
||||
#define NS_ERROR_ALREADY_INITIALIZED (NS_ERROR_BASE + 2)
|
||||
|
||||
/* Returned by a not implemented function */
|
||||
#define NS_ERROR_NOT_IMPLEMENTED ((nsresult) 0x80004001L)
|
||||
|
||||
/* Returned when a given interface is not supported. */
|
||||
#define NS_NOINTERFACE ((nsresult) 0x80004002L)
|
||||
#define NS_ERROR_NO_INTERFACE NS_NOINTERFACE
|
||||
|
||||
#define NS_ERROR_INVALID_POINTER ((nsresult) 0x80004003L)
|
||||
#define NS_ERROR_NULL_POINTER NS_ERROR_INVALID_POINTER
|
||||
|
||||
/* Returned when a function aborts */
|
||||
#define NS_ERROR_ABORT ((nsresult) 0x80004004L)
|
||||
|
||||
/* Returned when a function fails */
|
||||
#define NS_ERROR_FAILURE ((nsresult) 0x80004005L)
|
||||
|
||||
/* Returned when an unexpected error occurs */
|
||||
#define NS_ERROR_UNEXPECTED ((nsresult) 0x8000ffffL)
|
||||
|
||||
/* Returned when a memory allocation failes */
|
||||
#define NS_ERROR_OUT_OF_MEMORY ((nsresult) 0x8007000eL)
|
||||
|
||||
/* Returned when an illegal value is passed */
|
||||
#define NS_ERROR_ILLEGAL_VALUE ((nsresult) 0x80070057L)
|
||||
#define NS_ERROR_INVALID_ARG NS_ERROR_ILLEGAL_VALUE
|
||||
|
||||
/* Returned when a class doesn't allow aggregation */
|
||||
#define NS_ERROR_NO_AGGREGATION ((nsresult) 0x80040110L)
|
||||
|
||||
/* Returned when a class doesn't allow aggregation */
|
||||
#define NS_ERROR_NOT_AVAILABLE ((nsresult) 0x80040111L)
|
||||
|
||||
/* Returned when a class is not registered */
|
||||
#define NS_ERROR_FACTORY_NOT_REGISTERED ((nsresult) 0x80040154L)
|
||||
|
||||
/* Returned when a dynamically loaded factory couldn't be found */
|
||||
#define NS_ERROR_FACTORY_NOT_LOADED ((nsresult) 0x800401f8L)
|
||||
|
||||
/* Returned when a factory doesn't support signatures */
|
||||
#define NS_ERROR_FACTORY_NO_SIGNATURE_SUPPORT \
|
||||
(NS_ERROR_BASE + 0x101)
|
||||
|
||||
/* Returned when a factory already is registered */
|
||||
#define NS_ERROR_FACTORY_EXISTS (NS_ERROR_BASE + 0x100)
|
||||
|
||||
/*@}*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef XP_PC
|
||||
#pragma warning(disable: 4251) // 'nsCOMPtr<class nsIInputStream>' needs to have dll-interface to be used by clients of class 'nsInputStream'
|
||||
#pragma warning(disable: 4275) // non dll-interface class 'nsISupports' used as base for dll-interface class 'nsIRDFNode'
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
108
mozilla/xpcom/base/nsIAllocator.h
Normal file
108
mozilla/xpcom/base/nsIAllocator.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIAllocator_h___
|
||||
#define nsIAllocator_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
/**
|
||||
* Unlike IMalloc, this interface returns nsresults and doesn't
|
||||
* implement the problematic GetSize and DidAlloc routines.
|
||||
*/
|
||||
|
||||
#define NS_IALLOCATOR_IID \
|
||||
{ /* 56def700-b1b9-11d2-8177-006008119d7a */ \
|
||||
0x56def700, \
|
||||
0xb1b9, \
|
||||
0x11d2, \
|
||||
{0x81, 0x77, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
#define NS_ALLOCATOR_PROGID "component://netscape/allocator"
|
||||
#define NS_ALLOCATOR_CLASSNAME "Allocator"
|
||||
|
||||
class nsIAllocator : public nsISupports {
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IALLOCATOR_IID; return iid; }
|
||||
|
||||
/**
|
||||
* Allocates a block of memory of a particular size.
|
||||
*
|
||||
* @param size - the size of the block to allocate
|
||||
* @result the block of memory
|
||||
*/
|
||||
NS_IMETHOD_(void*) Alloc(PRUint32 size) = 0;
|
||||
|
||||
/**
|
||||
* Reallocates a block of memory to a new size.
|
||||
*
|
||||
* @param ptr - the block of memory to reallocate
|
||||
* @param size - the new size
|
||||
* @result the rellocated block of memory
|
||||
*/
|
||||
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size) = 0;
|
||||
|
||||
/**
|
||||
* Frees a block of memory.
|
||||
*
|
||||
* @param ptr - the block of memory to free
|
||||
* @param size - the size of the block to be freed. If -1 (the default),
|
||||
* the implementation must be able to determine the block size by
|
||||
* examining the block pointer.
|
||||
*/
|
||||
NS_IMETHOD Free(void* ptr) = 0;
|
||||
|
||||
/**
|
||||
* Attempts to shrink the heap.
|
||||
*/
|
||||
NS_IMETHOD HeapMinimize(void) = 0;
|
||||
|
||||
};
|
||||
|
||||
// To get the global memory manager service:
|
||||
#define NS_ALLOCATOR_CID \
|
||||
{ /* aafe6770-b1bb-11d2-8177-006008119d7a */ \
|
||||
0xaafe6770, \
|
||||
0xb1bb, \
|
||||
0x11d2, \
|
||||
{0x81, 0x77, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Public shortcuts to the shared allocator's methods
|
||||
*/
|
||||
|
||||
class nsAllocator
|
||||
{
|
||||
public:
|
||||
static NS_EXPORT void* Alloc(PRUint32 size);
|
||||
static NS_EXPORT void* Realloc(void* ptr, PRUint32 size);
|
||||
static NS_EXPORT void Free(void* ptr);
|
||||
static NS_EXPORT void HeapMinimize();
|
||||
static NS_EXPORT void* Clone(const void* ptr, PRUint32 size);
|
||||
private:
|
||||
nsAllocator(); // not implemented
|
||||
static PRBool EnsureAllocator() {return mAllocator || FetchAllocator();}
|
||||
static PRBool FetchAllocator();
|
||||
static nsIAllocator* mAllocator;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif /* nsIAllocator_h___ */
|
||||
73
mozilla/xpcom/base/nsID.cpp
Normal file
73
mozilla/xpcom/base/nsID.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#include "nsID.h"
|
||||
#include "prprf.h"
|
||||
|
||||
static const char gIDFormat[] =
|
||||
"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}";
|
||||
|
||||
static const char gIDFormat2[] =
|
||||
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
|
||||
|
||||
/*
|
||||
* Turns a {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} string into
|
||||
* an nsID
|
||||
*/
|
||||
|
||||
NS_COM PRBool nsID::Parse(char *aIDStr)
|
||||
{
|
||||
PRInt32 count = 0;
|
||||
PRInt32 n1, n2, n3[8];
|
||||
PRInt32 n0;
|
||||
|
||||
if (NULL != aIDStr) {
|
||||
count = PR_sscanf(aIDStr,
|
||||
(aIDStr[0] == '{') ? gIDFormat : gIDFormat2,
|
||||
&n0, &n1, &n2,
|
||||
&n3[0],&n3[1],&n3[2],&n3[3],
|
||||
&n3[4],&n3[5],&n3[6],&n3[7]);
|
||||
|
||||
m0 = (PRInt32) n0;
|
||||
m1 = (PRInt16) n1;
|
||||
m2 = (PRInt16) n2;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
m3[i] = (PRInt8) n3[i];
|
||||
}
|
||||
}
|
||||
return (PRBool) (count == 11);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns an allocated string in {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||
* format. Caller should delete [] the string.
|
||||
*/
|
||||
|
||||
NS_COM char *nsID::ToString() const
|
||||
{
|
||||
char *res = new char[39];
|
||||
|
||||
if (res != NULL) {
|
||||
PR_snprintf(res, 39, gIDFormat,
|
||||
m0, (PRUint32) m1, (PRUint32) m2,
|
||||
(PRUint32) m3[0], (PRUint32) m3[1], (PRUint32) m3[2],
|
||||
(PRUint32) m3[3], (PRUint32) m3[4], (PRUint32) m3[5],
|
||||
(PRUint32) m3[6], (PRUint32) m3[7]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
107
mozilla/xpcom/base/nsID.h
Normal file
107
mozilla/xpcom/base/nsID.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsID_h__
|
||||
#define nsID_h__
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef prtypes_h___
|
||||
#include "prtypes.h"
|
||||
#endif
|
||||
|
||||
#ifndef nsCom_h__
|
||||
#include "nsCom.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A "unique identifier". This is modeled after OSF DCE UUIDs.
|
||||
*/
|
||||
|
||||
struct nsID {
|
||||
/**
|
||||
* @name Indentifier values
|
||||
*/
|
||||
|
||||
//@{
|
||||
PRUint32 m0;
|
||||
PRUint16 m1;
|
||||
PRUint16 m2;
|
||||
PRUint8 m3[8];
|
||||
//@}
|
||||
|
||||
/**
|
||||
* @name Methods
|
||||
*/
|
||||
|
||||
//@{
|
||||
/**
|
||||
* Equivalency method. Compares this nsID with another.
|
||||
* @return <b>PR_TRUE</b> if they are the same, <b>PR_FALSE</b> if not.
|
||||
*/
|
||||
|
||||
inline PRBool Equals(const nsID& other) const {
|
||||
return (PRBool)
|
||||
((((PRUint32*) &m0)[0] == ((PRUint32*) &other.m0)[0]) &&
|
||||
(((PRUint32*) &m0)[1] == ((PRUint32*) &other.m0)[1]) &&
|
||||
(((PRUint32*) &m0)[2] == ((PRUint32*) &other.m0)[2]) &&
|
||||
(((PRUint32*) &m0)[3] == ((PRUint32*) &other.m0)[3]));
|
||||
}
|
||||
|
||||
/**
|
||||
* nsID Parsing method. Turns a {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||
* string into an nsID
|
||||
*/
|
||||
NS_COM PRBool Parse(char *aIDStr);
|
||||
|
||||
/**
|
||||
* nsID string encoder. Returns an allocated string in
|
||||
* {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format. Caller should free string.
|
||||
*/
|
||||
NS_COM char* ToString() const;
|
||||
//@}
|
||||
};
|
||||
|
||||
/**
|
||||
* Declare an ID. If NS_IMPL_IDS is set, a variable <i>_name</i> is declared
|
||||
* with the given values, otherwise <i>_name</i> is declared as an
|
||||
* <tt>extern</tt> variable.
|
||||
*/
|
||||
|
||||
#ifdef NS_IMPL_IDS
|
||||
#define NS_DECLARE_ID(_name,m0,m1,m2,m30,m31,m32,m33,m34,m35,m36,m37) \
|
||||
extern "C" const nsID _name = {m0,m1,m2,{m30,m31,m32,m33,m34,m35,m36,m37}}
|
||||
#else
|
||||
#define NS_DECLARE_ID(_name,m0,m1,m2,m30,m31,m32,m33,m34,m35,m36,m37) \
|
||||
extern "C" const nsID _name
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Class IDs
|
||||
*/
|
||||
|
||||
typedef nsID nsCID;
|
||||
|
||||
// Define an CID
|
||||
#define NS_DEFINE_CID(_name, _cidspec) \
|
||||
const nsCID _name = _cidspec
|
||||
|
||||
#define REFNSCID const nsCID&
|
||||
|
||||
#endif
|
||||
|
||||
46
mozilla/xpcom/base/nsIID.h
Normal file
46
mozilla/xpcom/base/nsIID.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef __nsIID_h
|
||||
#define __nsIID_h
|
||||
|
||||
#ifndef nsID_h__
|
||||
#include "nsID.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* An "interface id" which can be used to uniquely identify a given
|
||||
* interface.
|
||||
*/
|
||||
|
||||
typedef nsID nsIID;
|
||||
|
||||
/**
|
||||
* A macro shorthand for <tt>const nsIID&<tt>
|
||||
*/
|
||||
|
||||
#define REFNSIID const nsIID&
|
||||
|
||||
/**
|
||||
* Define an IID (obsolete)
|
||||
*/
|
||||
|
||||
#define NS_DEFINE_IID(_name, _iidspec) \
|
||||
const nsIID _name = _iidspec
|
||||
|
||||
#endif /* __nsIID_h */
|
||||
142
mozilla/xpcom/base/nsIPtr.h
Normal file
142
mozilla/xpcom/base/nsIPtr.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIPtr_h___
|
||||
#define nsIPtr_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
/*
|
||||
* nsIPtr is an "auto-release pointer" class for nsISupports based interfaces
|
||||
*
|
||||
* It's intent is to be a "set and forget" pointer to help with managing
|
||||
* active references to nsISupports bases objects.
|
||||
*
|
||||
* The pointer object ensures that the underlying pointer is always
|
||||
* released whenever the value is changed or when the object leaves scope.
|
||||
*
|
||||
* Proper care needs to be taken when assigning pointers to a nsIPtr.
|
||||
* When asigning from a C pointer (nsISupports*), the pointer presumes
|
||||
* an active reference and subsumes it. When assigning from another nsIPtr,
|
||||
* a new reference is established.
|
||||
*
|
||||
* There are 3 ways to assign a value to a nsIPtr.
|
||||
* 1) Direct construction or assignment from a C pointer.
|
||||
* 2) Direct construction or assignment form another nsIPtr.
|
||||
* 3) Usage of an "out parameter" method.
|
||||
* a) AssignRef() releases the underlying pointer and returns a reference to it.
|
||||
* Useful for pointer reference out paramaters.
|
||||
* b) AssignPtr() releases the underlying pointer and returns a pointer to it.
|
||||
* c) Query() releases the underlying pointer and returns a (void**) pointer to it.
|
||||
* Useful for calls to QueryInterface()
|
||||
* 4) The SetAddRef() method. This is equivalent to an assignment followed by an AddRef().
|
||||
*
|
||||
* examples:
|
||||
*
|
||||
* class It {
|
||||
* void NS_NewFoo(nsIFoo** aFoo);
|
||||
* nsIFoo* GetFoo(void);
|
||||
* void GetBar(nsIBar*& aBar);
|
||||
* };
|
||||
*
|
||||
* nsIFooPtr foo = it->GetFoo();
|
||||
* nsIBarPtr bar;
|
||||
*
|
||||
* it->NS_NewFoo(foo.AssignPtr());
|
||||
* it->GetBar(bar.AssignRef());
|
||||
* it->QueryInterface(kIFooIID, foo.Query());
|
||||
* bar.SetAddRef(new Bar());
|
||||
*
|
||||
* Advantages:
|
||||
* Set and forget. Once a pointer is assigned to a nsIPtr, it is impossible
|
||||
* to forget to release it.
|
||||
* Always pre-initialized. You can't forget to initialize the pointer.
|
||||
*
|
||||
* Disadvantages:
|
||||
* Usage of this class doesn't eliminate the need to think about ref counts
|
||||
* and assign values properly, AddRef'ing as needed.
|
||||
* The nsIPtr doesn't typecast exactly like a C pointer. In order to achieve
|
||||
* typecasting, it may be necessary to first cast to a C pointer of the
|
||||
* underlying type.
|
||||
*
|
||||
*/
|
||||
|
||||
#define NS_DEF_PTR(cls) \
|
||||
class cls##Ptr { \
|
||||
public: \
|
||||
cls##Ptr(void) : mPtr(0) {} \
|
||||
cls##Ptr(const cls##Ptr& aCopy) : mPtr(aCopy.mPtr) \
|
||||
{ NS_IF_ADDREF(mPtr); } \
|
||||
cls##Ptr(cls* aInterface) : mPtr(aInterface) {} \
|
||||
~cls##Ptr(void) { NS_IF_RELEASE(mPtr); } \
|
||||
cls##Ptr& operator=(const cls##Ptr& aCopy) \
|
||||
{ if(mPtr == aCopy.mPtr) return *this; \
|
||||
NS_IF_ADDREF(aCopy.mPtr); \
|
||||
NS_IF_RELEASE(mPtr); \
|
||||
mPtr = aCopy.mPtr; return *this; } \
|
||||
cls##Ptr& operator=(cls* aInterface) \
|
||||
{ if(mPtr == aInterface) return *this; \
|
||||
NS_IF_RELEASE(mPtr); mPtr = aInterface; \
|
||||
return *this; } \
|
||||
cls##Ptr& operator=(PRInt32 aInt) \
|
||||
{ NS_IF_RELEASE(mPtr); \
|
||||
return *this; } \
|
||||
void SetAddRef(cls* aInterface) \
|
||||
{ if(aInterface == mPtr) return; \
|
||||
NS_IF_ADDREF(aInterface); \
|
||||
NS_IF_RELEASE(mPtr); mPtr = aInterface; } \
|
||||
cls* AddRef(void) { NS_ADDREF(mPtr); return mPtr; } \
|
||||
cls* IfAddRef(void) \
|
||||
{ NS_IF_ADDREF(mPtr); return mPtr; } \
|
||||
cls*& AssignRef(void) \
|
||||
{ NS_IF_RELEASE(mPtr); return mPtr; } \
|
||||
cls** AssignPtr(void) \
|
||||
{ NS_IF_RELEASE(mPtr); return &mPtr; } \
|
||||
void** Query(void) \
|
||||
{ NS_IF_RELEASE(mPtr); return (void**)&mPtr; } \
|
||||
PRBool IsNull() const \
|
||||
{ return PRBool(0 == mPtr); } \
|
||||
PRBool IsNotNull() const \
|
||||
{ return PRBool(0 != mPtr); } \
|
||||
PRBool operator==(const cls##Ptr& aCopy) const \
|
||||
{ return PRBool(mPtr == aCopy.mPtr); } \
|
||||
PRBool operator==(cls* aInterface) const \
|
||||
{ return PRBool(mPtr == aInterface); } \
|
||||
PRBool operator!=(const cls##Ptr& aCopy) const \
|
||||
{ return PRBool(mPtr != aCopy.mPtr); } \
|
||||
PRBool operator!=(cls* aInterface) const \
|
||||
{ return PRBool(mPtr != aInterface); } \
|
||||
cls* operator->(void) { return mPtr; } \
|
||||
cls& operator*(void) { return *mPtr; } \
|
||||
operator cls*(void) { return mPtr; } \
|
||||
const cls* operator->(void) const { return mPtr; } \
|
||||
const cls& operator*(void) const { return *mPtr; } \
|
||||
operator const cls* (void) const { return mPtr; } \
|
||||
private: \
|
||||
void* operator new(size_t size) { return 0; } \
|
||||
void operator delete(void* aPtr) {} \
|
||||
cls* mPtr; \
|
||||
public: \
|
||||
friend inline PRBool operator==(const cls* aInterface, const cls##Ptr& aPtr) \
|
||||
{ return PRBool(aInterface == aPtr.mPtr); } \
|
||||
friend inline PRBool operator!=(const cls* aInterface, const cls##Ptr& aPtr) \
|
||||
{ return PRBool(aInterface != aPtr.mPtr); } \
|
||||
}
|
||||
|
||||
#endif // nsIPtr_h___
|
||||
|
||||
56
mozilla/xpcom/base/nsISupports.idl
Normal file
56
mozilla/xpcom/base/nsISupports.idl
Normal file
@@ -0,0 +1,56 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/* The mother of all xpcom interfaces. */
|
||||
|
||||
/* In order to get both the right typelib and the right header we force
|
||||
* the 'real' output from xpidl to be commentout out in the generated header
|
||||
* and includes a copy of the original nsISUpports.h. This is all just to deal
|
||||
* with the Mac specific ": public __comobject" thing.
|
||||
*/
|
||||
|
||||
#include "nsrootidl.idl"
|
||||
|
||||
%{C++
|
||||
/*
|
||||
* Start commenting out the C++ versions of the below in the output header
|
||||
*/
|
||||
#if 0
|
||||
%}
|
||||
|
||||
[scriptable, uuid(00000000-0000-0000-c000-000000000046)]
|
||||
interface nsISupports {
|
||||
void QueryInterface(in nsIIDRef uuid,
|
||||
[iid_is(uuid),retval] out nsQIResult result);
|
||||
[noscript, notxpcom] nsrefcnt AddRef();
|
||||
[noscript, notxpcom] nsrefcnt Release();
|
||||
};
|
||||
|
||||
%{C++
|
||||
/*
|
||||
* End commenting out the C++ versions of the above in the output header
|
||||
*/
|
||||
#endif
|
||||
%}
|
||||
|
||||
|
||||
%{C++
|
||||
|
||||
#include "nsISupportsUtils.h"
|
||||
|
||||
%}
|
||||
756
mozilla/xpcom/base/nsISupportsUtils.h
Normal file
756
mozilla/xpcom/base/nsISupportsUtils.h
Normal file
@@ -0,0 +1,756 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef __nsISupportsUtils_h
|
||||
#define __nsISupportsUtils_h
|
||||
|
||||
/***************************************************************************/
|
||||
/* this section copied from the hand written nsISupports.h */
|
||||
|
||||
#include "nsDebug.h"
|
||||
#include "nsID.h"
|
||||
#include "nsIID.h"
|
||||
#include "nsError.h"
|
||||
|
||||
#if defined(NS_MT_SUPPORTED)
|
||||
#include "prcmon.h"
|
||||
#endif /* NS_MT_SUPPORTED */
|
||||
|
||||
#if defined(XPIDL_JS_STUBS)
|
||||
struct JSObject;
|
||||
struct JSContext;
|
||||
#endif
|
||||
|
||||
// under Metrowerks (Mac), we don't have autoconf yet
|
||||
#ifdef __MWERKS__
|
||||
#define HAVE_CPP_SPECIALIZATION
|
||||
#endif
|
||||
|
||||
// under VC++ (Windows), we don't have autoconf yet
|
||||
#if defined(_MSC_VER) && (_MSC_VER>=1100)
|
||||
// VC++ 5.0 and greater implement template specialization, 4.2 is unknown
|
||||
#define HAVE_CPP_SPECIALIZATION
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CPP_SPECIALIZATION
|
||||
#define NSCAP_FEATURE_HIDE_NSISUPPORTS_GETIID
|
||||
#endif
|
||||
|
||||
/*@{*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* IID for the nsISupports interface
|
||||
* {00000000-0000-0000-c000-000000000046}
|
||||
*
|
||||
* To maintain binary compatibility with COM's nsIUnknown, we define the IID
|
||||
* of nsISupports to be the same as that of COM's nsIUnknown.
|
||||
*/
|
||||
#define NS_ISUPPORTS_IID \
|
||||
{ 0x00000000, 0x0000, 0x0000, \
|
||||
{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }
|
||||
|
||||
/**
|
||||
* Reference count values
|
||||
*
|
||||
* This is type of return value from Addref() and Release() in nsISupports.
|
||||
* nsIUnknown of COM returns a unsigned long from equivalent functions.
|
||||
* To maintain binary compatibility of nsISupports with nsIUnknown, we are
|
||||
* doing this ifdeffing.
|
||||
*/
|
||||
#if defined(XP_PC) && PR_BYTES_PER_LONG == 4
|
||||
typedef unsigned long nsrefcnt;
|
||||
#else
|
||||
typedef PRUint32 nsrefcnt;
|
||||
#endif
|
||||
|
||||
#include "nsTraceRefcnt.h"
|
||||
|
||||
/**
|
||||
* Base class for all XPCOM objects to use. This macro forces the C++
|
||||
* compiler to use a compatible vtable layout for all XPCOM objects.
|
||||
*/
|
||||
#ifdef XP_MAC
|
||||
#define XPCOM_OBJECT : public __comobject
|
||||
#else
|
||||
#define XPCOM_OBJECT
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Basic component object model interface. Objects which implement
|
||||
* this interface support runtime interface discovery (QueryInterface)
|
||||
* and a reference counted memory model (AddRef/Release). This is
|
||||
* modelled after the win32 IUnknown API.
|
||||
*/
|
||||
class nsISupports XPCOM_OBJECT {
|
||||
public:
|
||||
|
||||
#ifndef NSCAP_FEATURE_HIDE_NSISUPPORTS_GETIID
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_ISUPPORTS_IID; return iid; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Methods
|
||||
*/
|
||||
|
||||
//@{
|
||||
/**
|
||||
* A run time mechanism for interface discovery.
|
||||
* @param aIID [in] A requested interface IID
|
||||
* @param aInstancePtr [out] A pointer to an interface pointer to
|
||||
* receive the result.
|
||||
* @return <b>NS_OK</b> if the interface is supported by the associated
|
||||
* instance, <b>NS_NOINTERFACE</b> if it is not.
|
||||
* <b>NS_ERROR_INVALID_POINTER</b> if <i>aInstancePtr</i> is <b>NULL</b>.
|
||||
*/
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID,
|
||||
void** aInstancePtr) = 0;
|
||||
/**
|
||||
* Increases the reference count for this interface.
|
||||
* The associated instance will not be deleted unless
|
||||
* the reference count is returned to zero.
|
||||
*
|
||||
* @return The resulting reference count.
|
||||
*/
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void) = 0;
|
||||
|
||||
/**
|
||||
* Decreases the reference count for this interface.
|
||||
* Generally, if the reference count returns to zero,
|
||||
* the associated instance is deleted.
|
||||
*
|
||||
* @return The resulting reference count.
|
||||
*/
|
||||
NS_IMETHOD_(nsrefcnt) Release(void) = 0;
|
||||
|
||||
//@}
|
||||
};
|
||||
|
||||
/*@}*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/**
|
||||
* A macro to build the static const IID accessor method
|
||||
*/
|
||||
|
||||
#define NS_DEFINE_STATIC_IID_ACCESSOR(the_iid) \
|
||||
static const nsIID& GetIID() {static nsIID iid = the_iid; return iid;}
|
||||
|
||||
/**
|
||||
* A macro to build the static const CID accessor method
|
||||
*/
|
||||
|
||||
#define NS_DEFINE_STATIC_CID_ACCESSOR(the_cid) \
|
||||
static const nsID& GetCID() {static nsID cid = the_cid; return cid;}
|
||||
|
||||
/**
|
||||
* Some convenience macros for implementing AddRef and Release
|
||||
*/
|
||||
|
||||
/**
|
||||
* Declare the reference count variable and the implementations of the
|
||||
* AddRef and QueryInterface methods.
|
||||
*/
|
||||
|
||||
#define NS_DECL_ISUPPORTS \
|
||||
public: \
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, \
|
||||
void** aInstancePtr); \
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void); \
|
||||
NS_IMETHOD_(nsrefcnt) Release(void); \
|
||||
protected: \
|
||||
nsrefcnt mRefCnt; \
|
||||
public:
|
||||
|
||||
#define NS_DECL_ISUPPORTS_EXPORTED \
|
||||
public: \
|
||||
NS_EXPORT NS_IMETHOD QueryInterface(REFNSIID aIID, \
|
||||
void** aInstancePtr); \
|
||||
NS_EXPORT NS_IMETHOD_(nsrefcnt) AddRef(void); \
|
||||
NS_EXPORT NS_IMETHOD_(nsrefcnt) Release(void); \
|
||||
protected: \
|
||||
nsrefcnt mRefCnt; \
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Initialize the reference count variable. Add this to each and every
|
||||
* constructor you implement.
|
||||
*/
|
||||
#define NS_INIT_REFCNT() mRefCnt = 0
|
||||
#define NS_INIT_ISUPPORTS() NS_INIT_REFCNT() // what it should have been called in the first place
|
||||
|
||||
/**
|
||||
* Use this macro to implement the AddRef method for a given <i>_class</i>
|
||||
* @param _class The name of the class implementing the method
|
||||
*/
|
||||
#define NS_IMPL_ADDREF(_class) \
|
||||
NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
|
||||
{ \
|
||||
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
|
||||
++mRefCnt; \
|
||||
NS_LOG_ADDREF(this, mRefCnt, __FILE__, __LINE__); \
|
||||
return mRefCnt; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this macro to implement the Release method for a given <i>_class</i>
|
||||
* @param _class The name of the class implementing the method
|
||||
*/
|
||||
#define NS_IMPL_RELEASE(_class) \
|
||||
NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
|
||||
{ \
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
|
||||
--mRefCnt; \
|
||||
NS_LOG_RELEASE(this, mRefCnt, __FILE__, __LINE__); \
|
||||
if (mRefCnt == 0) { \
|
||||
NS_DELETEXPCOM(this); \
|
||||
return 0; \
|
||||
} \
|
||||
return mRefCnt; \
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* Some convenience macros for implementing QueryInterface
|
||||
*/
|
||||
|
||||
/**
|
||||
* This implements query interface with two assumptions: First, the
|
||||
* class in question implements nsISupports and it's own interface and
|
||||
* nothing else. Second, the implementation of the class's primary
|
||||
* inheritance chain leads to it's own interface.
|
||||
*
|
||||
* @param _class The name of the class implementing the method
|
||||
* @param _classiiddef The name of the #define symbol that defines the IID
|
||||
* for the class (e.g. NS_ISUPPORTS_IID)
|
||||
*/
|
||||
|
||||
#define NS_IMPL_QUERY_INTERFACE(_class,_classiiddef) \
|
||||
NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
|
||||
{ \
|
||||
if (NULL == aInstancePtr) { \
|
||||
return NS_ERROR_NULL_POINTER; \
|
||||
} \
|
||||
\
|
||||
*aInstancePtr = NULL; \
|
||||
\
|
||||
static NS_DEFINE_IID(kClassIID, _classiiddef); \
|
||||
if (aIID.Equals(kClassIID)) { \
|
||||
*aInstancePtr = (void*) this; \
|
||||
NS_ADDREF_THIS(); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
if (aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID())) { \
|
||||
*aInstancePtr = (void*) ((nsISupports*)this); \
|
||||
NS_ADDREF_THIS(); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
return NS_NOINTERFACE; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience macro for implementing all nsISupports methods for
|
||||
* a simple class.
|
||||
* @param _class The name of the class implementing the method
|
||||
* @param _classiiddef The name of the #define symbol that defines the IID
|
||||
* for the class (e.g. NS_ISUPPORTS_IID)
|
||||
*/
|
||||
|
||||
#define NS_IMPL_ISUPPORTS(_class,_classiiddef) \
|
||||
NS_IMPL_ADDREF(_class) \
|
||||
NS_IMPL_RELEASE(_class) \
|
||||
NS_IMPL_QUERY_INTERFACE(_class,_classiiddef)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Declare that you're going to inherit from something that already
|
||||
* implements nsISupports, but also implements an additional interface, thus
|
||||
* causing an ambiguity. In this case you don't need another mRefCnt, you
|
||||
* just need to forward the definitions to the appropriate superclass. E.g.
|
||||
*
|
||||
* class Bar : public Foo, public nsIBar { // both provide nsISupports
|
||||
* public:
|
||||
* NS_DECL_ISUPPORTS_INHERITED
|
||||
* ...other nsIBar and Bar methods...
|
||||
* };
|
||||
*/
|
||||
#define NS_DECL_ISUPPORTS_INHERITED \
|
||||
public: \
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, \
|
||||
void** aInstancePtr); \
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void); \
|
||||
NS_IMETHOD_(nsrefcnt) Release(void); \
|
||||
|
||||
/**
|
||||
* These macros can be used in conjunction with NS_DECL_ISUPPORTS_INHERITED
|
||||
* to implement the nsISupports methods, forwarding the invocations to a
|
||||
* superclass that already implements nsISupports.
|
||||
*
|
||||
* Note that I didn't make these inlined because they're virtual methods.
|
||||
*/
|
||||
|
||||
#define NS_IMPL_ADDREF_INHERITED(Class, Super) \
|
||||
NS_IMETHODIMP_(nsrefcnt) Class::AddRef(void) \
|
||||
{ \
|
||||
return Super::AddRef(); \
|
||||
} \
|
||||
|
||||
#define NS_IMPL_RELEASE_INHERITED(Class, Super) \
|
||||
NS_IMETHODIMP_(nsrefcnt) Class::Release(void) \
|
||||
{ \
|
||||
return Super::Release(); \
|
||||
} \
|
||||
|
||||
#define NS_IMPL_QUERY_INTERFACE_INHERITED(Class, Super, AdditionalInterface) \
|
||||
NS_IMETHODIMP Class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
|
||||
{ \
|
||||
if (!aInstancePtr) return NS_ERROR_NULL_POINTER; \
|
||||
if (aIID.Equals(AdditionalInterface::GetIID())) { \
|
||||
*aInstancePtr = NS_STATIC_CAST(AdditionalInterface*, this); \
|
||||
NS_ADDREF_THIS(); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
return Super::QueryInterface(aIID, aInstancePtr); \
|
||||
} \
|
||||
|
||||
#define NS_IMPL_ISUPPORTS_INHERITED(Class, Super, AdditionalInterface) \
|
||||
NS_IMPL_QUERY_INTERFACE_INHERITED(Class, Super, AdditionalInterface) \
|
||||
NS_IMPL_ADDREF_INHERITED(Class, Super) \
|
||||
NS_IMPL_RELEASE_INHERITED(Class, Super) \
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
*
|
||||
* Threadsafe implementations of the ISupports convenience macros
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* IID for the nsIsThreadsafe interface
|
||||
* {88210890-47a6-11d2-bec3-00805f8a66dc}
|
||||
*
|
||||
* This interface is *only* used for debugging purposes to determine if
|
||||
* a given component is threadsafe.
|
||||
*/
|
||||
#define NS_ISTHREADSAFE_IID \
|
||||
{ 0x88210890, 0x47a6, 0x11d2, \
|
||||
{0xbe, 0xc3, 0x00, 0x80, 0x5f, 0x8a, 0x66, 0xdc} }
|
||||
|
||||
#if defined(NS_MT_SUPPORTED)
|
||||
|
||||
#define NS_LOCK_INSTANCE() \
|
||||
PR_CEnterMonitor((void*)this)
|
||||
|
||||
#define NS_UNLOCK_INSTANCE() \
|
||||
PR_CExitMonitor((void*)this)
|
||||
|
||||
/**
|
||||
* Use this macro to implement the AddRef method for a given <i>_class</i>
|
||||
* @param _class The name of the class implementing the method
|
||||
*/
|
||||
#if defined(XP_PC)
|
||||
#define NS_IMPL_THREADSAFE_ADDREF(_class) \
|
||||
NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
|
||||
{ \
|
||||
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
|
||||
return InterlockedIncrement((LONG*)&mRefCnt); \
|
||||
}
|
||||
|
||||
#else /* ! XP_PC */
|
||||
#define NS_IMPL_THREADSAFE_ADDREF(_class) \
|
||||
nsrefcnt _class::AddRef(void) \
|
||||
{ \
|
||||
nsrefcnt count; \
|
||||
NS_LOCK_INSTANCE(); \
|
||||
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
|
||||
count = ++mRefCnt; \
|
||||
NS_UNLOCK_INSTANCE(); \
|
||||
return count; \
|
||||
}
|
||||
#endif /* ! XP_PC */
|
||||
|
||||
/**
|
||||
* Use this macro to implement the Release method for a given <i>_class</i>
|
||||
* @param _class The name of the class implementing the method
|
||||
*/
|
||||
#if defined(XP_PC)
|
||||
#define NS_IMPL_THREADSAFE_RELEASE(_class) \
|
||||
NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
|
||||
{ \
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
|
||||
if (0 == InterlockedDecrement((LONG*)&mRefCnt)) { \
|
||||
NS_DELETEXPCOM(this); \
|
||||
return 0; \
|
||||
} \
|
||||
return mRefCnt; /* Not threadsafe but who cares. */ \
|
||||
}
|
||||
|
||||
#else /* ! XP_PC */
|
||||
#define NS_IMPL_THREADSAFE_RELEASE(_class) \
|
||||
nsrefcnt _class::Release(void) \
|
||||
{ \
|
||||
nsrefcnt count; \
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
|
||||
NS_LOCK_INSTANCE(); \
|
||||
count = --mRefCnt; \
|
||||
NS_UNLOCK_INSTANCE(); \
|
||||
if (0 == count) { \
|
||||
NS_DELETEXPCOM(this); \
|
||||
return 0; \
|
||||
} \
|
||||
return count; \
|
||||
}
|
||||
#endif /* ! XP_PC */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* Some convenience macros for implementing QueryInterface
|
||||
*/
|
||||
|
||||
/**
|
||||
* This implements query interface with two assumptions: First, the
|
||||
* class in question implements nsISupports and it's own interface and
|
||||
* nothing else. Second, the implementation of the class's primary
|
||||
* inheritance chain leads to it's own interface.
|
||||
*
|
||||
* @param _class The name of the class implementing the method
|
||||
* @param _classiiddef The name of the #define symbol that defines the IID
|
||||
* for the class (e.g. NS_ISUPPORTS_IID)
|
||||
*/
|
||||
#if defined(NS_DEBUG)
|
||||
#define NS_VERIFY_THREADSAFE_INTERFACE(_iface) \
|
||||
if (NULL != (_iface)) { \
|
||||
nsISupports* tmp; \
|
||||
static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID); \
|
||||
NS_PRECONDITION((NS_OK == _iface->QueryInterface(kIsThreadsafeIID, \
|
||||
(void**)&tmp)), \
|
||||
"Interface is not threadsafe"); \
|
||||
}
|
||||
|
||||
#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \
|
||||
NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
|
||||
{ \
|
||||
if (NULL == aInstancePtr) { \
|
||||
return NS_ERROR_NULL_POINTER; \
|
||||
} \
|
||||
\
|
||||
*aInstancePtr = NULL; \
|
||||
\
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); \
|
||||
static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID); \
|
||||
static NS_DEFINE_IID(kClassIID, _classiiddef); \
|
||||
if (aIID.Equals(kClassIID)) { \
|
||||
*aInstancePtr = (void*) this; \
|
||||
NS_ADDREF_THIS(); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
if (aIID.Equals(kISupportsIID)) { \
|
||||
*aInstancePtr = (void*) ((nsISupports*)this); \
|
||||
NS_ADDREF_THIS(); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
if (aIID.Equals(kIsThreadsafeIID)) { \
|
||||
return NS_OK; \
|
||||
} \
|
||||
return NS_NOINTERFACE; \
|
||||
}
|
||||
|
||||
#else /* !NS_DEBUG */
|
||||
|
||||
#define NS_VERIFY_THREADSAFE_INTERFACE(_iface)
|
||||
#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \
|
||||
NS_IMPL_QUERY_INTERFACE(_class, _classiiddef)
|
||||
|
||||
#endif /* !NS_DEBUG */
|
||||
|
||||
/**
|
||||
* Convenience macro for implementing all nsISupports methods for
|
||||
* a simple class.
|
||||
* @param _class The name of the class implementing the method
|
||||
* @param _classiiddef The name of the #define symbol that defines the IID
|
||||
* for the class (e.g. NS_ISUPPORTS_IID)
|
||||
*/
|
||||
|
||||
#define NS_IMPL_THREADSAFE_ISUPPORTS(_class,_classiiddef) \
|
||||
NS_IMPL_THREADSAFE_ADDREF(_class) \
|
||||
NS_IMPL_THREADSAFE_RELEASE(_class) \
|
||||
NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef)
|
||||
|
||||
#else /* !NS_MT_SUPPORTED */
|
||||
|
||||
#define NS_LOCK_INSTANCE()
|
||||
|
||||
#define NS_UNLOCK_INSTANCE()
|
||||
|
||||
#define NS_IMPL_THREADSAFE_ADDREF(_class) NS_IMPL_ADDREF(_class)
|
||||
|
||||
#define NS_IMPL_THREADSAFE_RELEASE(_class) NS_IMPL_RELEASE(_class)
|
||||
|
||||
#define NS_VERIFY_THREADSAFE_INTERFACE(_iface)
|
||||
|
||||
#define NS_IMPL_THREADSAFE_QUERY_INTERFACE(_class,_classiiddef) \
|
||||
NS_IMPL_QUERY_INTERFACE(_class, _classiiddef)
|
||||
|
||||
#define NS_IMPL_THREADSAFE_ISUPPORTS(_class,_classiiddef) \
|
||||
NS_IMPL_ADDREF(_class) \
|
||||
NS_IMPL_RELEASE(_class) \
|
||||
NS_IMPL_QUERY_INTERFACE(_class,_classiiddef)
|
||||
|
||||
#endif /* !NS_MT_SUPPORTED */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Debugging Macros
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Macro for instantiating a new object that implements nsISupports.
|
||||
* Use this in your factory methods to allow for refcnt tracing.
|
||||
* Note that you can only use this if you adhere to the no arguments
|
||||
* constructor com policy (which you really should!).
|
||||
* @param _result Where the new instance pointer is stored
|
||||
* @param _type The type of object to call "new" with.
|
||||
*/
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
#define NS_NEWXPCOM(_result,_type) \
|
||||
PR_BEGIN_MACRO \
|
||||
_result = new _type(); \
|
||||
nsTraceRefcnt::Create(_result, #_type, __FILE__, __LINE__); \
|
||||
PR_END_MACRO
|
||||
#else
|
||||
#define NS_NEWXPCOM(_result,_type) \
|
||||
_result = new _type()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Macro for deleting an object that implements nsISupports.
|
||||
* Use this in your Release methods to allow for refcnt tracing.
|
||||
* @param _ptr The object to delete.
|
||||
*/
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
#define NS_DELETEXPCOM(_ptr) \
|
||||
PR_BEGIN_MACRO \
|
||||
nsTraceRefcnt::Destroy((_ptr), __FILE__, __LINE__); \
|
||||
delete (_ptr); \
|
||||
PR_END_MACRO
|
||||
#else
|
||||
#define NS_DELETEXPCOM(_ptr) \
|
||||
delete (_ptr)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Macro for adding a reference to an interface.
|
||||
* @param _ptr The interface pointer.
|
||||
*/
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
#define NS_ADDREF(_ptr) \
|
||||
((nsrefcnt) nsTraceRefcnt::AddRef((_ptr), (_ptr)->AddRef(), \
|
||||
__FILE__, __LINE__))
|
||||
#else
|
||||
#define NS_ADDREF(_ptr) \
|
||||
(_ptr)->AddRef()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Macro for adding a reference to this. This macro should be used
|
||||
* because NS_ADDREF (when tracing) may require an ambiguous cast
|
||||
* from the pointers primary type to nsISupports. This macro sidesteps
|
||||
* that entire problem.
|
||||
*/
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
#define NS_ADDREF_THIS() \
|
||||
((nsrefcnt) nsTraceRefcnt::AddRef(this, AddRef(), __FILE__, __LINE__))
|
||||
#else
|
||||
#define NS_ADDREF_THIS() \
|
||||
AddRef()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Macro for adding a reference to an interface that checks for NULL.
|
||||
* @param _ptr The interface pointer.
|
||||
*/
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
#define NS_IF_ADDREF(_ptr) \
|
||||
((0 != (_ptr)) \
|
||||
? ((nsrefcnt) nsTraceRefcnt::AddRef((_ptr), (_ptr)->AddRef(), __FILE__, \
|
||||
__LINE__)) \
|
||||
: 0)
|
||||
#else
|
||||
#define NS_IF_ADDREF(_ptr) \
|
||||
((0 != (_ptr)) ? (_ptr)->AddRef() : 0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Macro for releasing a reference to an interface.
|
||||
*
|
||||
* Note that when MOZ_TRACE_XPCOM_REFCNT is defined that the release will
|
||||
* be done before the trace message is logged. If the reference count
|
||||
* goes to zero and implementation of Release logs a message, the two
|
||||
* messages will be logged out of order.
|
||||
*
|
||||
* @param _ptr The interface pointer.
|
||||
*/
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
#define NS_RELEASE(_ptr) \
|
||||
PR_BEGIN_MACRO \
|
||||
nsTraceRefcnt::Release((_ptr), (_ptr)->Release(), __FILE__, __LINE__); \
|
||||
(_ptr) = 0; \
|
||||
PR_END_MACRO
|
||||
#else
|
||||
#define NS_RELEASE(_ptr) \
|
||||
PR_BEGIN_MACRO \
|
||||
(_ptr)->Release(); \
|
||||
(_ptr) = 0; \
|
||||
PR_END_MACRO
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Macro for releasing a reference to an interface.
|
||||
*
|
||||
* Note that when MOZ_TRACE_XPCOM_REFCNT is defined that the release will
|
||||
* be done before the trace message is logged. If the reference count
|
||||
* goes to zero and implementation of Release logs a message, the two
|
||||
* messages will be logged out of order.
|
||||
*
|
||||
* @param _ptr The interface pointer.
|
||||
*/
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
#define NS_RELEASE_THIS() \
|
||||
nsTraceRefcnt::Release(this, Release(), __FILE__, __LINE__)
|
||||
#else
|
||||
#define NS_RELEASE_THIS() \
|
||||
Release()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Macro for releasing a reference to an interface, except that this
|
||||
* macro preserves the return value from the underlying Release call.
|
||||
* The interface pointer argument will only be NULLed if the reference count
|
||||
* goes to zero.
|
||||
*
|
||||
* Note that when MOZ_TRACE_XPCOM_REFCNT is defined that the release will
|
||||
* be done before the trace message is logged. If the reference count
|
||||
* goes to zero and implementation of Release logs a message, the two
|
||||
* messages will be logged out of order.
|
||||
*
|
||||
* @param _ptr The interface pointer.
|
||||
*/
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
#define NS_RELEASE2(_ptr, _result) \
|
||||
PR_BEGIN_MACRO \
|
||||
_result = ((nsrefcnt) nsTraceRefcnt::Release((_ptr), (_ptr)->Release(), \
|
||||
__FILE__, __LINE__)); \
|
||||
if (0 == (_result)) (_ptr) = 0; \
|
||||
PR_END_MACRO
|
||||
#else
|
||||
#define NS_RELEASE2(_ptr, _result) \
|
||||
PR_BEGIN_MACRO \
|
||||
_result = (_ptr)->Release(); \
|
||||
if (0 == (_result)) (_ptr) = 0; \
|
||||
PR_END_MACRO
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Macro for releasing a reference to an interface that checks for NULL;
|
||||
*
|
||||
* Note that when MOZ_TRACE_XPCOM_REFCNT is defined that the release will
|
||||
* be done before the trace message is logged. If the reference count
|
||||
* goes to zero and implementation of Release logs a message, the two
|
||||
* messages will be logged out of order.
|
||||
*
|
||||
* @param _ptr The interface pointer.
|
||||
*/
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
#define NS_IF_RELEASE(_ptr) \
|
||||
PR_BEGIN_MACRO \
|
||||
((0 != (_ptr)) \
|
||||
? ((nsrefcnt) nsTraceRefcnt::Release((_ptr), (_ptr)->Release(), \
|
||||
__FILE__, __LINE__)) \
|
||||
: 0); \
|
||||
(_ptr) = 0; \
|
||||
PR_END_MACRO
|
||||
#else
|
||||
#define NS_IF_RELEASE(_ptr) \
|
||||
PR_BEGIN_MACRO \
|
||||
((0 != (_ptr)) ? (_ptr)->Release() : 0); \
|
||||
(_ptr) = 0; \
|
||||
PR_END_MACRO
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_LOG_REFCNT
|
||||
#define NS_LOG_ADDREF(_ptr, _refcnt, _file, _line) \
|
||||
nsTraceRefcnt::LogAddRef((_ptr), (_refcnt), (_file), (_line))
|
||||
|
||||
#define NS_LOG_RELEASE(_ptr, _refcnt, _file, _line) \
|
||||
nsTraceRefcnt::LogRelease((_ptr), (_refcnt), (_file), (_line))
|
||||
|
||||
#else
|
||||
#define NS_LOG_ADDREF(_file, _line, _ptr, _refcnt)
|
||||
#define NS_LOG_RELEASE(_file, _line, _ptr, _refcnt)
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// A type-safe interface for calling |QueryInterface()|. A similar implementation
|
||||
// exists in "nsCOMPtr.h" for use with |nsCOMPtr|s.
|
||||
|
||||
extern "C++" {
|
||||
// ...because some one is accidentally including this file inside an |extern "C"|
|
||||
|
||||
class nsISupports;
|
||||
|
||||
template <class T>
|
||||
struct nsCOMTypeInfo
|
||||
{
|
||||
static const nsIID& GetIID() { return T::GetIID(); }
|
||||
};
|
||||
|
||||
#ifdef NSCAP_FEATURE_HIDE_NSISUPPORTS_GETIID
|
||||
template <>
|
||||
struct nsCOMTypeInfo<nsISupports>
|
||||
{
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_ISUPPORTS_IID; return iid; }
|
||||
};
|
||||
#endif
|
||||
|
||||
#define NS_GET_IID(T) nsCOMTypeInfo<T>::GetIID()
|
||||
|
||||
template <class DestinationType>
|
||||
inline
|
||||
nsresult
|
||||
CallQueryInterface( nsISupports* aSource, DestinationType** aDestination )
|
||||
// a type-safe shortcut for calling the |QueryInterface()| member function
|
||||
{
|
||||
NS_PRECONDITION(aSource, "null parameter");
|
||||
NS_PRECONDITION(aDestination, "null parameter");
|
||||
|
||||
return aSource->QueryInterface(nsCOMTypeInfo<DestinationType>::GetIID(), (void**)aDestination);
|
||||
}
|
||||
|
||||
} // extern "C++"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif /* __nsISupportsUtils_h */
|
||||
486
mozilla/xpcom/base/nsTraceRefcnt.cpp
Normal file
486
mozilla/xpcom/base/nsTraceRefcnt.cpp
Normal file
@@ -0,0 +1,486 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
#include "nsISupports.h"
|
||||
#include "prprf.h"
|
||||
#include "prlog.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#elif defined(linux) && defined(__GLIBC__) && defined(__i386)
|
||||
#include <setjmp.h>
|
||||
|
||||
//
|
||||
// On glibc 2.1, the Dl_info api defined in <dlfcn.h> is only exposed
|
||||
// if __USE_GNU is defined. I suppose its some kind of standards
|
||||
// adherence thing.
|
||||
//
|
||||
#if (__GLIBC_MINOR__ >= 1)
|
||||
#define __USE_GNU
|
||||
#endif
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(NS_MT_SUPPORTED)
|
||||
#include "prlock.h"
|
||||
|
||||
static PRLock* gTraceLock;
|
||||
|
||||
#define LOCK_TRACELOG() PR_Lock(gTraceLock)
|
||||
#define UNLOCK_TRACELOG() PR_Unlock(gTraceLock)
|
||||
#else /* ! NT_MT_SUPPORTED */
|
||||
#define LOCK_TRACELOG()
|
||||
#define UNLOCK_TRACELOG()
|
||||
#endif /* ! NS_MT_SUPPORTED */
|
||||
|
||||
static PRLogModuleInfo* gTraceRefcntLog;
|
||||
|
||||
static void InitTraceLog(void)
|
||||
{
|
||||
if (0 == gTraceRefcntLog) {
|
||||
gTraceRefcntLog = PR_NewLogModule("xpcomrefcnt");
|
||||
|
||||
#if defined(NS_MT_SUPPORTED)
|
||||
gTraceLock = PR_NewLock();
|
||||
#endif /* NS_MT_SUPPORTED */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int nsIToA16(PRUint32 aNumber, char* aBuffer)
|
||||
{
|
||||
static char kHex[] = "0123456789abcdef";
|
||||
|
||||
if (aNumber == 0) {
|
||||
*aBuffer = '0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
char buf[8];
|
||||
PRInt32 count = 0;
|
||||
while (aNumber != 0) {
|
||||
PRUint32 nibble = aNumber & 0xf;
|
||||
buf[count++] = kHex[nibble];
|
||||
aNumber >>= 4;
|
||||
}
|
||||
|
||||
for (PRInt32 i = count - 1; i >= 0; --i)
|
||||
*aBuffer++ = buf[i];
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) // WIN32 stack walking code
|
||||
#include "imagehlp.h"
|
||||
#include <stdio.h>
|
||||
|
||||
// Define these as static pointers so that we can load the DLL on the
|
||||
// fly (and not introduce a link-time dependency on it). Tip o' the
|
||||
// hat to Matt Pietrick for this idea. See:
|
||||
//
|
||||
// http://msdn.microsoft.com/library/periodic/period97/F1/D3/S245C6.htm
|
||||
//
|
||||
typedef BOOL (__stdcall *SYMINITIALIZEPROC)(HANDLE, LPSTR, BOOL);
|
||||
static SYMINITIALIZEPROC _SymInitialize;
|
||||
|
||||
typedef BOOL (__stdcall *SYMCLEANUPPROC)(HANDLE);
|
||||
static SYMCLEANUPPROC _SymCleanup;
|
||||
|
||||
typedef BOOL (__stdcall *STACKWALKPROC)(DWORD,
|
||||
HANDLE,
|
||||
HANDLE,
|
||||
LPSTACKFRAME,
|
||||
LPVOID,
|
||||
PREAD_PROCESS_MEMORY_ROUTINE,
|
||||
PFUNCTION_TABLE_ACCESS_ROUTINE,
|
||||
PGET_MODULE_BASE_ROUTINE,
|
||||
PTRANSLATE_ADDRESS_ROUTINE);
|
||||
static STACKWALKPROC _StackWalk;
|
||||
|
||||
typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC)(HANDLE, DWORD);
|
||||
static SYMFUNCTIONTABLEACCESSPROC _SymFunctionTableAccess;
|
||||
|
||||
typedef DWORD (__stdcall *SYMGETMODULEBASEPROC)(HANDLE, DWORD);
|
||||
static SYMGETMODULEBASEPROC _SymGetModuleBase;
|
||||
|
||||
typedef BOOL (__stdcall *SYMGETSYMFROMADDRPROC)(HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL);
|
||||
static SYMGETSYMFROMADDRPROC _SymGetSymFromAddr;
|
||||
|
||||
|
||||
static PRBool
|
||||
EnsureSymInitialized()
|
||||
{
|
||||
PRBool gInitialized = PR_FALSE;
|
||||
|
||||
if (! gInitialized) {
|
||||
HMODULE module = ::LoadLibrary("IMAGEHLP.DLL");
|
||||
if (!module) return PR_FALSE;
|
||||
|
||||
_SymInitialize = (SYMINITIALIZEPROC) ::GetProcAddress(module, "SymInitialize");
|
||||
if (!_SymInitialize) return PR_FALSE;
|
||||
|
||||
_SymCleanup = (SYMCLEANUPPROC)GetProcAddress(module, "SymCleanup");
|
||||
if (!_SymCleanup) return PR_FALSE;
|
||||
|
||||
_StackWalk = (STACKWALKPROC)GetProcAddress(module, "StackWalk");
|
||||
if (!_StackWalk) return PR_FALSE;
|
||||
|
||||
_SymFunctionTableAccess = (SYMFUNCTIONTABLEACCESSPROC) GetProcAddress(module, "SymFunctionTableAccess");
|
||||
if (!_SymFunctionTableAccess) return PR_FALSE;
|
||||
|
||||
_SymGetModuleBase = (SYMGETMODULEBASEPROC)GetProcAddress(module, "SymGetModuleBase");
|
||||
if (!_SymGetModuleBase) return PR_FALSE;
|
||||
|
||||
_SymGetSymFromAddr = (SYMGETSYMFROMADDRPROC)GetProcAddress(module, "SymGetSymFromAddr");
|
||||
if (!_SymGetSymFromAddr) return PR_FALSE;
|
||||
|
||||
gInitialized = _SymInitialize(GetCurrentProcess(), 0, TRUE);
|
||||
}
|
||||
|
||||
return gInitialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk the stack, translating PC's found into strings and recording the
|
||||
* chain in aBuffer. For this to work properly, the dll's must be rebased
|
||||
* so that the address in the file agrees with the address in memory.
|
||||
* Otherwise StackWalk will return FALSE when it hits a frame in a dll's
|
||||
* whose in memory address doesn't match it's in-file address.
|
||||
*
|
||||
* Fortunately, there is a handy dandy routine in IMAGEHLP.DLL that does
|
||||
* the rebasing and accordingly I've made a tool to use it to rebase the
|
||||
* DLL's in one fell swoop (see xpcom/tools/windows/rebasedlls.cpp).
|
||||
*/
|
||||
void
|
||||
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
|
||||
{
|
||||
aBuffer[0] = '\0';
|
||||
aBufLen--; // leave room for nul
|
||||
|
||||
HANDLE myProcess = ::GetCurrentProcess();
|
||||
HANDLE myThread = ::GetCurrentThread();
|
||||
|
||||
BOOL ok;
|
||||
|
||||
ok = EnsureSymInitialized();
|
||||
if (! ok)
|
||||
return;
|
||||
|
||||
// Get the context information for this thread. That way we will
|
||||
// know where our sp, fp, pc, etc. are and can fill in the
|
||||
// STACKFRAME with the initial values.
|
||||
CONTEXT context;
|
||||
context.ContextFlags = CONTEXT_FULL;
|
||||
ok = GetThreadContext(myThread, &context);
|
||||
if (! ok)
|
||||
return;
|
||||
|
||||
// Setup initial stack frame to walk from
|
||||
STACKFRAME frame;
|
||||
memset(&frame, 0, sizeof(frame));
|
||||
frame.AddrPC.Offset = context.Eip;
|
||||
frame.AddrPC.Mode = AddrModeFlat;
|
||||
frame.AddrStack.Offset = context.Esp;
|
||||
frame.AddrStack.Mode = AddrModeFlat;
|
||||
frame.AddrFrame.Offset = context.Ebp;
|
||||
frame.AddrFrame.Mode = AddrModeFlat;
|
||||
|
||||
// Now walk the stack and map the pc's to symbol names that we stuff
|
||||
// append to *cp.
|
||||
char* cp = aBuffer;
|
||||
|
||||
int skip = 2;
|
||||
while (aBufLen > 0) {
|
||||
ok = _StackWalk(IMAGE_FILE_MACHINE_I386,
|
||||
myProcess,
|
||||
myThread,
|
||||
&frame,
|
||||
&context,
|
||||
0, // read process memory routine
|
||||
_SymFunctionTableAccess, // function table access routine
|
||||
_SymGetModuleBase, // module base routine
|
||||
0); // translate address routine
|
||||
|
||||
if (!ok || frame.AddrPC.Offset == 0)
|
||||
break;
|
||||
|
||||
if (skip-- > 0)
|
||||
continue;
|
||||
|
||||
char buf[sizeof(IMAGEHLP_SYMBOL) + 512];
|
||||
PIMAGEHLP_SYMBOL symbol = (PIMAGEHLP_SYMBOL) buf;
|
||||
symbol->SizeOfStruct = sizeof(buf);
|
||||
symbol->MaxNameLength = 512;
|
||||
|
||||
DWORD displacement;
|
||||
ok = _SymGetSymFromAddr(myProcess,
|
||||
frame.AddrPC.Offset,
|
||||
&displacement,
|
||||
symbol);
|
||||
|
||||
if (ok) {
|
||||
int nameLen = strlen(symbol->Name);
|
||||
if (nameLen + 12 > aBufLen) { // 12 == strlen("+0x12345678 ")
|
||||
break;
|
||||
}
|
||||
char* cp2 = symbol->Name;
|
||||
while (*cp2) {
|
||||
if (*cp2 == ' ') *cp2 = '_'; // replace spaces with underscores
|
||||
*cp++ = *cp2++;
|
||||
}
|
||||
aBufLen -= nameLen;
|
||||
*cp++ = '+';
|
||||
*cp++ = '0';
|
||||
*cp++ = 'x';
|
||||
PRInt32 len = nsIToA16(displacement, cp);
|
||||
cp += len;
|
||||
*cp++ = ' ';
|
||||
|
||||
aBufLen -= nameLen + len + 4;
|
||||
}
|
||||
else {
|
||||
if (11 > aBufLen) { // 11 == strlen("0x12345678 ")
|
||||
break;
|
||||
}
|
||||
*cp++ = '0';
|
||||
*cp++ = 'x';
|
||||
PRInt32 len = nsIToA16(frame.AddrPC.Offset, cp);
|
||||
cp += len;
|
||||
*cp++ = ' ';
|
||||
aBufLen -= len + 3;
|
||||
}
|
||||
}
|
||||
*cp = 0;
|
||||
}
|
||||
/* _WIN32 */
|
||||
|
||||
|
||||
#elif defined(linux) && defined(__GLIBC__) && defined(__i386) // i386 Linux stackwalking code
|
||||
|
||||
void
|
||||
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
|
||||
{
|
||||
aBuffer[0] = '\0';
|
||||
aBufLen--; // leave room for nul
|
||||
|
||||
char* cp = aBuffer;
|
||||
|
||||
jmp_buf jb;
|
||||
setjmp(jb);
|
||||
|
||||
// Stack walking code courtesy Kipp's "leaky".
|
||||
u_long* bp = (u_long*) (jb[0].__jmpbuf[JB_BP]);
|
||||
int skip = 2;
|
||||
for (;;) {
|
||||
u_long* nextbp = (u_long*) *bp++;
|
||||
u_long pc = *bp;
|
||||
if ((pc < 0x08000000) || (pc > 0x7fffffff) || (nextbp < bp)) {
|
||||
break;
|
||||
}
|
||||
if (--skip <= 0) {
|
||||
Dl_info info;
|
||||
int ok = dladdr((void*) pc, &info);
|
||||
if (ok < 0)
|
||||
break;
|
||||
|
||||
int len = strlen(info.dli_sname);
|
||||
if (! len)
|
||||
break; // XXX Lazy. We could look at the filename or something.
|
||||
|
||||
if (len + 12 >= aBufLen) // 12 == strlen("+0x12345678 ")
|
||||
break;
|
||||
|
||||
strcpy(cp, info.dli_sname);
|
||||
cp += len;
|
||||
|
||||
*cp++ = '+';
|
||||
*cp++ = '0';
|
||||
*cp++ = 'x';
|
||||
|
||||
PRUint32 off = (char*)pc - (char*)info.dli_saddr;
|
||||
PRInt32 addrStrLen = nsIToA16(off, cp);
|
||||
cp += addrStrLen;
|
||||
|
||||
*cp++ = ' ';
|
||||
|
||||
aBufLen -= addrStrLen + 4;
|
||||
}
|
||||
bp = nextbp;
|
||||
}
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
#else // unsupported platform.
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
|
||||
{
|
||||
// Write me!!!
|
||||
*aBuffer = '\0';
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
|
||||
void* aLibrayHandle)
|
||||
{
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
#if defined(_WIN32)
|
||||
InitTraceLog();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
|
||||
HANDLE myProcess = ::GetCurrentProcess();
|
||||
|
||||
if (!SymInitialize(myProcess, ".;..\\lib", TRUE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL b = ::SymLoadModule(myProcess,
|
||||
NULL,
|
||||
(char*)aLibraryName,
|
||||
(char*)aLibraryName,
|
||||
0,
|
||||
0);
|
||||
// DWORD lastError = 0;
|
||||
// if (!b) lastError = ::GetLastError();
|
||||
// printf("loading symbols for library %s => %s [%d]\n", aLibraryName,
|
||||
// b ? "true" : "false", lastError);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_COM unsigned long
|
||||
nsTraceRefcnt::AddRef(void* aPtr,
|
||||
unsigned long aNewRefcnt,
|
||||
const char* aFile,
|
||||
PRIntn aLine)
|
||||
{
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
InitTraceLog();
|
||||
|
||||
LOCK_TRACELOG();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
|
||||
char sb[1000];
|
||||
WalkTheStack(sb, sizeof(sb));
|
||||
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
|
||||
("AddRef: %p: %d=>%d [%s] in %s (line %d)",
|
||||
aPtr, aNewRefcnt-1, aNewRefcnt, sb, aFile, aLine));
|
||||
}
|
||||
UNLOCK_TRACELOG();
|
||||
#endif
|
||||
return aNewRefcnt;
|
||||
|
||||
}
|
||||
|
||||
NS_COM unsigned long
|
||||
nsTraceRefcnt::Release(void* aPtr,
|
||||
unsigned long aNewRefcnt,
|
||||
const char* aFile,
|
||||
PRIntn aLine)
|
||||
{
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
InitTraceLog();
|
||||
|
||||
LOCK_TRACELOG();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
|
||||
char sb[1000];
|
||||
WalkTheStack(sb, sizeof(sb));
|
||||
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
|
||||
("Release: %p: %d=>%d [%s] in %s (line %d)",
|
||||
aPtr, aNewRefcnt+1, aNewRefcnt, sb, aFile, aLine));
|
||||
}
|
||||
UNLOCK_TRACELOG();
|
||||
#endif
|
||||
return aNewRefcnt;
|
||||
}
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcnt::Create(void* aPtr,
|
||||
const char* aType,
|
||||
const char* aFile,
|
||||
PRIntn aLine)
|
||||
{
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
InitTraceLog();
|
||||
|
||||
LOCK_TRACELOG();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
|
||||
char sb[1000];
|
||||
WalkTheStack(sb, sizeof(sb));
|
||||
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
|
||||
("Create: %p[%s]: [%s] in %s (line %d)",
|
||||
aPtr, aType, sb, aFile, aLine));
|
||||
}
|
||||
UNLOCK_TRACELOG();
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcnt::Destroy(void* aPtr,
|
||||
const char* aFile,
|
||||
PRIntn aLine)
|
||||
{
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
InitTraceLog();
|
||||
|
||||
LOCK_TRACELOG();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
|
||||
char sb[1000];
|
||||
WalkTheStack(sb, sizeof(sb));
|
||||
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
|
||||
("Destroy: %p: [%s] in %s (line %d)",
|
||||
aPtr, sb, aFile, aLine));
|
||||
}
|
||||
UNLOCK_TRACELOG();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcnt::LogAddRef(void* aPtr,
|
||||
nsrefcnt aRefCnt,
|
||||
const char* aFile,
|
||||
int aLine)
|
||||
{
|
||||
InitTraceLog();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog, PR_LOG_DEBUG)) {
|
||||
char sb[16384];
|
||||
WalkTheStack(sb, sizeof(sb));
|
||||
// Can't use PR_LOG(), b/c it truncates the line
|
||||
printf("%s(%d) %p AddRef %d %s\n", aFile, aLine, aPtr, aRefCnt, sb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcnt::LogRelease(void* aPtr,
|
||||
nsrefcnt aRefCnt,
|
||||
const char* aFile,
|
||||
int aLine)
|
||||
{
|
||||
InitTraceLog();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog, PR_LOG_DEBUG)) {
|
||||
char sb[16384];
|
||||
WalkTheStack(sb, sizeof(sb));
|
||||
// Can't use PR_LOG(), b/c it truncates the line
|
||||
printf("%s(%d) %p Release %d %s\n", aFile, aLine, aPtr, aRefCnt, sb);
|
||||
}
|
||||
}
|
||||
72
mozilla/xpcom/base/nsTraceRefcnt.h
Normal file
72
mozilla/xpcom/base/nsTraceRefcnt.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
#ifndef nsTraceRefcnt_h___
|
||||
#define nsTraceRefcnt_h___
|
||||
|
||||
#include "nsCom.h"
|
||||
|
||||
/**
|
||||
* This class is used to support tracing (and logging using nspr) of
|
||||
* addref and release calls. Note that only calls that use the
|
||||
* NS_ADDREF and related macros in nsISupports can be traced.
|
||||
*
|
||||
* The name of the nspr log module is "xpcomrefcnt" (case matters).
|
||||
*
|
||||
* This code only performs tracing built with debugging AND when
|
||||
* built with -DMOZ_TRACE_XPCOM_REFCNT (because it's expensive!).
|
||||
*/
|
||||
class nsTraceRefcnt {
|
||||
public:
|
||||
static NS_COM unsigned long AddRef(void* aPtr,
|
||||
unsigned long aNewRefcnt,
|
||||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
static NS_COM unsigned long Release(void* aPtr,
|
||||
unsigned long aNewRefcnt,
|
||||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
static NS_COM void Create(void* aPtr,
|
||||
const char* aType,
|
||||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
static NS_COM void Destroy(void* aPtr,
|
||||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
static NS_COM void LoadLibrarySymbols(const char* aLibraryName,
|
||||
void* aLibrayHandle);
|
||||
|
||||
static NS_COM void WalkTheStack(char* aBuffer, int aBufLen);
|
||||
|
||||
static NS_COM void LogAddRef(void* aPtr,
|
||||
nsrefcnt aRefCnt,
|
||||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
static NS_COM void LogRelease(void* aPtr,
|
||||
nsrefcnt aRefCnt,
|
||||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
};
|
||||
|
||||
#endif /* nsTraceRefcnt_h___ */
|
||||
486
mozilla/xpcom/base/nsTraceRefcntImpl.cpp
Normal file
486
mozilla/xpcom/base/nsTraceRefcntImpl.cpp
Normal file
@@ -0,0 +1,486 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
#include "nsISupports.h"
|
||||
#include "prprf.h"
|
||||
#include "prlog.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#elif defined(linux) && defined(__GLIBC__) && defined(__i386)
|
||||
#include <setjmp.h>
|
||||
|
||||
//
|
||||
// On glibc 2.1, the Dl_info api defined in <dlfcn.h> is only exposed
|
||||
// if __USE_GNU is defined. I suppose its some kind of standards
|
||||
// adherence thing.
|
||||
//
|
||||
#if (__GLIBC_MINOR__ >= 1)
|
||||
#define __USE_GNU
|
||||
#endif
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(NS_MT_SUPPORTED)
|
||||
#include "prlock.h"
|
||||
|
||||
static PRLock* gTraceLock;
|
||||
|
||||
#define LOCK_TRACELOG() PR_Lock(gTraceLock)
|
||||
#define UNLOCK_TRACELOG() PR_Unlock(gTraceLock)
|
||||
#else /* ! NT_MT_SUPPORTED */
|
||||
#define LOCK_TRACELOG()
|
||||
#define UNLOCK_TRACELOG()
|
||||
#endif /* ! NS_MT_SUPPORTED */
|
||||
|
||||
static PRLogModuleInfo* gTraceRefcntLog;
|
||||
|
||||
static void InitTraceLog(void)
|
||||
{
|
||||
if (0 == gTraceRefcntLog) {
|
||||
gTraceRefcntLog = PR_NewLogModule("xpcomrefcnt");
|
||||
|
||||
#if defined(NS_MT_SUPPORTED)
|
||||
gTraceLock = PR_NewLock();
|
||||
#endif /* NS_MT_SUPPORTED */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int nsIToA16(PRUint32 aNumber, char* aBuffer)
|
||||
{
|
||||
static char kHex[] = "0123456789abcdef";
|
||||
|
||||
if (aNumber == 0) {
|
||||
*aBuffer = '0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
char buf[8];
|
||||
PRInt32 count = 0;
|
||||
while (aNumber != 0) {
|
||||
PRUint32 nibble = aNumber & 0xf;
|
||||
buf[count++] = kHex[nibble];
|
||||
aNumber >>= 4;
|
||||
}
|
||||
|
||||
for (PRInt32 i = count - 1; i >= 0; --i)
|
||||
*aBuffer++ = buf[i];
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) // WIN32 stack walking code
|
||||
#include "imagehlp.h"
|
||||
#include <stdio.h>
|
||||
|
||||
// Define these as static pointers so that we can load the DLL on the
|
||||
// fly (and not introduce a link-time dependency on it). Tip o' the
|
||||
// hat to Matt Pietrick for this idea. See:
|
||||
//
|
||||
// http://msdn.microsoft.com/library/periodic/period97/F1/D3/S245C6.htm
|
||||
//
|
||||
typedef BOOL (__stdcall *SYMINITIALIZEPROC)(HANDLE, LPSTR, BOOL);
|
||||
static SYMINITIALIZEPROC _SymInitialize;
|
||||
|
||||
typedef BOOL (__stdcall *SYMCLEANUPPROC)(HANDLE);
|
||||
static SYMCLEANUPPROC _SymCleanup;
|
||||
|
||||
typedef BOOL (__stdcall *STACKWALKPROC)(DWORD,
|
||||
HANDLE,
|
||||
HANDLE,
|
||||
LPSTACKFRAME,
|
||||
LPVOID,
|
||||
PREAD_PROCESS_MEMORY_ROUTINE,
|
||||
PFUNCTION_TABLE_ACCESS_ROUTINE,
|
||||
PGET_MODULE_BASE_ROUTINE,
|
||||
PTRANSLATE_ADDRESS_ROUTINE);
|
||||
static STACKWALKPROC _StackWalk;
|
||||
|
||||
typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC)(HANDLE, DWORD);
|
||||
static SYMFUNCTIONTABLEACCESSPROC _SymFunctionTableAccess;
|
||||
|
||||
typedef DWORD (__stdcall *SYMGETMODULEBASEPROC)(HANDLE, DWORD);
|
||||
static SYMGETMODULEBASEPROC _SymGetModuleBase;
|
||||
|
||||
typedef BOOL (__stdcall *SYMGETSYMFROMADDRPROC)(HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL);
|
||||
static SYMGETSYMFROMADDRPROC _SymGetSymFromAddr;
|
||||
|
||||
|
||||
static PRBool
|
||||
EnsureSymInitialized()
|
||||
{
|
||||
PRBool gInitialized = PR_FALSE;
|
||||
|
||||
if (! gInitialized) {
|
||||
HMODULE module = ::LoadLibrary("IMAGEHLP.DLL");
|
||||
if (!module) return PR_FALSE;
|
||||
|
||||
_SymInitialize = (SYMINITIALIZEPROC) ::GetProcAddress(module, "SymInitialize");
|
||||
if (!_SymInitialize) return PR_FALSE;
|
||||
|
||||
_SymCleanup = (SYMCLEANUPPROC)GetProcAddress(module, "SymCleanup");
|
||||
if (!_SymCleanup) return PR_FALSE;
|
||||
|
||||
_StackWalk = (STACKWALKPROC)GetProcAddress(module, "StackWalk");
|
||||
if (!_StackWalk) return PR_FALSE;
|
||||
|
||||
_SymFunctionTableAccess = (SYMFUNCTIONTABLEACCESSPROC) GetProcAddress(module, "SymFunctionTableAccess");
|
||||
if (!_SymFunctionTableAccess) return PR_FALSE;
|
||||
|
||||
_SymGetModuleBase = (SYMGETMODULEBASEPROC)GetProcAddress(module, "SymGetModuleBase");
|
||||
if (!_SymGetModuleBase) return PR_FALSE;
|
||||
|
||||
_SymGetSymFromAddr = (SYMGETSYMFROMADDRPROC)GetProcAddress(module, "SymGetSymFromAddr");
|
||||
if (!_SymGetSymFromAddr) return PR_FALSE;
|
||||
|
||||
gInitialized = _SymInitialize(GetCurrentProcess(), 0, TRUE);
|
||||
}
|
||||
|
||||
return gInitialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk the stack, translating PC's found into strings and recording the
|
||||
* chain in aBuffer. For this to work properly, the dll's must be rebased
|
||||
* so that the address in the file agrees with the address in memory.
|
||||
* Otherwise StackWalk will return FALSE when it hits a frame in a dll's
|
||||
* whose in memory address doesn't match it's in-file address.
|
||||
*
|
||||
* Fortunately, there is a handy dandy routine in IMAGEHLP.DLL that does
|
||||
* the rebasing and accordingly I've made a tool to use it to rebase the
|
||||
* DLL's in one fell swoop (see xpcom/tools/windows/rebasedlls.cpp).
|
||||
*/
|
||||
void
|
||||
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
|
||||
{
|
||||
aBuffer[0] = '\0';
|
||||
aBufLen--; // leave room for nul
|
||||
|
||||
HANDLE myProcess = ::GetCurrentProcess();
|
||||
HANDLE myThread = ::GetCurrentThread();
|
||||
|
||||
BOOL ok;
|
||||
|
||||
ok = EnsureSymInitialized();
|
||||
if (! ok)
|
||||
return;
|
||||
|
||||
// Get the context information for this thread. That way we will
|
||||
// know where our sp, fp, pc, etc. are and can fill in the
|
||||
// STACKFRAME with the initial values.
|
||||
CONTEXT context;
|
||||
context.ContextFlags = CONTEXT_FULL;
|
||||
ok = GetThreadContext(myThread, &context);
|
||||
if (! ok)
|
||||
return;
|
||||
|
||||
// Setup initial stack frame to walk from
|
||||
STACKFRAME frame;
|
||||
memset(&frame, 0, sizeof(frame));
|
||||
frame.AddrPC.Offset = context.Eip;
|
||||
frame.AddrPC.Mode = AddrModeFlat;
|
||||
frame.AddrStack.Offset = context.Esp;
|
||||
frame.AddrStack.Mode = AddrModeFlat;
|
||||
frame.AddrFrame.Offset = context.Ebp;
|
||||
frame.AddrFrame.Mode = AddrModeFlat;
|
||||
|
||||
// Now walk the stack and map the pc's to symbol names that we stuff
|
||||
// append to *cp.
|
||||
char* cp = aBuffer;
|
||||
|
||||
int skip = 2;
|
||||
while (aBufLen > 0) {
|
||||
ok = _StackWalk(IMAGE_FILE_MACHINE_I386,
|
||||
myProcess,
|
||||
myThread,
|
||||
&frame,
|
||||
&context,
|
||||
0, // read process memory routine
|
||||
_SymFunctionTableAccess, // function table access routine
|
||||
_SymGetModuleBase, // module base routine
|
||||
0); // translate address routine
|
||||
|
||||
if (!ok || frame.AddrPC.Offset == 0)
|
||||
break;
|
||||
|
||||
if (skip-- > 0)
|
||||
continue;
|
||||
|
||||
char buf[sizeof(IMAGEHLP_SYMBOL) + 512];
|
||||
PIMAGEHLP_SYMBOL symbol = (PIMAGEHLP_SYMBOL) buf;
|
||||
symbol->SizeOfStruct = sizeof(buf);
|
||||
symbol->MaxNameLength = 512;
|
||||
|
||||
DWORD displacement;
|
||||
ok = _SymGetSymFromAddr(myProcess,
|
||||
frame.AddrPC.Offset,
|
||||
&displacement,
|
||||
symbol);
|
||||
|
||||
if (ok) {
|
||||
int nameLen = strlen(symbol->Name);
|
||||
if (nameLen + 12 > aBufLen) { // 12 == strlen("+0x12345678 ")
|
||||
break;
|
||||
}
|
||||
char* cp2 = symbol->Name;
|
||||
while (*cp2) {
|
||||
if (*cp2 == ' ') *cp2 = '_'; // replace spaces with underscores
|
||||
*cp++ = *cp2++;
|
||||
}
|
||||
aBufLen -= nameLen;
|
||||
*cp++ = '+';
|
||||
*cp++ = '0';
|
||||
*cp++ = 'x';
|
||||
PRInt32 len = nsIToA16(displacement, cp);
|
||||
cp += len;
|
||||
*cp++ = ' ';
|
||||
|
||||
aBufLen -= nameLen + len + 4;
|
||||
}
|
||||
else {
|
||||
if (11 > aBufLen) { // 11 == strlen("0x12345678 ")
|
||||
break;
|
||||
}
|
||||
*cp++ = '0';
|
||||
*cp++ = 'x';
|
||||
PRInt32 len = nsIToA16(frame.AddrPC.Offset, cp);
|
||||
cp += len;
|
||||
*cp++ = ' ';
|
||||
aBufLen -= len + 3;
|
||||
}
|
||||
}
|
||||
*cp = 0;
|
||||
}
|
||||
/* _WIN32 */
|
||||
|
||||
|
||||
#elif defined(linux) && defined(__GLIBC__) && defined(__i386) // i386 Linux stackwalking code
|
||||
|
||||
void
|
||||
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
|
||||
{
|
||||
aBuffer[0] = '\0';
|
||||
aBufLen--; // leave room for nul
|
||||
|
||||
char* cp = aBuffer;
|
||||
|
||||
jmp_buf jb;
|
||||
setjmp(jb);
|
||||
|
||||
// Stack walking code courtesy Kipp's "leaky".
|
||||
u_long* bp = (u_long*) (jb[0].__jmpbuf[JB_BP]);
|
||||
int skip = 2;
|
||||
for (;;) {
|
||||
u_long* nextbp = (u_long*) *bp++;
|
||||
u_long pc = *bp;
|
||||
if ((pc < 0x08000000) || (pc > 0x7fffffff) || (nextbp < bp)) {
|
||||
break;
|
||||
}
|
||||
if (--skip <= 0) {
|
||||
Dl_info info;
|
||||
int ok = dladdr((void*) pc, &info);
|
||||
if (ok < 0)
|
||||
break;
|
||||
|
||||
int len = strlen(info.dli_sname);
|
||||
if (! len)
|
||||
break; // XXX Lazy. We could look at the filename or something.
|
||||
|
||||
if (len + 12 >= aBufLen) // 12 == strlen("+0x12345678 ")
|
||||
break;
|
||||
|
||||
strcpy(cp, info.dli_sname);
|
||||
cp += len;
|
||||
|
||||
*cp++ = '+';
|
||||
*cp++ = '0';
|
||||
*cp++ = 'x';
|
||||
|
||||
PRUint32 off = (char*)pc - (char*)info.dli_saddr;
|
||||
PRInt32 addrStrLen = nsIToA16(off, cp);
|
||||
cp += addrStrLen;
|
||||
|
||||
*cp++ = ' ';
|
||||
|
||||
aBufLen -= addrStrLen + 4;
|
||||
}
|
||||
bp = nextbp;
|
||||
}
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
#else // unsupported platform.
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
|
||||
{
|
||||
// Write me!!!
|
||||
*aBuffer = '\0';
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
|
||||
void* aLibrayHandle)
|
||||
{
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
#if defined(_WIN32)
|
||||
InitTraceLog();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
|
||||
HANDLE myProcess = ::GetCurrentProcess();
|
||||
|
||||
if (!SymInitialize(myProcess, ".;..\\lib", TRUE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL b = ::SymLoadModule(myProcess,
|
||||
NULL,
|
||||
(char*)aLibraryName,
|
||||
(char*)aLibraryName,
|
||||
0,
|
||||
0);
|
||||
// DWORD lastError = 0;
|
||||
// if (!b) lastError = ::GetLastError();
|
||||
// printf("loading symbols for library %s => %s [%d]\n", aLibraryName,
|
||||
// b ? "true" : "false", lastError);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_COM unsigned long
|
||||
nsTraceRefcnt::AddRef(void* aPtr,
|
||||
unsigned long aNewRefcnt,
|
||||
const char* aFile,
|
||||
PRIntn aLine)
|
||||
{
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
InitTraceLog();
|
||||
|
||||
LOCK_TRACELOG();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
|
||||
char sb[1000];
|
||||
WalkTheStack(sb, sizeof(sb));
|
||||
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
|
||||
("AddRef: %p: %d=>%d [%s] in %s (line %d)",
|
||||
aPtr, aNewRefcnt-1, aNewRefcnt, sb, aFile, aLine));
|
||||
}
|
||||
UNLOCK_TRACELOG();
|
||||
#endif
|
||||
return aNewRefcnt;
|
||||
|
||||
}
|
||||
|
||||
NS_COM unsigned long
|
||||
nsTraceRefcnt::Release(void* aPtr,
|
||||
unsigned long aNewRefcnt,
|
||||
const char* aFile,
|
||||
PRIntn aLine)
|
||||
{
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
InitTraceLog();
|
||||
|
||||
LOCK_TRACELOG();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
|
||||
char sb[1000];
|
||||
WalkTheStack(sb, sizeof(sb));
|
||||
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
|
||||
("Release: %p: %d=>%d [%s] in %s (line %d)",
|
||||
aPtr, aNewRefcnt+1, aNewRefcnt, sb, aFile, aLine));
|
||||
}
|
||||
UNLOCK_TRACELOG();
|
||||
#endif
|
||||
return aNewRefcnt;
|
||||
}
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcnt::Create(void* aPtr,
|
||||
const char* aType,
|
||||
const char* aFile,
|
||||
PRIntn aLine)
|
||||
{
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
InitTraceLog();
|
||||
|
||||
LOCK_TRACELOG();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
|
||||
char sb[1000];
|
||||
WalkTheStack(sb, sizeof(sb));
|
||||
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
|
||||
("Create: %p[%s]: [%s] in %s (line %d)",
|
||||
aPtr, aType, sb, aFile, aLine));
|
||||
}
|
||||
UNLOCK_TRACELOG();
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcnt::Destroy(void* aPtr,
|
||||
const char* aFile,
|
||||
PRIntn aLine)
|
||||
{
|
||||
#ifdef MOZ_TRACE_XPCOM_REFCNT
|
||||
InitTraceLog();
|
||||
|
||||
LOCK_TRACELOG();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
|
||||
char sb[1000];
|
||||
WalkTheStack(sb, sizeof(sb));
|
||||
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
|
||||
("Destroy: %p: [%s] in %s (line %d)",
|
||||
aPtr, sb, aFile, aLine));
|
||||
}
|
||||
UNLOCK_TRACELOG();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcnt::LogAddRef(void* aPtr,
|
||||
nsrefcnt aRefCnt,
|
||||
const char* aFile,
|
||||
int aLine)
|
||||
{
|
||||
InitTraceLog();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog, PR_LOG_DEBUG)) {
|
||||
char sb[16384];
|
||||
WalkTheStack(sb, sizeof(sb));
|
||||
// Can't use PR_LOG(), b/c it truncates the line
|
||||
printf("%s(%d) %p AddRef %d %s\n", aFile, aLine, aPtr, aRefCnt, sb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_COM void
|
||||
nsTraceRefcnt::LogRelease(void* aPtr,
|
||||
nsrefcnt aRefCnt,
|
||||
const char* aFile,
|
||||
int aLine)
|
||||
{
|
||||
InitTraceLog();
|
||||
if (PR_LOG_TEST(gTraceRefcntLog, PR_LOG_DEBUG)) {
|
||||
char sb[16384];
|
||||
WalkTheStack(sb, sizeof(sb));
|
||||
// Can't use PR_LOG(), b/c it truncates the line
|
||||
printf("%s(%d) %p Release %d %s\n", aFile, aLine, aPtr, aRefCnt, sb);
|
||||
}
|
||||
}
|
||||
72
mozilla/xpcom/base/nsTraceRefcntImpl.h
Normal file
72
mozilla/xpcom/base/nsTraceRefcntImpl.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
#ifndef nsTraceRefcnt_h___
|
||||
#define nsTraceRefcnt_h___
|
||||
|
||||
#include "nsCom.h"
|
||||
|
||||
/**
|
||||
* This class is used to support tracing (and logging using nspr) of
|
||||
* addref and release calls. Note that only calls that use the
|
||||
* NS_ADDREF and related macros in nsISupports can be traced.
|
||||
*
|
||||
* The name of the nspr log module is "xpcomrefcnt" (case matters).
|
||||
*
|
||||
* This code only performs tracing built with debugging AND when
|
||||
* built with -DMOZ_TRACE_XPCOM_REFCNT (because it's expensive!).
|
||||
*/
|
||||
class nsTraceRefcnt {
|
||||
public:
|
||||
static NS_COM unsigned long AddRef(void* aPtr,
|
||||
unsigned long aNewRefcnt,
|
||||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
static NS_COM unsigned long Release(void* aPtr,
|
||||
unsigned long aNewRefcnt,
|
||||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
static NS_COM void Create(void* aPtr,
|
||||
const char* aType,
|
||||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
static NS_COM void Destroy(void* aPtr,
|
||||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
static NS_COM void LoadLibrarySymbols(const char* aLibraryName,
|
||||
void* aLibrayHandle);
|
||||
|
||||
static NS_COM void WalkTheStack(char* aBuffer, int aBufLen);
|
||||
|
||||
static NS_COM void LogAddRef(void* aPtr,
|
||||
nsrefcnt aRefCnt,
|
||||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
static NS_COM void LogRelease(void* aPtr,
|
||||
nsrefcnt aRefCnt,
|
||||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
};
|
||||
|
||||
#endif /* nsTraceRefcnt_h___ */
|
||||
164
mozilla/xpcom/base/nscore.h
Normal file
164
mozilla/xpcom/base/nscore.h
Normal file
@@ -0,0 +1,164 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#ifndef nscore_h___
|
||||
#define nscore_h___
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NS_WIN32 1
|
||||
#endif
|
||||
|
||||
#if defined(__unix)
|
||||
#define NS_UNIX 1
|
||||
#endif
|
||||
|
||||
#include "prtypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "nsDebug.h"
|
||||
#endif
|
||||
|
||||
#ifndef __PRUNICHAR__
|
||||
#define __PRUNICHAR__
|
||||
typedef PRUint16 PRUnichar;
|
||||
#endif
|
||||
|
||||
/* The preferred symbol for null. */
|
||||
#define nsnull 0
|
||||
|
||||
/* Define brackets for protecting C code from C++ */
|
||||
#ifdef __cplusplus
|
||||
#define NS_BEGIN_EXTERN_C extern "C" {
|
||||
#define NS_END_EXTERN_C }
|
||||
#else
|
||||
#define NS_BEGIN_EXTERN_C
|
||||
#define NS_END_EXTERN_C
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Import/export defines */
|
||||
|
||||
#ifdef NS_WIN32
|
||||
#define NS_IMPORT _declspec(dllimport)
|
||||
#define NS_IMPORT_(type) type _declspec(dllimport) __stdcall
|
||||
#define NS_EXPORT _declspec(dllexport)
|
||||
/* XXX NS_EXPORT_ defined in nsCOm.h (xpcom) differs in where the __declspec
|
||||
is placed. It needs to be done this way to make the 4.x compiler happy... */
|
||||
#undef NS_EXPORT_
|
||||
#define NS_EXPORT_(type) type _declspec(dllexport) __stdcall
|
||||
#elif defined(XP_MAC)
|
||||
|
||||
#define NS_IMPORT
|
||||
#define NS_IMPORT_(type) type
|
||||
|
||||
/* XXX NS_EXPORT_ defined in nsCom.h actually does an export. Here it's just sugar. */
|
||||
#undef NS_EXPORT
|
||||
#undef NS_EXPORT_
|
||||
|
||||
#define NS_EXPORT __declspec(export)
|
||||
#define NS_EXPORT_(type) __declspec(export) type
|
||||
|
||||
#else
|
||||
/* XXX do something useful? */
|
||||
#define NS_IMPORT
|
||||
#define NS_IMPORT_(type) type
|
||||
#define NS_EXPORT
|
||||
#define NS_EXPORT_(type) type
|
||||
#endif
|
||||
|
||||
#ifdef _IMPL_NS_BASE
|
||||
#define NS_BASE NS_EXPORT
|
||||
#else
|
||||
#define NS_BASE NS_IMPORT
|
||||
#endif
|
||||
|
||||
#ifdef _IMPL_NS_NET
|
||||
#define NS_NET NS_EXPORT
|
||||
#else
|
||||
#define NS_NET NS_IMPORT
|
||||
#endif
|
||||
|
||||
#ifdef _IMPL_NS_DOM
|
||||
#define NS_DOM NS_EXPORT
|
||||
#else
|
||||
#define NS_DOM NS_IMPORT
|
||||
#endif
|
||||
|
||||
#ifdef _IMPL_NS_WIDGET
|
||||
#define NS_WIDGET NS_EXPORT
|
||||
#else
|
||||
#define NS_WIDGET NS_IMPORT
|
||||
#endif
|
||||
|
||||
#ifdef _IMPL_NS_VIEW
|
||||
#define NS_VIEW NS_EXPORT
|
||||
#else
|
||||
#define NS_VIEW NS_IMPORT
|
||||
#endif
|
||||
|
||||
#ifdef _IMPL_NS_GFXNONXP
|
||||
#define NS_GFXNONXP NS_EXPORT
|
||||
#define NS_GFXNONXP_(type) NS_EXPORT_(type)
|
||||
#else
|
||||
#define NS_GFXNONXP NS_IMPORT
|
||||
#define NS_GFXNONXP_(type) NS_IMPORT_(type)
|
||||
#endif
|
||||
|
||||
#ifdef _IMPL_NS_GFX
|
||||
#define NS_GFX NS_EXPORT
|
||||
#define NS_GFX_(type) NS_EXPORT_(type)
|
||||
#else
|
||||
#define NS_GFX NS_IMPORT
|
||||
#define NS_GFX_(type) NS_IMPORT_(type)
|
||||
#endif
|
||||
|
||||
#ifdef _IMPL_NS_PLUGIN
|
||||
#define NS_PLUGIN NS_EXPORT
|
||||
#else
|
||||
#define NS_PLUGIN NS_IMPORT
|
||||
#endif
|
||||
|
||||
#ifdef _IMPL_NS_APPSHELL
|
||||
#define NS_APPSHELL NS_EXPORT
|
||||
#else
|
||||
#define NS_APPSHELL NS_IMPORT
|
||||
#endif
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* Casting macros for hiding C++ features from older compilers */
|
||||
|
||||
/* unix now determines this automatically */
|
||||
#ifndef XP_UNIX
|
||||
#define HAVE_CPP_NEW_CASTS /* we'll be optimistic. */
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_CPP_NEW_CASTS)
|
||||
#define NS_STATIC_CAST(__type, __ptr) static_cast<__type>(__ptr)
|
||||
#define NS_CONST_CAST(__type, __ptr) const_cast<__type>(__ptr)
|
||||
#define NS_REINTERPRET_CAST(__type, __ptr) reinterpret_cast<__type>(__ptr)
|
||||
#else
|
||||
#define NS_STATIC_CAST(__type, __ptr) ((__type)(__ptr))
|
||||
#define NS_CONST_CAST(__type, __ptr) ((__type)(__ptr))
|
||||
#define NS_REINTERPRET_CAST(__type, __ptr) ((__type)(__ptr))
|
||||
#endif
|
||||
|
||||
/* No sense in making an NS_DYNAMIC_CAST() macro: you can't duplicate
|
||||
the semantics. So if you want to dynamic_cast, then just use it
|
||||
"straight", no macro. */
|
||||
|
||||
#endif /* nscore_h___ */
|
||||
63
mozilla/xpcom/base/nsrootidl.idl
Normal file
63
mozilla/xpcom/base/nsrootidl.idl
Normal file
@@ -0,0 +1,63 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/* Root idl declarations to be used by all. */
|
||||
|
||||
%{C++
|
||||
|
||||
#include "nscore.h"
|
||||
#include "prtime.h"
|
||||
|
||||
/*
|
||||
* Start commenting out the C++ versions of the below in the output header
|
||||
*/
|
||||
#if 0
|
||||
%}
|
||||
|
||||
typedef boolean PRBool ;
|
||||
typedef octet PRUint8 ;
|
||||
typedef unsigned short PRUint16 ;
|
||||
typedef unsigned long PRUint32 ;
|
||||
typedef unsigned long long PRUint64 ;
|
||||
typedef unsigned long long PRTime ;
|
||||
typedef short PRInt16 ;
|
||||
typedef long PRInt32 ;
|
||||
typedef long long PRInt64 ;
|
||||
|
||||
typedef unsigned long nsrefcnt ;
|
||||
typedef unsigned long nsresult ;
|
||||
|
||||
[ptr] native voidStar(void);
|
||||
[ptr] native charStar(char);
|
||||
|
||||
[ref, nsid] native nsIDRef(nsID);
|
||||
[ref, nsid] native nsIIDRef(nsIID);
|
||||
[ref, nsid] native nsCIDRef(nsCID);
|
||||
|
||||
[ptr, nsid] native nsIDPtr(nsID);
|
||||
[ptr, nsid] native nsIIDPtr(nsIID);
|
||||
[ptr, nsid] native nsCIDPtr(nsCID);
|
||||
|
||||
[ptr] native nsQIResult(void);
|
||||
|
||||
%{C++
|
||||
/*
|
||||
* End commenting out the C++ versions of the above in the output header
|
||||
*/
|
||||
#endif
|
||||
%}
|
||||
84
mozilla/xpcom/build/Makefile.in
Normal file
84
mozilla/xpcom/build/Makefile.in
Normal file
@@ -0,0 +1,84 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
#
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
LIBRARY_NAME = xpcom
|
||||
MODULE = xpcom
|
||||
|
||||
CPPSRCS = nsXPComInit.cpp
|
||||
|
||||
REQUIRES = xpcom
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(srcdir)/../base \
|
||||
-I$(srcdir)/../ds \
|
||||
-I$(srcdir)/../io \
|
||||
-I$(srcdir)/../components \
|
||||
-I$(srcdir)/../threads \
|
||||
-I$(srcdir)/../proxy/src \
|
||||
$(NULL)
|
||||
|
||||
DEFINES += -D_IMPL_NS_COM -D_IMPL_NS_BASE
|
||||
|
||||
SHARED_LIBRARY_LIBS = \
|
||||
$(DIST)/lib/libxpcomds_s.a \
|
||||
$(DIST)/lib/libxpcomio_s.a \
|
||||
$(DIST)/lib/libxpcomcomponents_s.a \
|
||||
$(DIST)/lib/libxpcomthreads_s.a \
|
||||
$(DIST)/lib/libxpcomproxy_s.a \
|
||||
$(DIST)/lib/libxpcombase_s.a \
|
||||
$(DIST)/lib/libxptcall.a \
|
||||
$(DIST)/lib/libxptinfo.a \
|
||||
$(DIST)/lib/libxpt.a \
|
||||
$(DIST)/lib/libxptcmd.a \
|
||||
$(DIST)/lib/libreg.a \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH),HP-UX)
|
||||
EXTRA_DSO_LDOPTS = -c objs/objslist
|
||||
else
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MKSHLIB_FORCE_ALL) \
|
||||
$(SHARED_LIBRARY_LIBS) \
|
||||
$(MKSHLIB_UNFORCE_ALL)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),BeOS)
|
||||
EXTRA_DSO_LDOPTS += -lbe
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifeq ($(OS_ARCH),HP-UX)
|
||||
shared_library_objs: $(SHARED_LIBRARY_LIBS)
|
||||
rm -rf objs
|
||||
mkdir objs
|
||||
(cd objs; for lib in $(SHARED_LIBRARY_LIBS); do ar xv ../$$lib; done) \
|
||||
| awk '{ print "objs/"$$3 }' > objs/objslist
|
||||
|
||||
$(LIBRARY) $(SHARED_LIBRARY): shared_library_objs Makefile
|
||||
else
|
||||
$(LIBRARY) $(SHARED_LIBRARY): $(SHARED_LIBRARY_LIBS) Makefile
|
||||
endif
|
||||
83
mozilla/xpcom/build/dlldeps.cpp
Normal file
83
mozilla/xpcom/build/dlldeps.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
// Force references to all of the symbols that we want exported from
|
||||
// the dll that are located in the .lib files we link with
|
||||
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsFileSpec.h"
|
||||
#include "nsIBuffer.h"
|
||||
//#include "nsIByteBufferInputStream.h"
|
||||
#include "nsFileStream.h"
|
||||
#include "nsFileSpecStreaming.h"
|
||||
#include "nsSpecialSystemDirectory.h"
|
||||
#include "nsIThread.h"
|
||||
#include "nsDeque.h"
|
||||
#include "nsObserver.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIEnumerator.h"
|
||||
#include "nsEnumeratorUtils.h"
|
||||
#include "nsQuickSort.h"
|
||||
#include "nsString2.h"
|
||||
#include "nsProxyEventPrivate.h"
|
||||
#include "xpt_xdr.h"
|
||||
#include "nsInterfaceInfo.h"
|
||||
#include "xptcall.h"
|
||||
#include "nsIFileSpec.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
|
||||
|
||||
void XXXNeverCalled()
|
||||
{
|
||||
nsVoidArray();
|
||||
NS_GetNumberOfAtoms();
|
||||
nsFileURL(NULL);
|
||||
NS_NewPipe(NULL, NULL, 0, 0, 0, NULL);
|
||||
nsFileSpec s;
|
||||
NS_NewIOFileStream(NULL, s, 0, 0);
|
||||
nsInputFileStream(s, 0, 0);
|
||||
nsPersistentFileDescriptor d;
|
||||
ReadDescriptor(NULL, d);
|
||||
new nsSpecialSystemDirectory(nsSpecialSystemDirectory::OS_DriveDirectory);
|
||||
nsIThread::GetCurrent(NULL);
|
||||
nsDeque(NULL);
|
||||
NS_NewObserver(NULL, NULL);
|
||||
nsTraceRefcnt::AddRef(NULL, 0, NULL, 0);
|
||||
nsXPIDLCString::Copy(NULL);
|
||||
NS_NewEmptyEnumerator(NULL);
|
||||
nsArrayEnumerator(NULL);
|
||||
NS_NewIntersectionEnumerator(NULL, NULL, NULL);
|
||||
NS_QuickSort(NULL, 0, 0, NULL, NULL);
|
||||
nsString2();
|
||||
nsProxyObject();
|
||||
XPT_DoString(NULL, NULL);
|
||||
XPT_DoHeader(NULL, NULL);
|
||||
nsInterfaceInfo* info = NULL;
|
||||
info->GetName(NULL);
|
||||
#ifdef DEBUG
|
||||
info->print(NULL);
|
||||
#endif
|
||||
XPTC_InvokeByIndex(NULL, 0, 0, NULL);
|
||||
NS_NewFileSpec(NULL);
|
||||
xptc_dummy();
|
||||
xptc_dummy2();
|
||||
XPTI_GetInterfaceInfoManager();
|
||||
NS_NewGenericFactory(NULL, NULL, NULL);
|
||||
}
|
||||
86
mozilla/xpcom/build/makefile.win
Normal file
86
mozilla/xpcom/build/makefile.win
Normal file
@@ -0,0 +1,86 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
DEPTH=..\..
|
||||
MODULE = xpcom
|
||||
|
||||
LIBNAME = .\$(OBJDIR)\xpcom
|
||||
DLL = $(LIBNAME).dll
|
||||
|
||||
LINCS = \
|
||||
-I$(PUBLIC)\xpcom \
|
||||
-I..\base \
|
||||
-I..\ds \
|
||||
-I..\io \
|
||||
-I..\components \
|
||||
-I..\threads \
|
||||
-I..\reflect\xptinfo\src \
|
||||
-I..\proxy\src \
|
||||
$(NULL)
|
||||
|
||||
LCFLAGS=-D_IMPL_NS_COM \
|
||||
-D_IMPL_NS_BASE \
|
||||
-DWIN32_LEAN_AND_MEAN \
|
||||
-DEXPORT_XPT_API \
|
||||
-DEXPORT_XPTC_API \
|
||||
-DEXPORT_XPTI_API
|
||||
|
||||
CPP_OBJS = \
|
||||
.\$(OBJDIR)\nsXPComInit.obj \
|
||||
.\$(OBJDIR)\dlldeps.obj \
|
||||
$(NULL)
|
||||
|
||||
!ifndef BUILD_OPT
|
||||
#CPP_OBJS = $(CPP_OBJS) .\$(OBJDIR)\nsConstructorPattern.obj
|
||||
!endif
|
||||
|
||||
OURLIBS = \
|
||||
$(LIBNSPR) \
|
||||
$(DIST)\lib\plc3.lib \
|
||||
$(DIST)\lib\xpcombase_s.lib \
|
||||
$(DIST)\lib\xpcomds_s.lib \
|
||||
$(DIST)\lib\xpcomio_s.lib \
|
||||
$(DIST)\lib\xpcomcomp_s.lib \
|
||||
$(DIST)\lib\xpcomthreads_s.lib \
|
||||
$(DIST)\lib\xpcomxpt_s.lib \
|
||||
$(DIST)\lib\xpcomxptcall_s.lib \
|
||||
$(DIST)\lib\xpcomxptcmd_s.lib \
|
||||
$(DIST)\lib\xpcomxptinfo_s.lib \
|
||||
$(DIST)\lib\xpcomproxy_s.lib \
|
||||
$(DIST)\lib\libreg32.lib \
|
||||
$(NULL)
|
||||
|
||||
LLIBS = \
|
||||
$(OURLIBS) \
|
||||
shell32.lib \
|
||||
!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE)
|
||||
$(GLOWDIR)\glowcode.lib \
|
||||
!endif
|
||||
!if defined(MOZ_TRACE_XPCOM_REFCNT)
|
||||
imagehlp.lib \
|
||||
!endif
|
||||
$(NULL)
|
||||
|
||||
MISCDEP=$(OURLIBS)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
libs:: $(DLL)
|
||||
$(MAKE_INSTALL) $(LIBNAME).$(DLL_SUFFIX) $(DIST)\bin
|
||||
$(MAKE_INSTALL) $(LIBNAME).$(LIB_SUFFIX) $(DIST)\lib
|
||||
243
mozilla/xpcom/build/nsConstructorPattern.cpp
Normal file
243
mozilla/xpcom/build/nsConstructorPattern.cpp
Normal file
@@ -0,0 +1,243 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIFoo.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Here's an interface that we're going to work with. Normally it would be
|
||||
// defined in nsIFoo.h:
|
||||
|
||||
#define NS_IFOO_IID \
|
||||
{ /* f981ba10-1547-11d3-9337-00104ba0fd40 */ \
|
||||
0xf981ba10, \
|
||||
0x1547, \
|
||||
0x11d3, \
|
||||
{0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
|
||||
}
|
||||
|
||||
#define NS_FOO_CID \
|
||||
{ /* fe1a5870-1547-11d3-9337-00104ba0fd40 */ \
|
||||
0xfe1a5870, \
|
||||
0x1547, \
|
||||
0x11d3, \
|
||||
{0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
|
||||
}
|
||||
|
||||
class nsIFoo : public nsISupports {
|
||||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFOO_IID);
|
||||
|
||||
NS_IMETHOD Init(const char* name) = 0;
|
||||
NS_IMETHOD Doit(int x) = 0;
|
||||
};
|
||||
|
||||
// Define a global constructor function if you really need one. Otherwise
|
||||
// you can always use nsIComponentManager::CreateInstance.
|
||||
PR_EXTERN(nsresult)
|
||||
NS_NewFoo(nsIFoo* *result, const char* name);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsFoo.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Here's the implementation class definition. Put this in an nsFoo.h (and don't
|
||||
// export it to dist).
|
||||
|
||||
//#include "nsIFoo.h"
|
||||
|
||||
class nsFoo : public nsIFoo {
|
||||
public:
|
||||
// Define the constructor, but don't give it arguments that are needed
|
||||
// for initialization that can fail:
|
||||
nsFoo();
|
||||
// Always make the destructor virtual:
|
||||
virtual ~nsFoo();
|
||||
|
||||
// Define a Create method to be used with a factory:
|
||||
static NS_METHOD
|
||||
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
|
||||
|
||||
// from nsIFoo:
|
||||
NS_IMETHOD Init(const char* name);
|
||||
|
||||
NS_IMETHOD Doit(int x);
|
||||
|
||||
// from nsISupports:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
protected:
|
||||
// instance variables:
|
||||
char* mName;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsFoo.cpp
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Here's the implementation. Put this in an nsFoo.cpp.
|
||||
|
||||
//#include "nsFoo.h"
|
||||
#include "nsCRT.h"
|
||||
#include <stdio.h>
|
||||
|
||||
// Don't do anything in the constructor that can fail. Just initialize all
|
||||
// the instance variables and get out:
|
||||
nsFoo::nsFoo()
|
||||
: mName(NULL)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
// Do anything that can fail in the Init method. It's a good idea to provide
|
||||
// one so that in the future if someone adds something that can fail they'll
|
||||
// be encouraged to do it right:
|
||||
NS_IMETHODIMP
|
||||
nsFoo::Init(const char* name)
|
||||
{
|
||||
mName = nsCRT::strdup(name);
|
||||
if (mName == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Destroy and release things as usual in the destructor:
|
||||
nsFoo::~nsFoo()
|
||||
{
|
||||
if (mName)
|
||||
nsCRT::free(mName);
|
||||
}
|
||||
|
||||
// Provide a Create method that can be called by a factory constructor:
|
||||
NS_METHOD
|
||||
nsFoo::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsFoo* foo = new nsFoo();
|
||||
if (foo == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Note that Create doesn't initialize the instance -- that has to
|
||||
// be done by the caller since the initialization args aren't passed
|
||||
// in here.
|
||||
|
||||
// AddRef before calling QI -- this makes it easier to handle the QI
|
||||
// failure case because we'll always just Release and return
|
||||
NS_ADDREF(foo);
|
||||
nsresult rv = foo->QueryInterface(aIID, aResult);
|
||||
|
||||
// This will free it if QI failed:
|
||||
NS_RELEASE(foo);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Implement the nsISupports methods:
|
||||
NS_IMPL_ISUPPORTS(nsFoo, nsIFoo::GetIID());
|
||||
|
||||
// Implement the method(s) of the interface:
|
||||
NS_IMETHODIMP
|
||||
nsFoo::Doit(int x)
|
||||
{
|
||||
printf("%s %d\n", mName, x);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Finally, (if you really need one) implement a global constructor function
|
||||
// for this class:
|
||||
PR_IMPLEMENT(nsresult)
|
||||
NS_NewFoo(nsIFoo* *result, const char* name)
|
||||
{
|
||||
// Use the constructor method to create this. Don't duplicate work.
|
||||
nsresult rv = nsFoo::Create(NULL, nsIFoo::GetIID(),
|
||||
(void**)result);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Only initialize if the constructor succeeded:
|
||||
rv = (*result)->Init(name);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsFooModuleFactory.cpp
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// This file defines the factory that instantiates nsFoo and any other classes
|
||||
// in the same component. It also defines the component's NSGetFactory,
|
||||
// NSRegisterSelf and NSUnregisterSelf entry points:
|
||||
|
||||
// Include nsFoo.h to get the nsFoo::Create method:
|
||||
//#include "nsFoo.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
// Include the generic factory stuff. It's the easiest and smallest way to
|
||||
// work with factories:
|
||||
#include "nsGenericFactory.h"
|
||||
|
||||
static NS_DEFINE_CID(kFooCID, NS_FOO_CID);
|
||||
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
|
||||
|
||||
extern "C" PR_IMPLEMENT(nsresult)
|
||||
NSGetFactory(nsISupports* aServMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIGenericFactory* fact;
|
||||
if (aClass.Equals(kFooCID))
|
||||
rv = NS_NewGenericFactory(&fact, nsFoo::Create);
|
||||
else
|
||||
rv = NS_ERROR_FAILURE;
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
*aFactory = fact;
|
||||
return rv;
|
||||
}
|
||||
|
||||
extern "C" PR_IMPLEMENT(nsresult)
|
||||
NSRegisterSelf(nsISupports* aServMgr , const char* aPath)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_WITH_SERVICE1(nsIComponentManager, compMgr,
|
||||
aServMgr, kComponentManagerCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = compMgr->RegisterComponent(kFooCID, "Foo", NULL,
|
||||
aPath, PR_TRUE, PR_TRUE);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
extern "C" PR_IMPLEMENT(nsresult)
|
||||
NSUnregisterSelf(nsISupports* aServMgr, const char* aPath)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE1(nsIComponentManager, compMgr,
|
||||
aServMgr, kComponentManagerCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = compMgr->UnregisterComponent(kFooCID, aPath);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
263
mozilla/xpcom/build/nsXPComInit.cpp
Normal file
263
mozilla/xpcom/build/nsXPComInit.cpp
Normal file
@@ -0,0 +1,263 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsIRegistry.h"
|
||||
#include "nscore.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsObserverService.h"
|
||||
#include "nsObserver.h"
|
||||
#include "nsProperties.h"
|
||||
|
||||
#include "nsAllocator.h"
|
||||
#include "nsArena.h"
|
||||
#include "nsBuffer.h"
|
||||
#include "nsByteBuffer.h"
|
||||
#include "nsPageMgr.h"
|
||||
#include "nsSupportsArray.h"
|
||||
#include "nsUnicharBuffer.h"
|
||||
|
||||
#include "nsComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsGenericFactory.h"
|
||||
|
||||
#include "nsEventQueueService.h"
|
||||
#include "nsEventQueue.h"
|
||||
|
||||
#include "nsProxyObjectManager.h"
|
||||
#include "nsProxyEventPrivate.h" // access to the impl of nsProxyObjectManager for the generic factory registration.
|
||||
|
||||
#include "nsFileSpecImpl.h"
|
||||
|
||||
// base
|
||||
static NS_DEFINE_CID(kAllocatorCID, NS_ALLOCATOR_CID);
|
||||
// ds
|
||||
static NS_DEFINE_CID(kArenaCID, NS_ARENA_CID);
|
||||
static NS_DEFINE_CID(kBufferCID, NS_BUFFER_CID);
|
||||
static NS_DEFINE_CID(kByteBufferCID, NS_BYTEBUFFER_CID);
|
||||
static NS_DEFINE_CID(kPageManagerCID, NS_PAGEMANAGER_CID);
|
||||
static NS_DEFINE_CID(kPropertiesCID, NS_PROPERTIES_CID);
|
||||
static NS_DEFINE_CID(kSupportsArrayCID, NS_SUPPORTSARRAY_CID);
|
||||
static NS_DEFINE_CID(kUnicharBufferCID, NS_UNICHARBUFFER_CID);
|
||||
// io
|
||||
static NS_DEFINE_CID(kFileSpecCID, NS_FILESPEC_CID);
|
||||
static NS_DEFINE_CID(kDirectoryIteratorCID, NS_DIRECTORYITERATOR_CID);
|
||||
// components
|
||||
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
|
||||
static NS_DEFINE_CID(kGenericFactoryCID, NS_GENERICFACTORY_CID);
|
||||
// threads
|
||||
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
static NS_DEFINE_CID(kEventQueueCID, NS_EVENTQUEUE_CID);
|
||||
// proxy
|
||||
static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XPCOM initialization
|
||||
//
|
||||
// To Control the order of initialization of these key components I am putting
|
||||
// this function.
|
||||
//
|
||||
// - nsServiceManager
|
||||
// - nsComponentManager
|
||||
// - nsRegistry
|
||||
//
|
||||
// Here are key points to remember:
|
||||
// - A global of all these need to exist. nsServiceManager is an independent object.
|
||||
// nsComponentManager uses both the globalServiceManager and its own registry.
|
||||
//
|
||||
// - A static object of both the nsComponentManager and nsServiceManager
|
||||
// are in use. Hence InitXPCOM() gets triggered from both
|
||||
// NS_GetGlobale{Service/Component}Manager() calls.
|
||||
//
|
||||
// - There exists no global Registry. Registry can be created from the component manager.
|
||||
//
|
||||
|
||||
static nsresult
|
||||
RegisterGenericFactory(nsIComponentManager* compMgr, const nsCID& cid, const char* className,
|
||||
const char *progid, nsIGenericFactory::ConstructorProcPtr constr)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIGenericFactory* fact;
|
||||
rv = NS_NewGenericFactory(&fact, constr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = compMgr->RegisterFactory(cid, className, progid, fact, PR_TRUE);
|
||||
NS_RELEASE(fact);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsIServiceManager* nsServiceManager::mGlobalServiceManager = NULL;
|
||||
nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL;
|
||||
|
||||
nsresult NS_InitXPCOM(nsIServiceManager* *result)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// 1. Create the Global Service Manager
|
||||
nsIServiceManager* servMgr = NULL;
|
||||
if (nsServiceManager::mGlobalServiceManager == NULL)
|
||||
{
|
||||
rv = NS_NewServiceManager(&servMgr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsServiceManager::mGlobalServiceManager = servMgr;
|
||||
if (result)
|
||||
{
|
||||
NS_ADDREF(servMgr);
|
||||
*result = servMgr;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Create the Component Manager and register with global service manager
|
||||
// It is understood that the component manager can use the global service manager.
|
||||
nsComponentManagerImpl *compMgr = NULL;
|
||||
if (nsComponentManagerImpl::gComponentManager == NULL)
|
||||
{
|
||||
compMgr = new nsComponentManagerImpl();
|
||||
if (compMgr == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(compMgr);
|
||||
rv = compMgr->Init();
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
NS_RELEASE(compMgr);
|
||||
return rv;
|
||||
}
|
||||
nsComponentManagerImpl::gComponentManager = compMgr;
|
||||
}
|
||||
|
||||
rv = servMgr->RegisterService(kComponentManagerCID, compMgr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// 3. Register the global services with the component manager so that
|
||||
// clients can create new objects.
|
||||
|
||||
// Registry
|
||||
nsIFactory *registryFactory = NULL;
|
||||
rv = NS_RegistryGetFactory(®istryFactory);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_DEFINE_CID(kRegistryCID, NS_REGISTRY_CID);
|
||||
|
||||
rv = compMgr->RegisterFactory(kRegistryCID,
|
||||
NS_REGISTRY_CLASSNAME,
|
||||
NS_REGISTRY_PROGID,
|
||||
registryFactory, PR_TRUE);
|
||||
NS_RELEASE(registryFactory);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, kAllocatorCID,
|
||||
NS_ALLOCATOR_CLASSNAME,
|
||||
NS_ALLOCATOR_PROGID,
|
||||
nsAllocatorImpl::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, kArenaCID,
|
||||
NS_ARENA_CLASSNAME,
|
||||
NS_ARENA_PROGID,
|
||||
ArenaImpl::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, kBufferCID,
|
||||
NS_BUFFER_CLASSNAME,
|
||||
NS_BUFFER_PROGID,
|
||||
nsBuffer::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, kByteBufferCID,
|
||||
NS_BYTEBUFFER_CLASSNAME,
|
||||
NS_BYTEBUFFER_PROGID,
|
||||
ByteBufferImpl::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, kFileSpecCID,
|
||||
NS_FILESPEC_CLASSNAME,
|
||||
NS_FILESPEC_PROGID,
|
||||
nsFileSpecImpl::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, kDirectoryIteratorCID,
|
||||
NS_DIRECTORYITERATOR_CLASSNAME,
|
||||
NS_DIRECTORYITERATOR_PROGID,
|
||||
nsDirectoryIteratorImpl::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, kPageManagerCID,
|
||||
NS_PAGEMANAGER_CLASSNAME,
|
||||
NS_PAGEMANAGER_PROGID,
|
||||
nsPageMgr::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, kPropertiesCID,
|
||||
NS_PROPERTIES_CLASSNAME,
|
||||
NS_PROPERTIES_PROGID,
|
||||
nsProperties::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, kPersistentPropertiesCID,
|
||||
NS_PERSISTENTPROPERTIES_CLASSNAME,
|
||||
NS_PERSISTENTPROPERTIES_PROGID,
|
||||
nsPersistentProperties::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, kSupportsArrayCID,
|
||||
NS_SUPPORTSARRAY_CLASSNAME,
|
||||
NS_SUPPORTSARRAY_PROGID,
|
||||
nsSupportsArray::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, nsObserver::GetCID(),
|
||||
NS_OBSERVER_CLASSNAME,
|
||||
NS_OBSERVER_PROGID,
|
||||
nsObserver::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, nsObserverService::GetCID(),
|
||||
NS_OBSERVERSERVICE_CLASSNAME,
|
||||
NS_OBSERVERSERVICE_PROGID,
|
||||
nsObserverService::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, kGenericFactoryCID,
|
||||
NS_GENERICFACTORY_CLASSNAME,
|
||||
NS_GENERICFACTORY_PROGID,
|
||||
nsGenericFactory::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, kEventQueueServiceCID,
|
||||
NS_EVENTQUEUESERVICE_CLASSNAME,
|
||||
NS_EVENTQUEUESERVICE_PROGID,
|
||||
nsEventQueueServiceImpl::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr, kEventQueueCID,
|
||||
NS_EVENTQUEUE_CLASSNAME,
|
||||
NS_EVENTQUEUE_PROGID,
|
||||
nsEventQueueImpl::Create);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = RegisterGenericFactory(compMgr,
|
||||
kProxyObjectManagerCID,
|
||||
NS_XPCOMPROXY_CLASSNAME,
|
||||
NS_XPCOMPROXY_PROGID,
|
||||
nsProxyObjectManager::Create);
|
||||
|
||||
// Prepopulate registry for performance
|
||||
nsComponentManagerImpl::gComponentManager->PlatformPrePopulateRegistry();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
8
mozilla/xpcom/components/MANIFEST
Normal file
8
mozilla/xpcom/components/MANIFEST
Normal file
@@ -0,0 +1,8 @@
|
||||
nsIComponentManager.h
|
||||
nsIFactory.h
|
||||
nsIGenericFactory.h
|
||||
nsIRegistry.h
|
||||
nsIServiceManager.h
|
||||
nsIServiceProvider.h
|
||||
nsRepository.h
|
||||
nsXPComFactory.h
|
||||
72
mozilla/xpcom/components/Makefile.in
Normal file
72
mozilla/xpcom/components/Makefile.in
Normal file
@@ -0,0 +1,72 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
LIBRARY_NAME = xpcomcomponents_s
|
||||
|
||||
MODULE = xpcom
|
||||
|
||||
XPIDLSRCS = \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsComponentManager.cpp \
|
||||
nsGenericFactory.cpp \
|
||||
nsRegistry.cpp \
|
||||
nsRepository.cpp \
|
||||
nsServiceManager.cpp \
|
||||
xcDll.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
nsIComponentManager.h \
|
||||
nsIFactory.h \
|
||||
nsIGenericFactory.h \
|
||||
nsIRegistry.h \
|
||||
nsIServiceManager.h \
|
||||
nsIServiceProvider.h \
|
||||
nsRepository.h \
|
||||
nsXPComFactory.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
DEFINES += -DUSE_NSREG -D_IMPL_NS_COM -D_IMPL_NS_BASE
|
||||
|
||||
REQUIRES = xpcom libreg
|
||||
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(srcdir)/../base \
|
||||
-I$(srcdir)/../thread \
|
||||
$(NULL)
|
||||
|
||||
MKSHLIB :=
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
override NO_SHARED_LIB=1
|
||||
override NO_STATIC_LIB=
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
69
mozilla/xpcom/components/makefile.win
Normal file
69
mozilla/xpcom/components/makefile.win
Normal file
@@ -0,0 +1,69 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
DEPTH=..\..
|
||||
MODULE = xpcom
|
||||
|
||||
################################################################################
|
||||
## exports
|
||||
|
||||
EXPORTS = \
|
||||
nsIComponentManager.h \
|
||||
nsIFactory.h \
|
||||
nsIGenericFactory.h \
|
||||
nsIRegistry.h \
|
||||
nsIServiceManager.h \
|
||||
nsIServiceProvider.h \
|
||||
nsRepository.h \
|
||||
nsXPComFactory.h \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS = \
|
||||
$(NULL)
|
||||
|
||||
################################################################################
|
||||
## library
|
||||
|
||||
LIBRARY_NAME=xpcomcomp_s
|
||||
|
||||
LINCS = \
|
||||
-I$(PUBLIC)\xpcom \
|
||||
-I$(PUBLIC)\libreg \
|
||||
-I..\base \
|
||||
-I..\threads \
|
||||
$(NULL)
|
||||
|
||||
LCFLAGS = -DUSE_NSREG -D_IMPL_NS_COM -D_IMPL_NS_BASE -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
CPP_OBJS = \
|
||||
.\$(OBJDIR)\nsComponentManager.obj \
|
||||
.\$(OBJDIR)\nsGenericFactory.obj \
|
||||
.\$(OBJDIR)\nsRegistry.obj \
|
||||
.\$(OBJDIR)\nsRepository.obj \
|
||||
.\$(OBJDIR)\nsServiceManager.obj \
|
||||
.\$(OBJDIR)\xcDll.obj \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
libs:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
168
mozilla/xpcom/components/mozIClassRegistry.h
Normal file
168
mozilla/xpcom/components/mozIClassRegistry.h
Normal file
@@ -0,0 +1,168 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#ifndef __mozIClassRegistry_h
|
||||
#define __mozIClassRegistry_h
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
/*---------------------------- mozIClassRegistry -------------------------------
|
||||
| This interface provides access to a mapping from mnemonic interface names |
|
||||
| to shared libraries where implementations of those interfaces can be located.|
|
||||
| |
|
||||
| This interface is designed to provide two things: |
|
||||
| 1. A means of less static binding between clients and the code that |
|
||||
| implements the XPCOM interfaces those clients use. This accomplished |
|
||||
| by the mapping from interface names to nsCID (and the shared libraries |
|
||||
| that implement those classes). |
|
||||
| 2. A means of dynamically changing the mapping from interface name to |
|
||||
| implementation. The canonical example of this is to switch to a |
|
||||
| "native" widget set versus an "XP" (implemented using gfx) set. |
|
||||
| |
|
||||
| The first goal is achieved by storing (in a "Netscape Registry" file, see |
|
||||
| nsReg.h) information that maps interface/class "names" to information about |
|
||||
| where to load implementations of those interfaces. That information |
|
||||
| includes the interface ID, class ID (of the implementation class), and the |
|
||||
| name of the shared library that contains the implementation. |
|
||||
| |
|
||||
| The class registry object will register those classes with the "repository" |
|
||||
| (see nsComponentManager.h) the first time a request is made to create an |
|
||||
| instance. Subsequent requests will simply be forwarded to the repository |
|
||||
| after the appropriate interface and class IDs are determined. |
|
||||
| |
|
||||
| The second goal is accomplished by permitting the mnemonic interface |
|
||||
| "names" to be "overloaded", that is, mapped to distinct implementations |
|
||||
| by separate class registry objects. Further, class registries can be |
|
||||
| cascaded: they can be chained together so that when a name is not |
|
||||
| recognized by one registry, it can pass the request to the next registry in |
|
||||
| the chain. Users can control resolution by making the request of a |
|
||||
| registry further up/down the chain. |
|
||||
| |
|
||||
| For example, consider the case of "native" vs. "gfx" widgets. This might |
|
||||
| be structured by a class registry arrangment like this: |
|
||||
| |
|
||||
| nativeWidgetRegistry baseWidgetRegistry |
|
||||
| +----------+ +----------+ |
|
||||
| | ----+---------------->| | |
|
||||
| +----------+ +----------+ |
|
||||
| |toolbar| -+-----+ |toolbar| -+-----+ |
|
||||
| +----------+ | +----------+ | |
|
||||
| |button | -+-----+ |button | -+-----+ |
|
||||
| +----------+ | +----------+ | |
|
||||
| V V |
|
||||
| +-----------------+ +-----------------+ |
|
||||
| | native.dll | | base.dll | |
|
||||
| +-----------------+ +-----------------+ |
|
||||
| |
|
||||
| If a specialized implementation of widgets is present (e.g., native.dll) |
|
||||
| then a corresponding class registry object is created and added to the |
|
||||
| head of the registry chain. Object creation requests (normal ones) are |
|
||||
| resolved to the native implementation. If such a library is not present, |
|
||||
| then the resolution is to the base implementation. If objects of the |
|
||||
| base implementation are required, then creation requests can be directed |
|
||||
| directly to the baseWidgetRegistry object, rather than the head of the |
|
||||
| registry chain. |
|
||||
| |
|
||||
| It is intended that there be a single instance of this interface, accessed |
|
||||
| via the Service Manager (see nsServiceManager.h). |
|
||||
------------------------------------------------------------------------------*/
|
||||
struct mozIClassRegistry : public ISupports {
|
||||
|
||||
/*------------------------------ CreateInstance ----------------------------
|
||||
| Create an instance of the requested class/interface. The interface |
|
||||
| ID is required to specify how the result will be treated. The class |
|
||||
| named by aName must support this interface. The result is placed in |
|
||||
| ncomment aResult (NULL if the request fails). "start" specifies the |
|
||||
| registry at which the search for an implementation of the named |
|
||||
| interface should start. It defaults to 0 (indicating to start at the |
|
||||
| head of the registry chain). |
|
||||
--------------------------------------------------------------------------*/
|
||||
NS_IMETHOD CreateInstance( const char *anInterfaceName,
|
||||
const nsIID &aIID,
|
||||
void* *aResult,
|
||||
const char *start = 0 ) = 0;
|
||||
|
||||
/*--------------------------- CreateEnumerator -----------------------------
|
||||
| Creates an nsIEnumerator interface object that can be used to examine |
|
||||
| the contents of the registry. "pattern" specifies either "*" or the |
|
||||
| name of a specific interface that you want to query. "result" will |
|
||||
| be set to point to a new object (which will be freed on the last call |
|
||||
| to its Release() member). See nsIEnumerator.h for details on how to |
|
||||
| use the returned interface pointer. |
|
||||
--------------------------------------------------------------------------*/
|
||||
NS_IMETHOD CreateEnumerator( const char *pattern,
|
||||
nsIEnumerator* *result ) = 0;
|
||||
}; // mozIClassRegistry
|
||||
|
||||
|
||||
/*-------------------------- mozIClassRegistryEntry ----------------------------
|
||||
| Objects of this class represent the individual elements that comprise a |
|
||||
| mozIClassRegistry interface. You obtain such objects by applying the |
|
||||
| CreateEnumerator member function to the class registry and then applying |
|
||||
| the CurrentItem member function to the resulting nsIEnumerator interface. |
|
||||
| |
|
||||
| Each entry can be queried for the following information: |
|
||||
| o sub-registry name |
|
||||
| o interface name |
|
||||
| o Class ID |
|
||||
| o IIDs implemented |
|
||||
| |
|
||||
| The information obtained from the entry (specifically, the const char* |
|
||||
| strings) remains valid for the life of the entry (i.e., until you |
|
||||
| Release() it). |
|
||||
| |
|
||||
| Here is an example of code that uses this interface to dump the contents |
|
||||
| of a mozIClassRegistry: |
|
||||
| |
|
||||
| mozIClassRegistry *reg = nsServiceManager::GetService( kIDRegistry ); |
|
||||
| nsIEnumerator *enum; |
|
||||
| reg->CreateEnumerator( "*", &enum ); |
|
||||
| for ( enum->First(); !enum->IsDone(); enum->Next(); ) { |
|
||||
| mozIClassRegistryEntry *entry; |
|
||||
| enum->CurrentItem( &entry ); |
|
||||
| const char *subreg; |
|
||||
| const char *name; |
|
||||
| nsCID cid; |
|
||||
| int numIIDs; |
|
||||
| entry->GetSubRegistryName( &subreg ); |
|
||||
| entry->GetInterfaceName( &name ); |
|
||||
| entry->GetClassID( &cid ); |
|
||||
| entry->GetNumIIDs( &numIIDs ); |
|
||||
| cout << subreg << "/" << name << " = " << cid.ToString() << endl; |
|
||||
| for ( int i = 0; i < numIIDs; i++ ) { |
|
||||
| nsIID iid; |
|
||||
| entry->GetInterfaceID( i, &iid ); |
|
||||
| cout << "/tIID[" << i << "] = " << iid.ToString() << endl; |
|
||||
| } |
|
||||
| entry->Release(); |
|
||||
| } |
|
||||
| enum->Release(); |
|
||||
------------------------------------------------------------------------------*/
|
||||
struct mozIClassRegistryEntry : public nsISupports {
|
||||
NS_IMETHOD GetSubRegistryName( const char **result ) = 0;
|
||||
NS_IMETHOD GetInterfaceName( const char **result ) = 0;
|
||||
NS_IMETHOD GetClassID( nsCID *result ) = 0;
|
||||
NS_IMETHOD GetNumIIDs( int *result ) = 0;
|
||||
NS_IMETHOD GetInterfaceID( int n, nsIID *result ) = 0;
|
||||
}; // mozIClassRegistryEntry
|
||||
|
||||
// {5D41A440-8E37-11d2-8059-00600811A9C3}
|
||||
#define MOZ_ICLASSREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
|
||||
// {D1B54831-AC07-11d2-805E-00600811A9C3}
|
||||
#define MOZ_ICLASSREGISTRYENTRY_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
|
||||
|
||||
#endif
|
||||
326
mozilla/xpcom/components/mozIRegistry.h
Normal file
326
mozilla/xpcom/components/mozIRegistry.h
Normal file
@@ -0,0 +1,326 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#ifndef __mozIRegistry_h
|
||||
#define __mozIRegistry_h
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsIEnumerator;
|
||||
|
||||
/*------------------------------- mozIRegistry ---------------------------------
|
||||
| This interface provides access to a tree of arbitrary values. |
|
||||
| |
|
||||
| Each node of the tree contains either a value or a subtree or both. |
|
||||
| |
|
||||
| The value at any of these leaf nodes can be any of these "primitive" types: |
|
||||
| o string (null terminated UTF string) |
|
||||
| o array of 32-bit integers |
|
||||
| o arbitrary array of bytes |
|
||||
| o file identifier |
|
||||
| Of course, since you can store an arbitrary array of bytes, you can put |
|
||||
| any data you like into a registry (although you have the burden of |
|
||||
| encoding/decoding your data in that case). |
|
||||
| |
|
||||
| Each branch of the tree is labelled with a string "key." The entire path |
|
||||
| from a given point of the tree to another point further down can be |
|
||||
| presented as a single string composed of each branch's label, concatenated |
|
||||
| to the next, with an intervening forward slash ('/'). The term "key" |
|
||||
| refers to both specific tree branch labels and to such concatenated paths. |
|
||||
| |
|
||||
| The branches from a given node must have unique labels. Distinct nodes can |
|
||||
| have branches with the same label. |
|
||||
| |
|
||||
| For example, here's a small registry tree: |
|
||||
| | |
|
||||
| /\ |
|
||||
| / \ |
|
||||
| / \ |
|
||||
| / \ |
|
||||
| "Classes" "Users" |
|
||||
| / \ |
|
||||
| / \ |
|
||||
| / ["joe"] |
|
||||
| / / \ |
|
||||
| | / \ |
|
||||
| /\ / \ |
|
||||
| / \ "joe" "bob" |
|
||||
| / \ / \ |
|
||||
| / \ |
|
||||
| "{xxxx-xx-1}" "{xxxx-xx-2}" ["c:/joe"] ["d:/Robert"] |
|
||||
| | | |
|
||||
| /\ /\ |
|
||||
| / \ / \ |
|
||||
| / \ / \ |
|
||||
| "Library" "Version" "Library" "Version" |
|
||||
| / \ / \ |
|
||||
| ["foo.dll"] 2 ["bar.dll"] 1 |
|
||||
| |
|
||||
| In this example, there are 2 keys under the root: "Classes" and "Users". |
|
||||
| The first denotes a subtree only (which has two subtrees, ...). The second |
|
||||
| denotes both a value ["joe"] and two subtrees labelled "joe" and "bob". |
|
||||
| The value at the node "/Users" is ["joe"], at "/Users/bob" is ["d:/Robert"]. |
|
||||
| The value at "/Classes/{xxxx-xx-1}/Version" is 2. |
|
||||
| |
|
||||
| The registry interface provides functions that let you navigate the tree |
|
||||
| and manipulate it's contents. |
|
||||
| |
|
||||
| Please note that the registry itself does not impose any structure or |
|
||||
| meaning on the contents of the tree. For example, the registry doesn't |
|
||||
| control whether the value at the key "/Users" is the label for the subtree |
|
||||
| with information about the last active user. That meaning is applied by |
|
||||
| the code that stores these values and uses them for that purpose. |
|
||||
| |
|
||||
| [Any resemblence between this example and actual contents of any actual |
|
||||
| registry is purely coincidental.] |
|
||||
------------------------------------------------------------------------------*/
|
||||
struct mozIRegistry : public nsISupports {
|
||||
/*------------------------------ Constants ---------------------------------
|
||||
| The following enumerated types and values are used by the registry |
|
||||
| interface. |
|
||||
--------------------------------------------------------------------------*/
|
||||
typedef enum {
|
||||
String = 1,
|
||||
Int32,
|
||||
Bytes,
|
||||
File
|
||||
} DataType;
|
||||
|
||||
/*-------------------------------- Types -----------------------------------
|
||||
| The following data types are used by this interface. All are basically |
|
||||
| opaque types. You obtain objects of these types via certain member |
|
||||
| function calls and re-use them later (without having to know what they |
|
||||
| contain). |
|
||||
| |
|
||||
| Key - Placeholder to represent a particular node in a registry |
|
||||
| tree. There are 3 enumerated values that correspond to |
|
||||
| specific nodes: |
|
||||
| Common - Where most stuff goes. |
|
||||
| Users - Special subtree to hold info about |
|
||||
| "users"; if you don't know what goes |
|
||||
| here, don't mess with it. |
|
||||
| CurrentUser - Subtree under Users corresponding to |
|
||||
| whatever user is designed the "current" |
|
||||
| one; see note above. |
|
||||
| You can specify any of these enumerated values as "keys" |
|
||||
| on any member function that takes a mozRegistry::Key. |
|
||||
| ValueInfo - Structure describing a registry value. |
|
||||
--------------------------------------------------------------------------*/
|
||||
typedef uint32 Key;
|
||||
|
||||
enum { Users = 1, Common = 2, CurrentUser = 3 };
|
||||
|
||||
struct ValueInfo {
|
||||
DataType type;
|
||||
uint32 length;
|
||||
};
|
||||
|
||||
/*--------------------------- Opening/Closing ------------------------------
|
||||
| These functions open the specified registry file (Open() with a non-null |
|
||||
| argument) or the default "standard" registry file (Open() with a null |
|
||||
| argument or OpenDefault()). |
|
||||
| |
|
||||
| Once opened, you can access the registry contents via the read/write |
|
||||
| or query functions. |
|
||||
| |
|
||||
| The registry file will be closed automatically when the registry object |
|
||||
| is destroyed. You can close the file prior to that by using the |
|
||||
| Close() function. |
|
||||
--------------------------------------------------------------------------*/
|
||||
NS_IMETHOD Open( const char *regFile = 0 ) = 0;
|
||||
NS_IMETHOD OpenDefault() = 0;
|
||||
NS_IMETHOD Close() = 0;
|
||||
|
||||
/*----------------------- Reading/Writing Values ---------------------------
|
||||
| These functions read/write the registry values at a given node. |
|
||||
| |
|
||||
| All functions require you to specify where in the registry key to |
|
||||
| get/set the value. The location is specified using two components: |
|
||||
| o A "base key" indicating where to start from; this is a value of type |
|
||||
| mozIRegistry::Key. You use either one of the special "root" key |
|
||||
| values or a subkey obtained via some other member function call. |
|
||||
| o A "relative path," expressed as a sequence of subtree names |
|
||||
| separated by forward slashes. This path describes how to get from |
|
||||
| the base key to the node at which you want to store the data. This |
|
||||
| component can be a null pointer which means the value goes directly |
|
||||
| at the node denoted by the base key. |
|
||||
| |
|
||||
| When you request a value of a given type, the data stored at the |
|
||||
| specified node must be of the type requested. If not, an error results. |
|
||||
| |
|
||||
| GetString - Obtains a newly allocated copy of a string type value. The |
|
||||
| caller is obligated to free the returned string using |
|
||||
| PR_Free. |
|
||||
| SetString - Stores the argument string at the specified node. |
|
||||
| GetInt - Obtains an int32 value at the specified node. The result |
|
||||
| is returned into an int32 location you specify. |
|
||||
| SetInt - Stores a given int32 value at a node. |
|
||||
| GetBytes - Obtains a byte array value; this returns both an allocated |
|
||||
| array of bytes and a length (necessary because there may be |
|
||||
| embedded null bytes in the array). You must free the |
|
||||
| resulting array using PR_Free. |
|
||||
| SetBytes - Stores a given array of bytes; you specify the bytes via a |
|
||||
| pointer and a length. |
|
||||
| GetIntArray - Obtains the array of int32 values stored at a given node. |
|
||||
| The result is composed of two values: a pointer to an |
|
||||
| array of integer values (which must be freed using |
|
||||
| PR_Free) and the number of elements in that array. |
|
||||
| SetIntArray - Stores a set of int32 values at a given node. You must |
|
||||
| provide a pointer to the array and the number of entries. |
|
||||
--------------------------------------------------------------------------*/
|
||||
NS_IMETHOD GetString( Key baseKey, const char *path, char **result ) = 0;
|
||||
NS_IMETHOD SetString( Key baseKey, const char *path, const char *value ) = 0;
|
||||
NS_IMETHOD GetInt( Key baseKey, const char *path, int32 *result ) = 0;
|
||||
NS_IMETHOD SetInt( Key baseKey, const char *path, int32 value ) = 0;
|
||||
NS_IMETHOD GetBytes( Key baseKey, const char *path, void **result, uint32 *len ) = 0;
|
||||
NS_IMETHOD SetBytes( Key baseKey, const char *path, void *value, uint32 len ) = 0;
|
||||
NS_IMETHOD GetIntArray( Key baseKey, const char *path, int32 **result, uint32 *len ) = 0;
|
||||
NS_IMETHOD SetIntArray( Key baseKey, const char *path, const int32 *value, uint32 len ) = 0;
|
||||
|
||||
/*------------------------------ Navigation --------------------------------
|
||||
| These functions let you navigate through the registry tree, querying |
|
||||
| its contents. |
|
||||
| |
|
||||
| As above, all these functions requires a starting tree location ("base |
|
||||
| key") specified as a mozIRegistry::Key. Some also require a path |
|
||||
| name to locate the registry node location relative to this base key. |
|
||||
| |
|
||||
| AddSubtree - Adds a new registry subtree at the specified |
|
||||
| location. Returns the resulting key in |
|
||||
| the location specified by the third argument |
|
||||
| (unless that pointer is 0). |
|
||||
| RemoveNode - Removes the specified registry subtree or |
|
||||
| value at the specified location. |
|
||||
| GetSubtree - Returns a mozIRegistry::Key that can be used |
|
||||
| to refer to the specified registry location. |
|
||||
| EnumerateSubtrees - Returns a nsIEnumerator object that you can |
|
||||
| use to enumerate all the subtrees descending |
|
||||
| from a specified location. You must free the |
|
||||
| enumerator via Release() when you're done with |
|
||||
| it. |
|
||||
| EnumerateAllSubtrees - Like EnumerateSubtrees, but will recursively |
|
||||
| enumerate lower-level subtrees, too. |
|
||||
| GetValueInfo - Returns a uint32 value that designates the type |
|
||||
| of data stored at this location in the registry; |
|
||||
| the possible values are defined by the enumerated |
|
||||
| type mozIRegistry::DataType. |
|
||||
| GetValueLength - Returns a uint32 value that indicates the length |
|
||||
| of this registry value; the length is the number |
|
||||
| of characters (for Strings), the number of bytes |
|
||||
| (for Bytes), or the number of int32 values (for |
|
||||
| Int32). |
|
||||
| EnumerateValues - Returns a nsIEnumerator that you can use to |
|
||||
| enumerate all the value nodes descending from |
|
||||
| a specified location. |
|
||||
--------------------------------------------------------------------------*/
|
||||
NS_IMETHOD AddSubtree( Key baseKey, const char *path, Key *result ) = 0;
|
||||
NS_IMETHOD RemoveSubtree( Key baseKey, const char *path ) = 0;
|
||||
NS_IMETHOD GetSubtree( Key baseKey, const char *path, Key *result ) = 0;
|
||||
|
||||
NS_IMETHOD EnumerateSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
|
||||
NS_IMETHOD EnumerateAllSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
|
||||
|
||||
NS_IMETHOD GetValueType( Key baseKey, const char *path, uint32 *result ) = 0;
|
||||
NS_IMETHOD GetValueLength( Key baseKey, const char *path, uint32 *result ) = 0;
|
||||
|
||||
NS_IMETHOD EnumerateValues( Key baseKey, nsIEnumerator **result ) = 0;
|
||||
|
||||
/*------------------------------ User Name ---------------------------------
|
||||
| These functions manipulate the current "user name." This value controls |
|
||||
| the behavior of certain registry functions (namely, ?). |
|
||||
| |
|
||||
| GetCurrentUserName allocates a copy of the current user name (which the |
|
||||
| caller should free using PR_Free). |
|
||||
--------------------------------------------------------------------------*/
|
||||
NS_IMETHOD GetCurrentUserName( char **result ) = 0;
|
||||
NS_IMETHOD SetCurrentUserName( const char *name ) = 0;
|
||||
|
||||
/*------------------------------ Utilities ---------------------------------
|
||||
| Various utility functions: |
|
||||
| |
|
||||
| Pack() is used to compress the contents of an open registry file. |
|
||||
--------------------------------------------------------------------------*/
|
||||
NS_IMETHOD Pack() = 0;
|
||||
|
||||
}; // mozIRegistry
|
||||
|
||||
/*----------------------------- mozIRegistryNode -------------------------------
|
||||
| This interface is implemented by all the objects obtained from the |
|
||||
| nsIEnumerators that mozIRegistry provides when you call either of the |
|
||||
| subtree enumeration functions EnumerateSubtrees or EnumerateAllSubtrees. |
|
||||
| |
|
||||
| You can call this function to get the name of this subtree. This is the |
|
||||
| relative path from the base key from which you got this interface. |
|
||||
| |
|
||||
| GetName - Returns the path name of this node; this is the relative path |
|
||||
| from the base key from which this subtree was obtained. The |
|
||||
| function allocates a copy of the name; the caller must free it |
|
||||
| using PR_Free. |
|
||||
------------------------------------------------------------------------------*/
|
||||
struct mozIRegistryNode : public nsISupports {
|
||||
NS_IMETHOD GetName( char **result ) = 0;
|
||||
}; // mozIRegistryNode
|
||||
|
||||
/*----------------------------- mozIRegistryValue ------------------------------
|
||||
| This interface is implemented by the objects obtained from the |
|
||||
| nsIEnumerators that mozIRegistry provides when you call the |
|
||||
| EnumerateValues function. An object supporting this interface is |
|
||||
| returned when you call the CurrentItem() function on that enumerator. |
|
||||
| |
|
||||
| You use the member functions of this interface to obtain information |
|
||||
| about each registry value. |
|
||||
| |
|
||||
| GetName - Returns the path name of this node; this is the relative |
|
||||
| path\ from the base key from which this value was obtained. |
|
||||
| The function allocates a copy of the name; the caller must |
|
||||
| subsequently free it via PR_Free. |
|
||||
| GetValueType - Returns (into a location provided by the caller) the type |
|
||||
| of the value; the types are defined by the enumerated |
|
||||
| type mozIRegistry::DataType. |
|
||||
| GetValueLength - Returns a uint32 value that indicates the length |
|
||||
| of this registry value; the length is the number |
|
||||
| of characters (for Strings), the number of bytes |
|
||||
| (for Bytes), or the number of int32 values (for |
|
||||
| Int32). |
|
||||
------------------------------------------------------------------------------*/
|
||||
struct mozIRegistryValue : public nsISupports {
|
||||
NS_IMETHOD GetName( char **result ) = 0;
|
||||
NS_IMETHOD GetValueType( uint32 *result ) = 0;
|
||||
NS_IMETHOD GetValueLength( uint32 *result ) = 0;
|
||||
}; // mozIRegistryEntry
|
||||
|
||||
|
||||
/*------------------------------- Error Codes ----------------------------------
|
||||
------------------------------------------------------------------------------*/
|
||||
#define NS_ERROR_REG_BADTYPE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 1 )
|
||||
#define NS_ERROR_REG_NO_MORE NS_ERROR_GENERATE_SUCCESS( NS_ERROR_MODULE_REG, 2 )
|
||||
#define NS_ERROR_REG_NOT_FOUND NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 3 )
|
||||
#define NS_ERROR_REG_NOFILE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 4 )
|
||||
#define NS_ERROR_REG_BUFFER_TOO_SMALL NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 5 )
|
||||
#define NS_ERROR_REG_NAME_TOO_LONG NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 6 )
|
||||
#define NS_ERROR_REG_NO_PATH NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 7 )
|
||||
#define NS_ERROR_REG_READ_ONLY NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 8 )
|
||||
#define NS_ERROR_REG_BAD_UTF8 NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 9 )
|
||||
|
||||
// {5D41A440-8E37-11d2-8059-00600811A9C3}
|
||||
#define MOZ_IREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
|
||||
// {D1B54831-AC07-11d2-805E-00600811A9C3}
|
||||
#define MOZ_IREGISTRYNODE_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
|
||||
// {5316C380-B2F8-11d2-A374-0080C6F80E4B}
|
||||
#define MOZ_IREGISTRYVALUE_IID { 0x5316c380, 0xb2f8, 0x11d2, { 0xa3, 0x74, 0x0, 0x80, 0xc6, 0xf8, 0xe, 0x4b } }
|
||||
|
||||
#endif
|
||||
1191
mozilla/xpcom/components/mozRegistry.cpp
Normal file
1191
mozilla/xpcom/components/mozRegistry.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2106
mozilla/xpcom/components/nsComponentManager.cpp
Normal file
2106
mozilla/xpcom/components/nsComponentManager.cpp
Normal file
File diff suppressed because it is too large
Load Diff
260
mozilla/xpcom/components/nsComponentManager.h
Normal file
260
mozilla/xpcom/components/nsComponentManager.h
Normal file
@@ -0,0 +1,260 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsComponentManager_h__
|
||||
#define nsComponentManager_h__
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIRegistry.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "prtime.h"
|
||||
#include "prmon.h"
|
||||
|
||||
class nsFactoryEntry;
|
||||
class nsDll;
|
||||
|
||||
// Registry Factory creation function defined in nsRegistry.cpp
|
||||
// We hook into this function locally to create and register the registry
|
||||
// Since noone outside xpcom needs to know about this and nsRegistry.cpp
|
||||
// does not have a local include file, we are putting this definition
|
||||
// here rather than in nsIRegistry.h
|
||||
extern "C" NS_EXPORT nsresult NS_RegistryGetFactory(nsIFactory** aFactory);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsComponentManagerImpl : public nsIComponentManager {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIComponentManager methods:
|
||||
NS_IMETHOD FindFactory(const nsCID &aClass,
|
||||
nsIFactory **aFactory);
|
||||
|
||||
// Finds a class ID for a specific Program ID
|
||||
NS_IMETHOD ProgIDToCLSID(const char *aProgID,
|
||||
nsCID *aClass);
|
||||
|
||||
// Finds a Program ID for a specific class ID
|
||||
// caller frees the result with delete[]
|
||||
NS_IMETHOD CLSIDToProgID(nsCID *aClass,
|
||||
char* *aClassName,
|
||||
char* *aProgID);
|
||||
|
||||
// Creates a class instance for a specific class ID
|
||||
NS_IMETHOD CreateInstance(const nsCID &aClass,
|
||||
nsISupports *aDelegate,
|
||||
const nsIID &aIID,
|
||||
void **aResult);
|
||||
|
||||
// Convenience routine, creates a class instance for a specific ProgID
|
||||
NS_IMETHOD CreateInstance(const char *aProgID,
|
||||
nsISupports *aDelegate,
|
||||
const nsIID &aIID,
|
||||
void **aResult);
|
||||
|
||||
// Manually registry a factory for a class
|
||||
NS_IMETHOD RegisterFactory(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory *aFactory,
|
||||
PRBool aReplace);
|
||||
|
||||
// Manually register a dynamically loaded component.
|
||||
// The libraryPersistentDescriptor is what gets passed to the library
|
||||
// self register function from ComponentManager. The format of this string
|
||||
// is the same as nsIFileSpec::GetPersistentDescriptorString()
|
||||
//
|
||||
// This function will go away in favour of RegisterComponentSpec. In fact,
|
||||
// it internally turns around and calls RegisterComponentSpec.
|
||||
NS_IMETHOD RegisterComponent(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
const char *aLibraryPersistentDescriptor,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist);
|
||||
|
||||
// Register a component using its FileSpec as its identification
|
||||
// This is the more prevalent use.
|
||||
NS_IMETHOD RegisterComponentSpec(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFileSpec *aLibrary,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist);
|
||||
|
||||
// Register a component using its dllName. This could be a dll name with
|
||||
// no path so that LD_LIBRARY_PATH on unix or PATH on win can load it. Or
|
||||
// this could be a code fragment name on the Mac.
|
||||
NS_IMETHOD RegisterComponentLib(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
const char *adllName,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist);
|
||||
|
||||
// Manually unregister a factory for a class
|
||||
NS_IMETHOD UnregisterFactory(const nsCID &aClass,
|
||||
nsIFactory *aFactory);
|
||||
|
||||
// Manually unregister a dynamically loaded component
|
||||
NS_IMETHOD UnregisterComponent(const nsCID &aClass,
|
||||
const char *aLibrary);
|
||||
|
||||
// Unload dynamically loaded factories that are not in use
|
||||
NS_IMETHOD FreeLibraries(void);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// DLL registration support
|
||||
// Autoregistration will try only files with these extensions.
|
||||
// All extensions are case insensitive.
|
||||
// ".dll", // Windows
|
||||
// ".dso", // Unix
|
||||
// ".so", // Unix
|
||||
// ".sl", // Unix: HP
|
||||
// ".shlb", // Mac
|
||||
// ".dlm", // new for all platforms
|
||||
//
|
||||
//
|
||||
NS_IMETHOD AutoRegister(RegistrationTime when, nsIFileSpec *directory);
|
||||
NS_IMETHOD AutoRegisterComponent(RegistrationTime when, nsIFileSpec *component);
|
||||
|
||||
// nsComponentManagerImpl methods:
|
||||
nsComponentManagerImpl();
|
||||
virtual ~nsComponentManagerImpl();
|
||||
|
||||
static nsComponentManagerImpl* gComponentManager;
|
||||
nsresult Init(void);
|
||||
nsresult PlatformPrePopulateRegistry();
|
||||
|
||||
protected:
|
||||
nsresult LoadFactory(nsFactoryEntry *aEntry, nsIFactory **aFactory);
|
||||
nsFactoryEntry *GetFactoryEntry(const nsCID &aClass, PRBool checkRegistry);
|
||||
|
||||
nsresult SyncComponentsInDir(RegistrationTime when, nsIFileSpec *dirSpec);
|
||||
nsresult SelfRegisterDll(nsDll *dll);
|
||||
nsresult SelfUnregisterDll(nsDll *dll);
|
||||
nsresult HashProgID(const char *aprogID, const nsCID &aClass);
|
||||
nsDll *CreateCachedDll(const char *persistentDescriptor, PRUint32 modDate, PRUint32 size);
|
||||
nsDll *CreateCachedDll(nsIFileSpec *dllSpec);
|
||||
nsDll *CreateCachedDllName(const char *dllName);
|
||||
|
||||
// The following functions are the only ones that operate on the persistent
|
||||
// registry
|
||||
nsresult PlatformInit(void);
|
||||
nsresult PlatformVersionCheck();
|
||||
nsresult PlatformCreateDll(const char *fullname, nsDll* *result);
|
||||
nsresult PlatformMarkNoComponents(nsDll *dll);
|
||||
nsresult PlatformRegister(const char *cidString, const char *className, const char *progID, nsDll *dll);
|
||||
nsresult PlatformUnregister(const char *cidString, const char *aLibrary);
|
||||
nsresult PlatformFind(const nsCID &aCID, nsFactoryEntry* *result);
|
||||
nsresult PlatformProgIDToCLSID(const char *aProgID, nsCID *aClass);
|
||||
nsresult PlatformCLSIDToProgID(nsCID *aClass, char* *aClassName, char* *aProgID);
|
||||
void PlatformGetFileInfo(nsIRegistry::Key Key, PRUint32 *lastModifiedTime, PRUint32 *fileSize);
|
||||
void PlatformSetFileInfo(nsIRegistry::Key Key, PRUint32 lastModifiedTime, PRUint32 fileSize);
|
||||
|
||||
protected:
|
||||
nsHashtable* mFactories;
|
||||
nsHashtable* mProgIDs;
|
||||
PRMonitor* mMon;
|
||||
nsHashtable* mDllStore;
|
||||
nsIRegistry* mRegistry;
|
||||
nsIRegistry::Key mXPCOMKey;
|
||||
nsIRegistry::Key mClassesKey;
|
||||
nsIRegistry::Key mCLSIDKey;
|
||||
};
|
||||
|
||||
#define NS_MAX_FILENAME_LEN 1024
|
||||
|
||||
#define NS_ERROR_IS_DIR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCOM, 24)
|
||||
|
||||
#ifdef XP_UNIX
|
||||
/* The default registry on the unix system is $HOME/.mozilla/registry per
|
||||
* vr_findGlobalRegName(). vr_findRegFile() will create the registry file
|
||||
* if it doesn't exist. But it wont create directories.
|
||||
*
|
||||
* Hence we need to create the directory if it doesn't exist already.
|
||||
*
|
||||
* Why create it here as opposed to the app ?
|
||||
* ------------------------------------------
|
||||
* The app cannot create the directory in main() as most of the registry
|
||||
* and initialization happens due to use of static variables.
|
||||
* And we dont want to be dependent on the order in which
|
||||
* these static stuff happen.
|
||||
*
|
||||
* Permission for the $HOME/.mozilla will be Read,Write,Execute
|
||||
* for user only. Nothing to group and others.
|
||||
*/
|
||||
#define NS_MOZILLA_DIR_NAME ".mozilla"
|
||||
#define NS_MOZILLA_DIR_PERMISSION 00700
|
||||
#endif /* XP_UNIX */
|
||||
|
||||
#ifdef XP_BEOS
|
||||
#define NS_MOZILLA_DIR_NAME "mozilla"
|
||||
#define NS_MOZILLA_DIR_PERMISSION 00700
|
||||
#endif /* XP_BEOS */
|
||||
|
||||
/**
|
||||
* When using the registry we put a version number in it.
|
||||
* If the version number that is in the registry doesn't match
|
||||
* the following, we ignore the registry. This lets news versions
|
||||
* of the software deal with old formats of registry and not
|
||||
*
|
||||
* alpha0.20 : First time we did versioning
|
||||
* alpha0.30 : Changing autoreg to begin registration from ./components on unix
|
||||
* alpha0.40 : repository -> component manager
|
||||
* alpha0.50 : using nsIRegistry
|
||||
* alpha0.60 : xpcom 2.0 landing
|
||||
* alpha0.70 : using nsIFileSpec. PRTime -> PRUint32
|
||||
*/
|
||||
#define NS_XPCOM_COMPONENT_MANAGER_VERSION_STRING "alpha0.70"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Class: nsFactoryEntry()
|
||||
*
|
||||
* There are two types of FactoryEntries.
|
||||
*
|
||||
* 1. {CID, dll} mapping.
|
||||
* Factory is a consequence of the dll. These can be either session
|
||||
* specific or persistent based on whether we write this
|
||||
* to the registry or not.
|
||||
*
|
||||
* 2. {CID, factory} mapping
|
||||
* These are strictly session specific and in memory only.
|
||||
*/
|
||||
|
||||
class nsFactoryEntry {
|
||||
public:
|
||||
nsFactoryEntry(const nsCID &aClass, nsDll *dll);
|
||||
nsFactoryEntry(const nsCID &aClass, nsIFactory *aFactory);
|
||||
~nsFactoryEntry();
|
||||
|
||||
nsresult Init(nsHashtable* dllHashtable, const nsCID &aClass, const char *aLibrary,
|
||||
PRTime lastModTime, PRUint32 fileSize);
|
||||
|
||||
nsCID cid;
|
||||
nsIFactory *factory;
|
||||
|
||||
// DO NOT DELETE THIS. Many nsFactoryEntry(s) could be sharing the same Dll.
|
||||
// This gets deleted from the dllStore going away.
|
||||
nsDll *dll;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // nsComponentManager_h__
|
||||
110
mozilla/xpcom/components/nsGenericFactory.cpp
Normal file
110
mozilla/xpcom/components/nsGenericFactory.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsGenericFactory.h"
|
||||
|
||||
nsGenericFactory::nsGenericFactory(ConstructorProcPtr constructor)
|
||||
: mConstructor(constructor), mDestructor(NULL)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsGenericFactory::~nsGenericFactory()
|
||||
{
|
||||
if (mDestructor != NULL)
|
||||
(*mDestructor) ();
|
||||
}
|
||||
|
||||
NS_METHOD nsGenericFactory::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (aIID.Equals(nsIGenericFactory::GetIID()) ||
|
||||
aIID.Equals(nsIFactory::GetIID()) ||
|
||||
aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID())) {
|
||||
*aInstancePtr = (nsIGenericFactory*) this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsGenericFactory)
|
||||
NS_IMPL_RELEASE(nsGenericFactory)
|
||||
|
||||
NS_IMETHODIMP nsGenericFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
return mConstructor(aOuter, aIID, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsGenericFactory::LockFactory(PRBool aLock)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsGenericFactory::SetConstructor(ConstructorProcPtr constructor)
|
||||
{
|
||||
mConstructor = constructor;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsGenericFactory::SetDestructor(DestructorProcPtr destructor)
|
||||
{
|
||||
mDestructor = destructor;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsGenericFactory::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
|
||||
{
|
||||
// sorry, aggregation not spoken here.
|
||||
nsresult res = NS_ERROR_NO_AGGREGATION;
|
||||
if (outer == NULL) {
|
||||
nsGenericFactory* factory = new nsGenericFactory;
|
||||
if (factory != NULL) {
|
||||
res = factory->QueryInterface(aIID, aInstancePtr);
|
||||
if (res != NS_OK)
|
||||
delete factory;
|
||||
} else {
|
||||
res = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_COM nsresult
|
||||
NS_NewGenericFactory(nsIGenericFactory* *result,
|
||||
nsIGenericFactory::ConstructorProcPtr constructor,
|
||||
nsIGenericFactory::DestructorProcPtr destructor)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIGenericFactory* fact;
|
||||
rv = nsGenericFactory::Create(NULL, nsIGenericFactory::GetIID(), (void**)&fact);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = fact->SetConstructor(constructor);
|
||||
if (NS_FAILED(rv)) goto error;
|
||||
rv = fact->SetDestructor(destructor);
|
||||
if (NS_FAILED(rv)) goto error;
|
||||
*result = fact;
|
||||
return rv;
|
||||
|
||||
error:
|
||||
NS_RELEASE(fact);
|
||||
return rv;
|
||||
}
|
||||
|
||||
60
mozilla/xpcom/components/nsGenericFactory.h
Normal file
60
mozilla/xpcom/components/nsGenericFactory.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsGenericFactory_h___
|
||||
#define nsGenericFactory_h___
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
|
||||
/**
|
||||
* Most factories follow this simple pattern, so why not just use a function pointer
|
||||
* for most creation operations?
|
||||
*/
|
||||
class nsGenericFactory : public nsIGenericFactory {
|
||||
public:
|
||||
static const nsCID& CID() { static nsCID cid = NS_GENERICFACTORY_CID; return cid; }
|
||||
|
||||
nsGenericFactory(ConstructorProcPtr constructor = NULL);
|
||||
virtual ~nsGenericFactory();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
NS_IMETHOD LockFactory(PRBool aLock);
|
||||
|
||||
/**
|
||||
* Establishes the generic factory's constructor function, which will be called
|
||||
* by CreateInstance.
|
||||
*/
|
||||
NS_IMETHOD SetConstructor(ConstructorProcPtr constructor);
|
||||
|
||||
/**
|
||||
* Establishes the generic factory's destructor function, which will be called
|
||||
* whe the generic factory is deleted. This is used to notify the DLL that
|
||||
* an instance of one of its generic factories is going away.
|
||||
*/
|
||||
NS_IMETHOD SetDestructor(DestructorProcPtr destructor);
|
||||
|
||||
static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
|
||||
private:
|
||||
ConstructorProcPtr mConstructor;
|
||||
DestructorProcPtr mDestructor;
|
||||
};
|
||||
|
||||
#endif /* nsGenericFactory_h___ */
|
||||
286
mozilla/xpcom/components/nsIComponentManager.h
Normal file
286
mozilla/xpcom/components/nsIComponentManager.h
Normal file
@@ -0,0 +1,286 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIComponentManager_h__
|
||||
#define nsIComponentManager_h__
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "nsCom.h"
|
||||
#include "nsID.h"
|
||||
#include "nsError.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsIFileSpec.h"
|
||||
|
||||
/*
|
||||
* Prototypes for dynamic library export functions. Your DLL/DSO needs to export
|
||||
* these methods to play in the component world.
|
||||
*/
|
||||
|
||||
extern "C" NS_EXPORT nsresult NSGetFactory(nsISupports* aServMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory);
|
||||
extern "C" NS_EXPORT PRBool NSCanUnload(nsISupports* aServMgr);
|
||||
extern "C" NS_EXPORT nsresult NSRegisterSelf(nsISupports* aServMgr, const char *fullpath);
|
||||
extern "C" NS_EXPORT nsresult NSUnregisterSelf(nsISupports* aServMgr, const char *fullpath);
|
||||
|
||||
typedef nsresult (*nsFactoryProc)(nsISupports* aServMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory);
|
||||
typedef PRBool (*nsCanUnloadProc)(nsISupports* aServMgr);
|
||||
typedef nsresult (*nsRegisterProc)(nsISupports* aServMgr, const char *path);
|
||||
typedef nsresult (*nsUnregisterProc)(nsISupports* aServMgr, const char *path);
|
||||
|
||||
#define NS_ICOMPONENTMANAGER_IID \
|
||||
{ /* 8458a740-d5dc-11d2-92fb-00e09805570f */ \
|
||||
0x8458a740, \
|
||||
0xd5dc, \
|
||||
0x11d2, \
|
||||
{0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f} \
|
||||
}
|
||||
|
||||
#define NS_COMPONENTMANAGER_CID \
|
||||
{ /* 91775d60-d5dc-11d2-92fb-00e09805570f */ \
|
||||
0x91775d60, \
|
||||
0xd5dc, \
|
||||
0x11d2, \
|
||||
{0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f} \
|
||||
}
|
||||
|
||||
/*
|
||||
* nsIComponentManager interface
|
||||
*/
|
||||
|
||||
class nsIComponentManager : public nsISupports {
|
||||
public:
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICOMPONENTMANAGER_IID)
|
||||
|
||||
NS_IMETHOD FindFactory(const nsCID &aClass,
|
||||
nsIFactory **aFactory) = 0;
|
||||
|
||||
// Finds a class ID for a specific Program ID
|
||||
NS_IMETHOD ProgIDToCLSID(const char *aProgID,
|
||||
nsCID *aClass) = 0;
|
||||
|
||||
// Finds a Program ID for a specific class ID
|
||||
// caller frees the result with delete[]
|
||||
NS_IMETHOD CLSIDToProgID(nsCID *aClass,
|
||||
char* *aClassName,
|
||||
char* *aProgID) = 0;
|
||||
|
||||
// Creates a class instance for a specific class ID
|
||||
NS_IMETHOD CreateInstance(const nsCID &aClass,
|
||||
nsISupports *aDelegate,
|
||||
const nsIID &aIID,
|
||||
void **aResult) = 0;
|
||||
|
||||
// Convenience routine, creates a class instance for a specific ProgID
|
||||
NS_IMETHOD CreateInstance(const char *aProgID,
|
||||
nsISupports *aDelegate,
|
||||
const nsIID &aIID,
|
||||
void **aResult) = 0;
|
||||
|
||||
// Manually registry a factory for a class
|
||||
NS_IMETHOD RegisterFactory(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory *aFactory,
|
||||
PRBool aReplace) = 0;
|
||||
|
||||
// Manually register a dynamically loaded component.
|
||||
// The libraryPersistentDescriptor is what gets passed to the library
|
||||
// self register function from ComponentManager. The format of this string
|
||||
// is the same as nsIFileSpec::GetPersistentDescriptorString()
|
||||
//
|
||||
// This function will go away in favour of RegisterComponentSpec. In fact,
|
||||
// it internally turns around and calls RegisterComponentSpec.
|
||||
NS_IMETHOD RegisterComponent(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
const char *aLibraryPersistentDescriptor,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist) = 0;
|
||||
|
||||
// Register a component using its FileSpec as its identification
|
||||
// This is the more prevalent use.
|
||||
NS_IMETHOD RegisterComponentSpec(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFileSpec *aLibrary,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist) = 0;
|
||||
|
||||
// Register a component using its dllName. This could be a dll name with
|
||||
// no path so that LD_LIBRARY_PATH on unix or PATH on win can load it. Or
|
||||
// this could be a code fragment name on the Mac.
|
||||
NS_IMETHOD RegisterComponentLib(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
const char *adllName,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist) = 0;
|
||||
|
||||
// Manually unregister a factory for a class
|
||||
NS_IMETHOD UnregisterFactory(const nsCID &aClass,
|
||||
nsIFactory *aFactory) = 0;
|
||||
|
||||
// Manually unregister a dynamically loaded component
|
||||
NS_IMETHOD UnregisterComponent(const nsCID &aClass,
|
||||
const char *aLibrary) = 0;
|
||||
|
||||
// Unload dynamically loaded factories that are not in use
|
||||
NS_IMETHOD FreeLibraries(void) = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// DLL registration support
|
||||
// Autoregistration will try only files with these extensions.
|
||||
// All extensions are case insensitive.
|
||||
// ".dll", // Windows
|
||||
// ".dso", // Unix
|
||||
// ".so", // Unix
|
||||
// ".sl", // Unix: HP
|
||||
// ".shlb", // Mac
|
||||
// ".dlm", // new for all platforms
|
||||
//
|
||||
// Directory and fullname are what NSPR will accept. For eg.
|
||||
// MAC /Hard drive/mozilla/dist/bin
|
||||
// WIN y:\Hard drive\mozilla\dist\bin (or) y:/Hard drive/mozilla/dist/bin
|
||||
// UNIX /Hard drive/mozilla/dist/bin
|
||||
//
|
||||
enum RegistrationTime {
|
||||
NS_Startup = 0,
|
||||
NS_Script = 1,
|
||||
NS_Timer = 2
|
||||
};
|
||||
|
||||
NS_IMETHOD AutoRegister(RegistrationTime when, nsIFileSpec* directory) = 0;
|
||||
NS_IMETHOD AutoRegisterComponent(RegistrationTime when, nsIFileSpec *component) = 0;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern NS_COM nsresult
|
||||
NS_GetGlobalComponentManager(nsIComponentManager* *result);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Global Static Component Manager Methods
|
||||
// (for when you need to link with xpcom)
|
||||
|
||||
class NS_COM nsComponentManager {
|
||||
public:
|
||||
static nsresult Initialize(void);
|
||||
|
||||
// Finds a factory for a specific class ID
|
||||
static nsresult FindFactory(const nsCID &aClass,
|
||||
nsIFactory **aFactory);
|
||||
|
||||
// Finds a class ID for a specific Program ID
|
||||
static nsresult ProgIDToCLSID(const char *aProgID,
|
||||
nsCID *aClass);
|
||||
|
||||
// Finds a Program ID for a specific class ID
|
||||
// caller frees the result with delete[]
|
||||
static nsresult CLSIDToProgID(nsCID *aClass,
|
||||
char* *aClassName,
|
||||
char* *aProgID);
|
||||
|
||||
// Creates a class instance for a specific class ID
|
||||
static nsresult CreateInstance(const nsCID &aClass,
|
||||
nsISupports *aDelegate,
|
||||
const nsIID &aIID,
|
||||
void **aResult);
|
||||
|
||||
// Convenience routine, creates a class instance for a specific ProgID
|
||||
static nsresult CreateInstance(const char *aProgID,
|
||||
nsISupports *aDelegate,
|
||||
const nsIID &aIID,
|
||||
void **aResult);
|
||||
|
||||
// Manually registry a factory for a class
|
||||
static nsresult RegisterFactory(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory *aFactory,
|
||||
PRBool aReplace);
|
||||
|
||||
// Manually register a dynamically loaded component.
|
||||
// The libraryPersistentDescriptor is what gets passed to the library
|
||||
// self register function from ComponentManager. The format of this string
|
||||
// is the same as nsIFileSpec::GetPersistentDescriptorString()
|
||||
//
|
||||
// This function will go away in favour of RegisterComponentSpec. In fact,
|
||||
// it internally turns around and calls RegisterComponentSpec.
|
||||
static nsresult RegisterComponent(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
const char *aLibraryPersistentDescriptor,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist);
|
||||
|
||||
// Register a component using its FileSpec as its identification
|
||||
// This is the more prevalent use.
|
||||
static nsresult RegisterComponentSpec(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFileSpec *aLibrary,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist);
|
||||
|
||||
// Register a component using its dllName. This could be a dll name with
|
||||
// no path so that LD_LIBRARY_PATH on unix or PATH on win can load it. Or
|
||||
// this could be a code fragment name on the Mac.
|
||||
static nsresult RegisterComponentLib(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
const char *adllName,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist);
|
||||
|
||||
|
||||
// Manually unregister a factory for a class
|
||||
static nsresult UnregisterFactory(const nsCID &aClass,
|
||||
nsIFactory *aFactory);
|
||||
|
||||
// Manually unregister a dynamically loaded component
|
||||
static nsresult UnregisterComponent(const nsCID &aClass,
|
||||
const char *aLibrary);
|
||||
|
||||
// Unload dynamically loaded factories that are not in use
|
||||
static nsresult FreeLibraries(void);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// DLL registration support
|
||||
|
||||
// If directory is NULL, then AutoRegister will try registering components
|
||||
// in the default components directory which is got by
|
||||
// nsSpecialSystemDirectory(XPCOM_CurrentProcessComponentDirectory)
|
||||
static nsresult AutoRegister(nsIComponentManager::RegistrationTime when,
|
||||
nsIFileSpec* directory);
|
||||
static nsresult AutoRegisterComponent(nsIComponentManager::RegistrationTime when,
|
||||
nsIFileSpec *component);
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
||||
39
mozilla/xpcom/components/nsIFactory.h
Normal file
39
mozilla/xpcom/components/nsIFactory.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* DO NOT EDIT. THIS FILE IS GENERATED FROM nsIFactory.idl
|
||||
*/
|
||||
|
||||
#ifndef __gen_nsIFactory_h__
|
||||
#define __gen_nsIFactory_h__
|
||||
|
||||
#include "nsISupports.h" /* interface nsISupports */
|
||||
#include "nsrootidl.h" /* interface nsrootidl */
|
||||
|
||||
#ifdef XPIDL_JS_STUBS
|
||||
#include "jsapi.h"
|
||||
#endif
|
||||
|
||||
/* starting interface: nsIFactory */
|
||||
|
||||
/* {00000001-0000-0000-c000-000000000046} */
|
||||
#define NS_IFACTORY_IID_STR "00000001-0000-0000-c000-000000000046"
|
||||
#define NS_IFACTORY_IID \
|
||||
{0x00000001, 0x0000, 0x0000, \
|
||||
{ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 }}
|
||||
|
||||
class nsIFactory : public nsISupports {
|
||||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFACTORY_IID)
|
||||
|
||||
/* voidStar CreateInstance (in nsISupports aOuter, in nsIIDRef iid); */
|
||||
NS_IMETHOD CreateInstance(nsISupports *aOuter, const nsIID & iid, void * *_retval) = 0;
|
||||
|
||||
/* void LockFactory (in PRBool lock); */
|
||||
NS_IMETHOD LockFactory(PRBool lock) = 0;
|
||||
|
||||
#ifdef XPIDL_JS_STUBS
|
||||
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);
|
||||
static NS_EXPORT_(JSObject *) GetJSObject(JSContext *cx, nsIFactory *priv);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* __gen_nsIFactory_h__ */
|
||||
29
mozilla/xpcom/components/nsIFactory.idl
Normal file
29
mozilla/xpcom/components/nsIFactory.idl
Normal file
@@ -0,0 +1,29 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[object, uuid(00000001-0000-0000-c000-000000000046)]
|
||||
interface nsIFactory : nsISupports {
|
||||
|
||||
voidStar CreateInstance(in nsISupports aOuter,
|
||||
in nsIIDRef iid);
|
||||
|
||||
void LockFactory(in PRBool lock);
|
||||
};
|
||||
|
||||
95
mozilla/xpcom/components/nsIGenericFactory.h
Normal file
95
mozilla/xpcom/components/nsIGenericFactory.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIGenericFactory_h___
|
||||
#define nsIGenericFactory_h___
|
||||
|
||||
#include "nsIFactory.h"
|
||||
|
||||
// {3bc97f01-ccdf-11d2-bab8-b548654461fc}
|
||||
#define NS_GENERICFACTORY_CID \
|
||||
{ 0x3bc97f01, 0xccdf, 0x11d2, { 0xba, 0xb8, 0xb5, 0x48, 0x65, 0x44, 0x61, 0xfc } }
|
||||
|
||||
// {3bc97f00-ccdf-11d2-bab8-b548654461fc}
|
||||
#define NS_IGENERICFACTORY_IID \
|
||||
{ 0x3bc97f00, 0xccdf, 0x11d2, { 0xba, 0xb8, 0xb5, 0x48, 0x65, 0x44, 0x61, 0xfc } }
|
||||
|
||||
#define NS_GENERICFACTORY_PROGID "component:/netscape/generic-factory"
|
||||
#define NS_GENERICFACTORY_CLASSNAME "Generic Factory"
|
||||
/**
|
||||
* Provides a Generic nsIFactory implementation that can be used by
|
||||
* DLLs with very simple factory needs.
|
||||
*/
|
||||
class nsIGenericFactory : public nsIFactory {
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IGENERICFACTORY_IID; return iid; }
|
||||
|
||||
typedef NS_CALLBACK(ConstructorProcPtr) (nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
typedef NS_CALLBACK(DestructorProcPtr) (void);
|
||||
|
||||
/**
|
||||
* Establishes the generic factory's constructor function, which will be called
|
||||
* by CreateInstance.
|
||||
*/
|
||||
NS_IMETHOD SetConstructor(ConstructorProcPtr constructor) = 0;
|
||||
|
||||
/**
|
||||
* Establishes the generic factory's destructor function, which will be called
|
||||
* whe the generic factory is deleted. This is used to notify the DLL that
|
||||
* an instance of one of its generic factories is going away.
|
||||
*/
|
||||
NS_IMETHOD SetDestructor(DestructorProcPtr destructor) = 0;
|
||||
};
|
||||
|
||||
extern NS_COM nsresult
|
||||
NS_NewGenericFactory(nsIGenericFactory* *result,
|
||||
nsIGenericFactory::ConstructorProcPtr constructor,
|
||||
nsIGenericFactory::DestructorProcPtr destructor = NULL);
|
||||
|
||||
#define NS_GENERIC_FACTORY_CONSTRUCTOR(_InstanceClass) \
|
||||
static nsresult \
|
||||
_InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) \
|
||||
{ \
|
||||
nsresult rv; \
|
||||
\
|
||||
_InstanceClass * inst; \
|
||||
\
|
||||
if (NULL == aResult) { \
|
||||
rv = NS_ERROR_NULL_POINTER; \
|
||||
goto done; \
|
||||
} \
|
||||
*aResult = NULL; \
|
||||
if (NULL != aOuter) { \
|
||||
rv = NS_ERROR_NO_AGGREGATION; \
|
||||
goto done; \
|
||||
} \
|
||||
\
|
||||
NS_NEWXPCOM(inst, _InstanceClass); \
|
||||
if (NULL == inst) { \
|
||||
rv = NS_ERROR_OUT_OF_MEMORY; \
|
||||
goto done; \
|
||||
} \
|
||||
NS_ADDREF(inst); \
|
||||
rv = inst->QueryInterface(aIID, aResult); \
|
||||
NS_RELEASE(inst); \
|
||||
\
|
||||
done: \
|
||||
return rv; \
|
||||
}
|
||||
|
||||
#endif /* nsIGenericFactory_h___ */
|
||||
363
mozilla/xpcom/components/nsIRegistry.h
Normal file
363
mozilla/xpcom/components/nsIRegistry.h
Normal file
@@ -0,0 +1,363 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#ifndef __nsIRegistry_h
|
||||
#define __nsIRegistry_h
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
// {5D41A440-8E37-11d2-8059-00600811A9C3}
|
||||
#define NS_IREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
|
||||
#define NS_REGISTRY_PROGID "component://netscape/registry"
|
||||
#define NS_REGISTRY_CLASSNAME "Mozilla Registry"
|
||||
|
||||
// {D1B54831-AC07-11d2-805E-00600811A9C3}
|
||||
#define NS_IREGISTRYNODE_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
|
||||
// {5316C380-B2F8-11d2-A374-0080C6F80E4B}
|
||||
#define NS_IREGISTRYVALUE_IID { 0x5316c380, 0xb2f8, 0x11d2, { 0xa3, 0x74, 0x0, 0x80, 0xc6, 0xf8, 0xe, 0x4b } }
|
||||
|
||||
/* be761f00-a3b0-11d2-996c-0080c7cb1081 */
|
||||
#define NS_REGISTRY_CID \
|
||||
{ 0xbe761f00, 0xa3b0, 0x11d2, \
|
||||
{0x99, 0x6c, 0x00, 0x80, 0xc7, 0xcb, 0x10, 0x81} }
|
||||
|
||||
|
||||
class nsIEnumerator;
|
||||
|
||||
/*-------------------------------- nsIRegistry ---------------------------------
|
||||
| This interface provides access to a tree of arbitrary values. |
|
||||
| |
|
||||
| Each node of the tree contains either a value or a subtree or both. |
|
||||
| |
|
||||
| The value at any of these leaf nodes can be any of these "primitive" types: |
|
||||
| o string (null terminated UTF string) |
|
||||
| o array of 32-bit integers |
|
||||
| o arbitrary array of bytes |
|
||||
| o file identifier |
|
||||
| Of course, since you can store an arbitrary array of bytes, you can put |
|
||||
| any data you like into a registry (although you have the burden of |
|
||||
| encoding/decoding your data in that case). |
|
||||
| |
|
||||
| Each branch of the tree is labelled with a string "key." The entire path |
|
||||
| from a given point of the tree to another point further down can be |
|
||||
| presented as a single string composed of each branch's label, concatenated |
|
||||
| to the next, with an intervening forward slash ('/'). The term "key" |
|
||||
| refers to both specific tree branch labels and to such concatenated paths. |
|
||||
| |
|
||||
| The branches from a given node must have unique labels. Distinct nodes can |
|
||||
| have branches with the same label. |
|
||||
| |
|
||||
| For example, here's a small registry tree: |
|
||||
| | |
|
||||
| /\ |
|
||||
| / \ |
|
||||
| / \ |
|
||||
| / \ |
|
||||
| "Classes" "Users" |
|
||||
| / \ |
|
||||
| / \ |
|
||||
| / ["joe"] |
|
||||
| / / \ |
|
||||
| | / \ |
|
||||
| /\ / \ |
|
||||
| / \ "joe" "bob" |
|
||||
| / \ / \ |
|
||||
| / \ |
|
||||
| "{xxxx-xx-1}" "{xxxx-xx-2}" ["c:/joe"] ["d:/Robert"] |
|
||||
| | | |
|
||||
| /\ /\ |
|
||||
| / \ / \ |
|
||||
| / \ / \ |
|
||||
| "Library" "Version" "Library" "Version" |
|
||||
| / \ / \ |
|
||||
| ["foo.dll"] 2 ["bar.dll"] 1 |
|
||||
| |
|
||||
| In this example, there are 2 keys under the root: "Classes" and "Users". |
|
||||
| The first denotes a subtree only (which has two subtrees, ...). The second |
|
||||
| denotes both a value ["joe"] and two subtrees labelled "joe" and "bob". |
|
||||
| The value at the node "/Users" is ["joe"], at "/Users/bob" is ["d:/Robert"]. |
|
||||
| The value at "/Classes/{xxxx-xx-1}/Version" is 2. |
|
||||
| |
|
||||
| The registry interface provides functions that let you navigate the tree |
|
||||
| and manipulate it's contents. |
|
||||
| |
|
||||
| Please note that the registry itself does not impose any structure or |
|
||||
| meaning on the contents of the tree. For example, the registry doesn't |
|
||||
| control whether the value at the key "/Users" is the label for the subtree |
|
||||
| with information about the last active user. That meaning is applied by |
|
||||
| the code that stores these values and uses them for that purpose. |
|
||||
| |
|
||||
| [Any resemblence between this example and actual contents of any actual |
|
||||
| registry is purely coincidental.] |
|
||||
------------------------------------------------------------------------------*/
|
||||
struct nsIRegistry : public nsISupports {
|
||||
/*------------------------------ Constants ---------------------------------
|
||||
| The following enumerated types and values are used by the registry |
|
||||
| interface. |
|
||||
--------------------------------------------------------------------------*/
|
||||
typedef enum {
|
||||
String = 1,
|
||||
Int32,
|
||||
Bytes,
|
||||
File
|
||||
} DataType;
|
||||
|
||||
/*-------------------------------- Types -----------------------------------
|
||||
| The following data types are used by this interface. All are basically |
|
||||
| opaque types. You obtain objects of these types via certain member |
|
||||
| function calls and re-use them later (without having to know what they |
|
||||
| contain). |
|
||||
| |
|
||||
| Key - Placeholder to represent a particular node in a registry |
|
||||
| tree. There are 3 enumerated values that correspond to |
|
||||
| specific nodes: |
|
||||
| Common - Where most stuff goes. |
|
||||
| Users - Special subtree to hold info about |
|
||||
| "users"; if you don't know what goes |
|
||||
| here, don't mess with it. |
|
||||
| CurrentUser - Subtree under Users corresponding to |
|
||||
| whatever user is designed the "current" |
|
||||
| one; see note above. |
|
||||
| You can specify any of these enumerated values as "keys" |
|
||||
| on any member function that takes a nsRegistry::Key. |
|
||||
| ValueInfo - Structure describing a registry value. |
|
||||
--------------------------------------------------------------------------*/
|
||||
typedef uint32 Key;
|
||||
|
||||
enum WellKnownKeys { Users = 1, Common = 2, CurrentUser = 3 };
|
||||
|
||||
enum WellKnownRegistry {
|
||||
ApplicationComponentRegistry = 1
|
||||
};
|
||||
|
||||
struct ValueInfo {
|
||||
DataType type;
|
||||
uint32 length;
|
||||
};
|
||||
|
||||
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IREGISTRY_IID; return iid; }
|
||||
|
||||
/*--------------------------- Opening/Closing ------------------------------
|
||||
| These functions open the specified registry file (Open() with a non-null |
|
||||
| argument) or the default "standard" registry file (Open() with a null |
|
||||
| argument or OpenDefault()). |
|
||||
| |
|
||||
| Once opened, you can access the registry contents via the read/write |
|
||||
| or query functions. |
|
||||
| |
|
||||
| The registry file will be closed automatically when the registry object |
|
||||
| is destroyed. You can close the file prior to that by using the |
|
||||
| Close() function. |
|
||||
--------------------------------------------------------------------------*/
|
||||
NS_IMETHOD Open( const char *regFile = 0 ) = 0;
|
||||
NS_IMETHOD OpenWellKnownRegistry( uint32 regid ) = 0;
|
||||
NS_IMETHOD OpenDefault() = 0;
|
||||
NS_IMETHOD Close() = 0;
|
||||
|
||||
/*----------------------- Reading/Writing Values ---------------------------
|
||||
| These functions read/write the registry values at a given node. |
|
||||
| |
|
||||
| All functions require you to specify where in the registry key to |
|
||||
| get/set the value. The location is specified using two components: |
|
||||
| o A "base key" indicating where to start from; this is a value of type |
|
||||
| nsIRegistry::Key. You use either one of the special "root" key |
|
||||
| values or a subkey obtained via some other member function call. |
|
||||
| o A "relative path," expressed as a sequence of subtree names |
|
||||
| separated by forward slashes. This path describes how to get from |
|
||||
| the base key to the node at which you want to store the data. This |
|
||||
| component can be a null pointer which means the value goes directly |
|
||||
| at the node denoted by the base key. |
|
||||
| |
|
||||
| When you request a value of a given type, the data stored at the |
|
||||
| specified node must be of the type requested. If not, an error results. |
|
||||
| |
|
||||
| GetString - Obtains a newly allocated copy of a string type value. The |
|
||||
| caller is obligated to free the returned string using |
|
||||
| PR_Free. |
|
||||
| SetString - Stores the argument string at the specified node. |
|
||||
| GetInt - Obtains an int32 value at the specified node. The result |
|
||||
| is returned into an int32 location you specify. |
|
||||
| SetInt - Stores a given int32 value at a node. |
|
||||
| GetBytes - Obtains a byte array value; this returns both an allocated |
|
||||
| array of bytes and a length (necessary because there may be |
|
||||
| embedded null bytes in the array). You must free the |
|
||||
| resulting array using PR_Free. |
|
||||
| SetBytes - Stores a given array of bytes; you specify the bytes via a |
|
||||
| pointer and a length. |
|
||||
| GetIntArray - Obtains the array of int32 values stored at a given node. |
|
||||
| The result is composed of two values: a pointer to an |
|
||||
| array of integer values (which must be freed using |
|
||||
| PR_Free) and the number of elements in that array. |
|
||||
| SetIntArray - Stores a set of int32 values at a given node. You must |
|
||||
| provide a pointer to the array and the number of entries. |
|
||||
--------------------------------------------------------------------------*/
|
||||
NS_IMETHOD GetString( Key baseKey, const char *path, char **result ) = 0;
|
||||
NS_IMETHOD SetString( Key baseKey, const char *path, const char *value ) = 0;
|
||||
NS_IMETHOD GetInt( Key baseKey, const char *path, int32 *result ) = 0;
|
||||
NS_IMETHOD SetInt( Key baseKey, const char *path, int32 value ) = 0;
|
||||
NS_IMETHOD GetBytes( Key baseKey, const char *path, void **result, uint32 *len ) = 0;
|
||||
NS_IMETHOD SetBytes( Key baseKey, const char *path, void *value, uint32 len ) = 0;
|
||||
NS_IMETHOD GetIntArray( Key baseKey, const char *path, int32 **result, uint32 *len ) = 0;
|
||||
NS_IMETHOD SetIntArray( Key baseKey, const char *path, const int32 *value, uint32 len ) = 0;
|
||||
|
||||
/*------------------------------ Navigation --------------------------------
|
||||
| These functions let you navigate through the registry tree, querying |
|
||||
| its contents. |
|
||||
| |
|
||||
| As above, all these functions requires a starting tree location ("base |
|
||||
| key") specified as a nsIRegistry::Key. Some also require a path |
|
||||
| name to locate the registry node location relative to this base key. |
|
||||
| |
|
||||
| AddSubtree - Adds a new registry subtree at the specified |
|
||||
| location. Returns the resulting key in |
|
||||
| the location specified by the third argument |
|
||||
| (unless that pointer is 0). |
|
||||
| AddSubtreeRaw - Adds a new registry subtree at the specified |
|
||||
| location. Returns the resulting key in |
|
||||
| the location specified by the third argument |
|
||||
| (unless that pointer is 0). |
|
||||
| Does not interpret special chars in key names. |
|
||||
| |
|
||||
| RemoveSubtree - Removes the specified registry subtree or |
|
||||
| value at the specified location. |
|
||||
| RemoveSubtreeRaw - Removes the specified registry subtree or |
|
||||
| value at the specified location. |
|
||||
| Does not interpret special chars in key names. |
|
||||
| |
|
||||
| GetSubtree - Returns a nsIRegistry::Key that can be used |
|
||||
| to refer to the specified registry location. |
|
||||
| GetSubtreeRaw - Returns a nsIRegistry::Key that can be used |
|
||||
| to refer to the specified registry location. |
|
||||
| Does not interpret special chars in key names. |
|
||||
| |
|
||||
| EnumerateSubtrees - Returns a nsIEnumerator object that you can |
|
||||
| use to enumerate all the subtrees descending |
|
||||
| from a specified location. You must free the |
|
||||
| enumerator via Release() when you're done with |
|
||||
| it. |
|
||||
| EnumerateAllSubtrees - Like EnumerateSubtrees, but will recursively |
|
||||
| enumerate lower-level subtrees, too. |
|
||||
| GetValueInfo - Returns a uint32 value that designates the type |
|
||||
| of data stored at this location in the registry; |
|
||||
| the possible values are defined by the enumerated |
|
||||
| type nsIRegistry::DataType. |
|
||||
| GetValueLength - Returns a uint32 value that indicates the length |
|
||||
| of this registry value; the length is the number |
|
||||
| of characters (for Strings), the number of bytes |
|
||||
| (for Bytes), or the number of int32 values (for |
|
||||
| Int32). |
|
||||
| EnumerateValues - Returns a nsIEnumerator that you can use to |
|
||||
| enumerate all the value nodes descending from |
|
||||
| a specified location. |
|
||||
--------------------------------------------------------------------------*/
|
||||
NS_IMETHOD AddSubtree( Key baseKey, const char *path, Key *result ) = 0;
|
||||
NS_IMETHOD RemoveSubtree( Key baseKey, const char *path ) = 0;
|
||||
NS_IMETHOD GetSubtree( Key baseKey, const char *path, Key *result ) = 0;
|
||||
|
||||
NS_IMETHOD AddSubtreeRaw( Key baseKey, const char *keyname, Key *result ) = 0;
|
||||
NS_IMETHOD RemoveSubtreeRaw( Key baseKey, const char *keyname ) = 0;
|
||||
NS_IMETHOD GetSubtreeRaw( Key baseKey, const char *keyname, Key *result ) = 0;
|
||||
|
||||
NS_IMETHOD EnumerateSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
|
||||
NS_IMETHOD EnumerateAllSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
|
||||
|
||||
NS_IMETHOD GetValueType( Key baseKey, const char *path, uint32 *result ) = 0;
|
||||
NS_IMETHOD GetValueLength( Key baseKey, const char *path, uint32 *result ) = 0;
|
||||
|
||||
NS_IMETHOD EnumerateValues( Key baseKey, nsIEnumerator **result ) = 0;
|
||||
|
||||
/*------------------------------ User Name ---------------------------------
|
||||
| These functions manipulate the current "user name." This value controls |
|
||||
| the behavior of certain registry functions (namely, ?). |
|
||||
| |
|
||||
| GetCurrentUserName allocates a copy of the current user name (which the |
|
||||
| caller should free using PR_Free). |
|
||||
--------------------------------------------------------------------------*/
|
||||
NS_IMETHOD GetCurrentUserName( char **result ) = 0;
|
||||
NS_IMETHOD SetCurrentUserName( const char *name ) = 0;
|
||||
|
||||
/*------------------------------ Utilities ---------------------------------
|
||||
| Various utility functions: |
|
||||
| |
|
||||
| Pack() is used to compress the contents of an open registry file. |
|
||||
--------------------------------------------------------------------------*/
|
||||
NS_IMETHOD Pack() = 0;
|
||||
|
||||
}; // nsIRegistry
|
||||
|
||||
/*------------------------------ nsIRegistryNode -------------------------------
|
||||
| This interface is implemented by all the objects obtained from the |
|
||||
| nsIEnumerators that nsIRegistry provides when you call either of the |
|
||||
| subtree enumeration functions EnumerateSubtrees or EnumerateAllSubtrees. |
|
||||
| |
|
||||
| You can call this function to get the name of this subtree. This is the |
|
||||
| relative path from the base key from which you got this interface. |
|
||||
| |
|
||||
| GetName - Returns the path name of this node; this is the relative path |
|
||||
| from the base key from which this subtree was obtained. The |
|
||||
| function allocates a copy of the name; the caller must free it |
|
||||
| using PR_Free. |
|
||||
------------------------------------------------------------------------------*/
|
||||
struct nsIRegistryNode : public nsISupports {
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IREGISTRYNODE_IID)
|
||||
NS_IMETHOD GetName( char **result ) = 0;
|
||||
NS_IMETHOD GetKey( nsIRegistry::Key *r_key ) = 0;
|
||||
}; // nsIRegistryNode
|
||||
|
||||
/*------------------------------ nsIRegistryValue ------------------------------
|
||||
| This interface is implemented by the objects obtained from the |
|
||||
| nsIEnumerators that nsIRegistry provides when you call the |
|
||||
| EnumerateValues function. An object supporting this interface is |
|
||||
| returned when you call the CurrentItem() function on that enumerator. |
|
||||
| |
|
||||
| You use the member functions of this interface to obtain information |
|
||||
| about each registry value. |
|
||||
| |
|
||||
| GetName - Returns the path name of this node; this is the relative |
|
||||
| path\ from the base key from which this value was obtained. |
|
||||
| The function allocates a copy of the name; the caller must |
|
||||
| subsequently free it via PR_Free. |
|
||||
| GetValueType - Returns (into a location provided by the caller) the type |
|
||||
| of the value; the types are defined by the enumerated |
|
||||
| type nsIRegistry::DataType. |
|
||||
| GetValueLength - Returns a uint32 value that indicates the length |
|
||||
| of this registry value; the length is the number |
|
||||
| of characters (for Strings), the number of bytes |
|
||||
| (for Bytes), or the number of int32 values (for |
|
||||
| Int32). |
|
||||
------------------------------------------------------------------------------*/
|
||||
struct nsIRegistryValue : public nsISupports {
|
||||
NS_IMETHOD GetName( char **result ) = 0;
|
||||
NS_IMETHOD GetValueType( uint32 *result ) = 0;
|
||||
NS_IMETHOD GetValueLength( uint32 *result ) = 0;
|
||||
}; // nsIRegistryEntry
|
||||
|
||||
|
||||
/*------------------------------- Error Codes ----------------------------------
|
||||
------------------------------------------------------------------------------*/
|
||||
#define NS_ERROR_REG_BADTYPE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 1 )
|
||||
#define NS_ERROR_REG_NO_MORE NS_ERROR_GENERATE_SUCCESS( NS_ERROR_MODULE_REG, 2 )
|
||||
#define NS_ERROR_REG_NOT_FOUND NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 3 )
|
||||
#define NS_ERROR_REG_NOFILE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 4 )
|
||||
#define NS_ERROR_REG_BUFFER_TOO_SMALL NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 5 )
|
||||
#define NS_ERROR_REG_NAME_TOO_LONG NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 6 )
|
||||
#define NS_ERROR_REG_NO_PATH NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 7 )
|
||||
#define NS_ERROR_REG_READ_ONLY NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 8 )
|
||||
#define NS_ERROR_REG_BAD_UTF8 NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 9 )
|
||||
|
||||
#endif
|
||||
343
mozilla/xpcom/components/nsIServiceManager.h
Normal file
343
mozilla/xpcom/components/nsIServiceManager.h
Normal file
@@ -0,0 +1,343 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIServiceManager_h___
|
||||
#define nsIServiceManager_h___
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsID.h"
|
||||
|
||||
class nsIShutdownListener;
|
||||
|
||||
#define NS_ISERVICEMANAGER_IID \
|
||||
{ /* cf0df3b0-3401-11d2-8163-006008119d7a */ \
|
||||
0xcf0df3b0, \
|
||||
0x3401, \
|
||||
0x11d2, \
|
||||
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
|
||||
/**
|
||||
* The nsIServiceManager manager interface provides a means to obtain
|
||||
* global services in an application. The service manager depends on the
|
||||
* repository to find and instantiate factories to obtain services.
|
||||
*
|
||||
* Users of the service manager must first obtain a pointer to the global
|
||||
* service manager by calling NS_GetGlobalServiceManager. After that,
|
||||
* they can request specific services by calling GetService. When they are
|
||||
* finished with a service the release it by calling ReleaseService (instead
|
||||
* of releasing the service object directly):
|
||||
*
|
||||
* nsICacheManager* cm;
|
||||
* nsServiceManager::GetService(kCacheManagerCID, kICacheManagerIID, (nsISupports**)&cm);
|
||||
*
|
||||
* ... use cm, and then sometime later ...
|
||||
*
|
||||
* nsServiceManager::ReleaseService(kCacheManagerCID, cm);
|
||||
*
|
||||
* A user of a service may keep references to particular services indefinitely
|
||||
* and only must call ReleaseService when it shuts down. However if the user
|
||||
* wishes to voluntarily cooperate with the shutdown of the service it is
|
||||
* using, it may supply an nsIShutdownListener to provide for asynchronous
|
||||
* release of the services it is using. The shutdown listener's OnShutdown
|
||||
* method will be called for a service that is being shut down, and it is
|
||||
* its responsiblity to release references obtained from that service if at
|
||||
* all possible.
|
||||
*
|
||||
* The process of shutting down a particular service is initiated by calling
|
||||
* the service manager's ShutdownService method. This will iterate through
|
||||
* all the registered shutdown listeners for the service being shut down, and
|
||||
* then will attempt to unload the library associated with the service if
|
||||
* possible. The status result of ShutdownService indicates whether the
|
||||
* service was successfully shut down, failed, or was not in service.
|
||||
*
|
||||
* XXX QUESTIONS:
|
||||
* - Should a "service" be more than nsISupports? Should it be a factory
|
||||
* and/or have Startup(), Shutdown(), etc.
|
||||
* - If the asynchronous OnShutdown operation gets called, does the user
|
||||
* of a service still need to call ReleaseService? (Or should they _not_
|
||||
* call it?)
|
||||
*/
|
||||
class nsIServiceManager : public nsISupports {
|
||||
public:
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISERVICEMANAGER_IID);
|
||||
|
||||
/**
|
||||
* RegisterService may be called explicitly to register a service
|
||||
* with the service manager. If a service is not registered explicitly,
|
||||
* the component manager will be used to create an instance according
|
||||
* to the class ID specified.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
RegisterService(const nsCID& aClass, nsISupports* aService) = 0;
|
||||
|
||||
/**
|
||||
* Requests a service to be shut down, possibly unloading its DLL.
|
||||
*
|
||||
* @returns NS_OK - if shutdown was successful and service was unloaded,
|
||||
* @returns NS_ERROR_SERVICE_NOT_FOUND - if shutdown failed because
|
||||
* the service was not currently loaded
|
||||
* @returns NS_ERROR_SERVICE_IN_USE - if shutdown failed because some
|
||||
* user of the service wouldn't voluntarily release it by using
|
||||
* a shutdown listener.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
UnregisterService(const nsCID& aClass) = 0;
|
||||
|
||||
NS_IMETHOD
|
||||
GetService(const nsCID& aClass, const nsIID& aIID,
|
||||
nsISupports* *result,
|
||||
nsIShutdownListener* shutdownListener = nsnull) = 0;
|
||||
|
||||
NS_IMETHOD
|
||||
ReleaseService(const nsCID& aClass, nsISupports* service,
|
||||
nsIShutdownListener* shutdownListener = nsnull) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// let's do it again, this time with ProgIDs...
|
||||
|
||||
NS_IMETHOD
|
||||
RegisterService(const char* aProgID, nsISupports* aService) = 0;
|
||||
|
||||
NS_IMETHOD
|
||||
UnregisterService(const char* aProgID) = 0;
|
||||
|
||||
NS_IMETHOD
|
||||
GetService(const char* aProgID, const nsIID& aIID,
|
||||
nsISupports* *result,
|
||||
nsIShutdownListener* shutdownListener = nsnull) = 0;
|
||||
|
||||
NS_IMETHOD
|
||||
ReleaseService(const char* aProgID, nsISupports* service,
|
||||
nsIShutdownListener* shutdownListener = nsnull) = 0;
|
||||
|
||||
};
|
||||
|
||||
#define NS_ERROR_SERVICE_NOT_FOUND NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCOM, 22)
|
||||
#define NS_ERROR_SERVICE_IN_USE NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCOM, 23)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define NS_ISHUTDOWNLISTENER_IID \
|
||||
{ /* 56decae0-3406-11d2-8163-006008119d7a */ \
|
||||
0x56decae0, \
|
||||
0x3406, \
|
||||
0x11d2, \
|
||||
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
|
||||
class nsIShutdownListener : public nsISupports {
|
||||
public:
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISHUTDOWNLISTENER_IID);
|
||||
|
||||
NS_IMETHOD
|
||||
OnShutdown(const nsCID& aClass, nsISupports* service) = 0;
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Interface to Global Services
|
||||
|
||||
class NS_COM nsServiceManager {
|
||||
public:
|
||||
|
||||
static nsresult
|
||||
RegisterService(const nsCID& aClass, nsISupports* aService);
|
||||
|
||||
static nsresult
|
||||
UnregisterService(const nsCID& aClass);
|
||||
|
||||
static nsresult
|
||||
GetService(const nsCID& aClass, const nsIID& aIID,
|
||||
nsISupports* *result,
|
||||
nsIShutdownListener* shutdownListener = nsnull);
|
||||
|
||||
static nsresult
|
||||
ReleaseService(const nsCID& aClass, nsISupports* service,
|
||||
nsIShutdownListener* shutdownListener = nsnull);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// let's do it again, this time with ProgIDs...
|
||||
|
||||
static nsresult
|
||||
RegisterService(const char* aProgID, nsISupports* aService);
|
||||
|
||||
static nsresult
|
||||
UnregisterService(const char* aProgID);
|
||||
|
||||
static nsresult
|
||||
GetService(const char* aProgID, const nsIID& aIID,
|
||||
nsISupports* *result,
|
||||
nsIShutdownListener* shutdownListener = nsnull);
|
||||
|
||||
static nsresult
|
||||
ReleaseService(const char* aProgID, nsISupports* service,
|
||||
nsIShutdownListener* shutdownListener = nsnull);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static nsresult GetGlobalServiceManager(nsIServiceManager* *result);
|
||||
|
||||
// This method can be called when shutting down the application. It
|
||||
// releases all the global services, and deletes the global service manager.
|
||||
static nsresult ShutdownGlobalServiceManager(nsIServiceManager* *result);
|
||||
|
||||
static nsIServiceManager* mGlobalServiceManager;
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NS_WITH_SERVICE: macro to make using services easier.
|
||||
// Now you can replace this:
|
||||
// {
|
||||
// nsIMyService* service;
|
||||
// rv = nsServiceManager::GetService(kMyServiceCID, nsIMyService::GetIID(),
|
||||
// &service);
|
||||
// if (NS_FAILED(rv)) return rv;
|
||||
// service->Doit(...); // use my service
|
||||
// rv = nsServiceManager::ReleaseService(kMyServiceCID, service);
|
||||
// }
|
||||
// with this:
|
||||
// {
|
||||
// NS_WITH_SERVICE(nsIMyService, service, kMyServiceCID, &rv);
|
||||
// if (NS_FAILED(rv)) return rv;
|
||||
// service->Doit(...); // use my service
|
||||
// }
|
||||
// and the automatic destructor will take care of releasing the service.
|
||||
//
|
||||
// Note that this macro requires you to link with the xpcom DLL to pick up the
|
||||
// static member functions from nsServiceManager. For situations where you're
|
||||
// passed an nsISupports that is an nsIComponentManager (such as in a DLL's
|
||||
// NSRegisterSelf or NSUnregisterSelf entry points) you can use the following
|
||||
// macro instead:
|
||||
//
|
||||
// NSRegisterSelf(nsISupports* servMgr, const char* path) {
|
||||
// NS_WITH_SERVICE1(nsIComponentManager, compMgr, servMgr,
|
||||
// kComponentManagerCID, &rv);
|
||||
// if (NS_FAILED(rv)) return rv;
|
||||
// compMgr->RegisterComponent(...); // use the service
|
||||
// }
|
||||
//
|
||||
// Note that both NS_WITH_SERVICE and NS_WITH_SERVICE1 can be used with a
|
||||
// "progid" as well as a "clsid"; for example,
|
||||
//
|
||||
// nsresult rv;
|
||||
// NS_WITH_SERVICE(nsIObserverService,
|
||||
// observer,
|
||||
// "component://netscape/observer-service", /* or NS_OBSERVERSERVICE_PROGID */
|
||||
// &rv);
|
||||
//
|
||||
|
||||
|
||||
#define NS_WITH_SERVICE(T, var, cid, rvAddr) \
|
||||
nsService _serv##var(cid, T::GetIID(), rvAddr); \
|
||||
T* var = (T*)(nsISupports*)_serv##var;
|
||||
|
||||
#define NS_WITH_SERVICE1(T, var, isupports, cid, rvAddr) \
|
||||
nsService _serv##var(isupports, cid, T::GetIID(), rvAddr); \
|
||||
T* var = (T*)(nsISupports*)_serv##var;
|
||||
|
||||
class nsService {
|
||||
protected:
|
||||
nsCID mCID;
|
||||
nsISupports* mService;
|
||||
|
||||
public:
|
||||
nsService(nsISupports* aServMgr, const nsCID& aClass, const nsIID& aIID, nsresult *rv)
|
||||
: mCID(aClass), mService(0)
|
||||
{
|
||||
nsIServiceManager* servMgr;
|
||||
*rv = aServMgr->QueryInterface(nsIServiceManager::GetIID(), (void**)&servMgr);
|
||||
if (NS_SUCCEEDED(*rv)) {
|
||||
*rv = servMgr->GetService(mCID, aIID, &mService);
|
||||
NS_RELEASE(servMgr);
|
||||
}
|
||||
}
|
||||
|
||||
nsService(nsISupports* aServMgr, const char* aProgID, const nsIID& aIID, nsresult *rv)
|
||||
: mService(0)
|
||||
{
|
||||
*rv = nsComponentManager::ProgIDToCLSID(aProgID, &mCID);
|
||||
if (NS_FAILED(*rv)) return;
|
||||
|
||||
nsIServiceManager* servMgr;
|
||||
*rv = aServMgr->QueryInterface(nsIServiceManager::GetIID(), (void**)&servMgr);
|
||||
if (NS_SUCCEEDED(*rv)) {
|
||||
*rv = servMgr->GetService(mCID, aIID, &mService);
|
||||
NS_RELEASE(servMgr);
|
||||
}
|
||||
}
|
||||
|
||||
nsService(const nsCID& aClass, const nsIID& aIID, nsresult *rv)
|
||||
: mCID(aClass), mService(0) {
|
||||
*rv = nsServiceManager::GetService(aClass, aIID,
|
||||
(nsISupports**)&mService);
|
||||
}
|
||||
|
||||
nsService(const char* aProgID, const nsIID& aIID, nsresult *rv)
|
||||
: mService(0)
|
||||
{
|
||||
*rv = nsComponentManager::ProgIDToCLSID(aProgID, &mCID);
|
||||
if (NS_FAILED(*rv)) return;
|
||||
|
||||
*rv = nsServiceManager::GetService(mCID, aIID,
|
||||
(nsISupports**)&mService);
|
||||
}
|
||||
|
||||
~nsService() {
|
||||
if (mService) { // mService could be null if the constructor fails
|
||||
nsresult rv = NS_OK;
|
||||
rv = nsServiceManager::ReleaseService(mCID, mService);
|
||||
}
|
||||
}
|
||||
|
||||
nsISupports* operator->() const {
|
||||
NS_PRECONDITION(mService != 0, "Your code should test the error result from the constructor.");
|
||||
return mService;
|
||||
}
|
||||
|
||||
PRBool operator==(const nsISupports* other) {
|
||||
return mService == other;
|
||||
}
|
||||
|
||||
operator nsISupports*() const {
|
||||
return mService;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NS_NewServiceManager: For when you want to create a service manager
|
||||
// in a given context.
|
||||
|
||||
extern NS_COM nsresult
|
||||
NS_NewServiceManager(nsIServiceManager* *result);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Initialization of XPCOM. Creates the global ComponentManager, ServiceManager
|
||||
// and registers xpcom components with the ComponentManager. Should be called
|
||||
// before any call can be made to XPCOM. Currently we are coping with this
|
||||
// not being called and internally initializing XPCOM if not already.
|
||||
extern NS_COM nsresult
|
||||
NS_InitXPCOM(nsIServiceManager* *result);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif /* nsIServiceManager_h___ */
|
||||
@@ -16,23 +16,16 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsInstallFileOpEnums_h__
|
||||
#define nsInstallFileOpEnums_h__
|
||||
#ifndef __nsIServerProvider_h
|
||||
#define __nsIServerProvider_h
|
||||
#include "nsISupports.h"
|
||||
|
||||
typedef enum nsInstallFileOpEnums {
|
||||
NS_FOP_DIR_CREATE = 0,
|
||||
NS_FOP_DIR_REMOVE = 1,
|
||||
NS_FOP_DIR_RENAME = 2,
|
||||
NS_FOP_FILE_COPY = 3,
|
||||
NS_FOP_FILE_DELETE = 4,
|
||||
NS_FOP_FILE_EXECUTE = 5,
|
||||
NS_FOP_FILE_MOVE = 6,
|
||||
NS_FOP_FILE_RENAME = 7,
|
||||
NS_FOP_WIN_SHORTCUT_CREATE = 8,
|
||||
NS_FOP_MAC_ALIAS_CREATE = 9,
|
||||
NS_FOP_UNIX_LINK_CREATE = 10,
|
||||
NS_FOP_FILE_SET_STAT = 11
|
||||
typedef nsID nsSID;
|
||||
#define NSSIDREF const nsSID&
|
||||
|
||||
} nsInstallFileOpEnums;
|
||||
class nsIServiceProvider: public nsISupports {
|
||||
public:
|
||||
NS_IMETHOD QueryService(NSSIDREF aSID, NSIIDREF sIID, (void **) pService);
|
||||
};
|
||||
|
||||
#endif /* nsInstallFileOpEnums_h__ */
|
||||
#endif /* __nsIServerProvider_h */
|
||||
164
mozilla/xpcom/components/nsMacRepository.h
Normal file
164
mozilla/xpcom/components/nsMacRepository.h
Normal file
@@ -0,0 +1,164 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#ifdef XP_MAC
|
||||
#ifdef MOZ_NGLAYOUT
|
||||
|
||||
#error "nsMacRepository.h became obsolete when the shared lib conversion was completed."
|
||||
|
||||
// The Mac NGLayout is not based on shared libraries yet.
|
||||
// All the DLLs are built as static libraries and we present them as
|
||||
// shared libraries by redefining PR_LoadLibrary(), PR_UnloadLibrary()
|
||||
// and PR_FindSymbol() below.
|
||||
//
|
||||
// If you add or remove shared libraries on other platforms, you must
|
||||
// - Add the library name to the defines below.
|
||||
// - Rename the "NSGetFactory" and "NSCanUnload" procs for the Mac:
|
||||
// just append the library name to the function name.
|
||||
// - Add the library and its procs to the static list below.
|
||||
|
||||
|
||||
typedef struct MacLibrary
|
||||
{
|
||||
char * name;
|
||||
nsFactoryProc factoryProc;
|
||||
nsCanUnloadProc unloadProc;
|
||||
} MacLibrary;
|
||||
|
||||
// library names
|
||||
#define WIDGET_DLL "WIDGET_DLL"
|
||||
#define GFXWIN_DLL "GFXWIN_DLL"
|
||||
#define VIEW_DLL "VIEW_DLL"
|
||||
#define WEB_DLL "WEB_DLL"
|
||||
#define PLUGIN_DLL "PLUGIN_DLL"
|
||||
#define PREF_DLL "PREF_DLL"
|
||||
#define PARSER_DLL "PARSER_DLL"
|
||||
#define DOM_DLL "DOM_DLL"
|
||||
#define LAYOUT_DLL "LAYOUT_DLL"
|
||||
#define NETLIB_DLL "NETLIB_DLL"
|
||||
#define EDITOR_DLL "EDITOR_DLL"
|
||||
|
||||
#ifdef IMPL_MAC_REPOSITORY
|
||||
|
||||
extern "C" nsresult NSGetFactory_WIDGET_DLL(nsISupports* serviceMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory);
|
||||
extern "C" nsresult NSGetFactory_GFXWIN_DLL(nsISupports* serviceMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory);
|
||||
extern "C" nsresult NSGetFactory_VIEW_DLL(nsISupports* serviceMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory);
|
||||
extern "C" nsresult NSGetFactory_WEB_DLL(nsISupports* serviceMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory);
|
||||
#if 0
|
||||
extern "C" nsresult NSGetFactory_PLUGIN_DLL(nsISupports* serviceMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory);
|
||||
#endif
|
||||
extern "C" nsresult NSGetFactory_PREF_DLL(nsISupports* serviceMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory);
|
||||
extern "C" nsresult NSGetFactory_PARSER_DLL(nsISupports* serviceMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory);
|
||||
extern "C" nsresult NSGetFactory_DOM_DLL(nsISupports* serviceMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory);
|
||||
extern "C" nsresult NSGetFactory_LAYOUT_DLL(nsISupports* serviceMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory);
|
||||
extern "C" nsresult NSGetFactory_NETLIB_DLL(nsISupports* serviceMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory);
|
||||
extern "C" nsresult NSGetFactory_EDITOR_DLL(nsISupports* serviceMgr,
|
||||
const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory **aFactory);
|
||||
|
||||
extern "C" PRBool NSCanUnload_PREF_DLL(void);
|
||||
|
||||
// library list
|
||||
static MacLibrary libraries[] = {
|
||||
#if 0
|
||||
WIDGET_DLL, NSGetFactory_WIDGET_DLL, NULL,
|
||||
GFXWIN_DLL, NSGetFactory_GFXWIN_DLL, NULL,
|
||||
VIEW_DLL, NSGetFactory_VIEW_DLL, NULL,
|
||||
WEB_DLL, NSGetFactory_WEB_DLL, NULL,
|
||||
//PLUGIN_DLL, NSGetFactory_PLUGIN_DLL, NULL,
|
||||
PREF_DLL, NSGetFactory_PREF_DLL, NSCanUnload_PREF_DLL,
|
||||
PARSER_DLL, NSGetFactory_PARSER_DLL, NULL,
|
||||
DOM_DLL, NSGetFactory_DOM_DLL, NULL,
|
||||
LAYOUT_DLL, NSGetFactory_LAYOUT_DLL, NULL,
|
||||
NETLIB_DLL, NSGetFactory_NETLIB_DLL, NULL,
|
||||
//EDITOR_DLL, NSGetFactory_EDITOR_DLL, NULL, // FIX ME
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
static void* FindMacSymbol(char* libName, const char *symbolName)
|
||||
{
|
||||
MacLibrary * macLib;
|
||||
|
||||
for (macLib = libraries; ; macLib ++)
|
||||
{
|
||||
if (macLib->name == NULL)
|
||||
return NULL;
|
||||
|
||||
if (PL_strcmp(macLib->name, libName) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (PL_strcmp(symbolName, "NSGetFactory") == 0) {
|
||||
return macLib->factoryProc;
|
||||
}
|
||||
else if (PL_strcmp(symbolName, "NSCanUnload") == 0) {
|
||||
return macLib->unloadProc;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define PR_LoadLibrary(libName) (PRLibrary *)libName
|
||||
#define PR_UnloadLibrary(lib) lib = NULL
|
||||
#define PR_FindSymbol(lib, symbolName) FindMacSymbol((char*)lib, symbolName)
|
||||
|
||||
#endif // IMPL_MAC_REPOSITORY
|
||||
|
||||
#endif // MOZ_NGLAYOUT
|
||||
#endif // XP_MAC
|
||||
1443
mozilla/xpcom/components/nsRegistry.cpp
Normal file
1443
mozilla/xpcom/components/nsRegistry.cpp
Normal file
File diff suppressed because it is too large
Load Diff
188
mozilla/xpcom/components/nsRepository.cpp
Normal file
188
mozilla/xpcom/components/nsRepository.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
nsresult
|
||||
nsComponentManager::Initialize(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::FindFactory(const nsCID &aClass,
|
||||
nsIFactory **aFactory)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->FindFactory(aClass, aFactory);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::ProgIDToCLSID(const char *aProgID,
|
||||
nsCID *aClass)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->ProgIDToCLSID(aProgID, aClass);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::CLSIDToProgID(nsCID *aClass,
|
||||
char* *aClassName,
|
||||
char* *aProgID)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->CLSIDToProgID(aClass, aClassName, aProgID);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::CreateInstance(const nsCID &aClass,
|
||||
nsISupports *aDelegate,
|
||||
const nsIID &aIID,
|
||||
void **aResult)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->CreateInstance(aClass, aDelegate, aIID, aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::CreateInstance(const char *aProgID,
|
||||
nsISupports *aDelegate,
|
||||
const nsIID &aIID,
|
||||
void **aResult)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->CreateInstance(aProgID, aDelegate, aIID, aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::RegisterFactory(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFactory *aFactory,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->RegisterFactory(aClass, aClassName, aProgID,
|
||||
aFactory, aReplace);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::RegisterComponent(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
const char *aLibraryPersistentDescriptor,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->RegisterComponent(aClass, aClassName, aProgID,
|
||||
aLibraryPersistentDescriptor, aReplace, aPersist);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::RegisterComponentSpec(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
nsIFileSpec *aLibrary,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->RegisterComponentSpec(aClass, aClassName, aProgID,
|
||||
aLibrary, aReplace, aPersist);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::RegisterComponentLib(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aProgID,
|
||||
const char *adllName,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->RegisterComponentLib(aClass, aClassName, aProgID,
|
||||
adllName, aReplace, aPersist);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::UnregisterFactory(const nsCID &aClass,
|
||||
nsIFactory *aFactory)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->UnregisterFactory(aClass, aFactory);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::UnregisterComponent(const nsCID &aClass,
|
||||
const char *aLibrary)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->UnregisterComponent(aClass, aLibrary);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::FreeLibraries(void)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->FreeLibraries();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::AutoRegister(nsIComponentManager::RegistrationTime when,
|
||||
nsIFileSpec *directory)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->AutoRegister(when, directory);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManager::AutoRegisterComponent(nsIComponentManager::RegistrationTime when,
|
||||
nsIFileSpec *fullname)
|
||||
{
|
||||
nsIComponentManager* cm;
|
||||
nsresult rv = NS_GetGlobalComponentManager(&cm);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return cm->AutoRegisterComponent(when, fullname);
|
||||
}
|
||||
28
mozilla/xpcom/components/nsRepository.h
Normal file
28
mozilla/xpcom/components/nsRepository.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef __nsRespository_h
|
||||
#define __nsRespository_h
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
// XXX nsRepository is obsolete! Use nsComponentManager now!
|
||||
|
||||
#define nsRepository nsComponentManager
|
||||
|
||||
#endif
|
||||
518
mozilla/xpcom/components/nsServiceManager.cpp
Normal file
518
mozilla/xpcom/components/nsServiceManager.cpp
Normal file
@@ -0,0 +1,518 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsVector.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "prcmon.h"
|
||||
#include "prthread.h" /* XXX: only used for the NSPR initialization hack (rick) */
|
||||
|
||||
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
|
||||
|
||||
class nsServiceEntry {
|
||||
public:
|
||||
|
||||
nsServiceEntry(const nsCID& cid, nsISupports* service);
|
||||
~nsServiceEntry();
|
||||
|
||||
nsresult AddListener(nsIShutdownListener* listener);
|
||||
nsresult RemoveListener(nsIShutdownListener* listener);
|
||||
nsresult NotifyListeners(void);
|
||||
|
||||
const nsCID& mClassID;
|
||||
nsISupports* mService;
|
||||
nsVector* mListeners; // nsVector<nsIShutdownListener>
|
||||
PRBool mShuttingDown;
|
||||
|
||||
};
|
||||
|
||||
nsServiceEntry::nsServiceEntry(const nsCID& cid, nsISupports* service)
|
||||
: mClassID(cid), mService(service), mListeners(NULL), mShuttingDown(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
nsServiceEntry::~nsServiceEntry()
|
||||
{
|
||||
if (mListeners) {
|
||||
NS_ASSERTION(mListeners->GetSize() == 0, "listeners not removed or notified");
|
||||
#if 0
|
||||
PRUint32 size = mListeners->GetSize();
|
||||
for (PRUint32 i = 0; i < size; i++) {
|
||||
nsIShutdownListener* listener = (nsIShutdownListener*)(*mListeners)[i];
|
||||
NS_RELEASE(listener);
|
||||
}
|
||||
#endif
|
||||
delete mListeners;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsServiceEntry::AddListener(nsIShutdownListener* listener)
|
||||
{
|
||||
if (listener == NULL)
|
||||
return NS_OK;
|
||||
if (mListeners == NULL) {
|
||||
mListeners = new nsVector();
|
||||
if (mListeners == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
PRInt32 rv = mListeners->Add(listener);
|
||||
NS_ADDREF(listener);
|
||||
return rv == -1 ? NS_ERROR_FAILURE : NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsServiceEntry::RemoveListener(nsIShutdownListener* listener)
|
||||
{
|
||||
if (listener == NULL)
|
||||
return NS_OK;
|
||||
NS_ASSERTION(mListeners, "no listeners added yet");
|
||||
PRUint32 size = mListeners->GetSize();
|
||||
for (PRUint32 i = 0; i < size; i++) {
|
||||
if ((*mListeners)[i] == listener) {
|
||||
mListeners->Remove(i);
|
||||
NS_RELEASE(listener);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(0, "unregistered shutdown listener");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsServiceEntry::NotifyListeners(void)
|
||||
{
|
||||
if (mListeners) {
|
||||
PRUint32 size = mListeners->GetSize();
|
||||
for (PRUint32 i = 0; i < size; i++) {
|
||||
nsIShutdownListener* listener = (nsIShutdownListener*)(*mListeners)[0];
|
||||
nsresult rv = listener->OnShutdown(mClassID, mService);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_RELEASE(listener);
|
||||
mListeners->Remove(0);
|
||||
}
|
||||
NS_ASSERTION(mListeners->GetSize() == 0, "failed to notify all listeners");
|
||||
delete mListeners;
|
||||
mListeners = NULL;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsServiceManagerImpl : public nsIServiceManager {
|
||||
public:
|
||||
|
||||
NS_IMETHOD
|
||||
RegisterService(const nsCID& aClass, nsISupports* aService);
|
||||
|
||||
NS_IMETHOD
|
||||
UnregisterService(const nsCID& aClass);
|
||||
|
||||
NS_IMETHOD
|
||||
GetService(const nsCID& aClass, const nsIID& aIID,
|
||||
nsISupports* *result,
|
||||
nsIShutdownListener* shutdownListener = NULL);
|
||||
|
||||
NS_IMETHOD
|
||||
ReleaseService(const nsCID& aClass, nsISupports* service,
|
||||
nsIShutdownListener* shutdownListener = NULL);
|
||||
|
||||
NS_IMETHOD
|
||||
RegisterService(const char* aProgID, nsISupports* aService);
|
||||
|
||||
NS_IMETHOD
|
||||
UnregisterService(const char* aProgID);
|
||||
|
||||
NS_IMETHOD
|
||||
GetService(const char* aProgID, const nsIID& aIID,
|
||||
nsISupports* *result,
|
||||
nsIShutdownListener* shutdownListener = NULL);
|
||||
|
||||
NS_IMETHOD
|
||||
ReleaseService(const char* aProgID, nsISupports* service,
|
||||
nsIShutdownListener* shutdownListener = NULL);
|
||||
|
||||
nsServiceManagerImpl(void);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~nsServiceManagerImpl(void);
|
||||
|
||||
nsHashtable/*<nsServiceEntry>*/* mServices;
|
||||
};
|
||||
|
||||
nsServiceManagerImpl::nsServiceManagerImpl(void)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mServices = new nsHashtable(256, PR_TRUE); // Get a threadSafe hashtable
|
||||
NS_ASSERTION(mServices, "out of memory already?");
|
||||
}
|
||||
|
||||
static PRBool
|
||||
DeleteEntry(nsHashKey *aKey, void *aData, void* closure)
|
||||
{
|
||||
nsServiceEntry* entry = (nsServiceEntry*)aData;
|
||||
NS_RELEASE(entry->mService);
|
||||
delete entry;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsServiceManagerImpl::~nsServiceManagerImpl(void)
|
||||
{
|
||||
if (mServices) {
|
||||
mServices->Enumerate(DeleteEntry);
|
||||
delete mServices;
|
||||
}
|
||||
}
|
||||
|
||||
static NS_DEFINE_IID(kIServiceManagerIID, NS_ISERVICEMANAGER_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
||||
NS_IMPL_ADDREF(nsServiceManagerImpl);
|
||||
NS_IMPL_RELEASE(nsServiceManagerImpl);
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsServiceManagerImpl::QueryInterface(const nsIID& aIID, void* *aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
*aInstancePtr = NULL;
|
||||
if (aIID.Equals(kIServiceManagerIID) ||
|
||||
aIID.Equals(kISupportsIID)) {
|
||||
*aInstancePtr = (void*) this;
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsServiceManagerImpl::GetService(const nsCID& aClass, const nsIID& aIID,
|
||||
nsISupports* *result,
|
||||
nsIShutdownListener* shutdownListener)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
/* XXX: This is a hack to force NSPR initialization.. This should be
|
||||
* removed once PR_CEnterMonitor(...) initializes NSPR... (rick)
|
||||
*/
|
||||
(void)PR_GetCurrentThread();
|
||||
PR_CEnterMonitor(this);
|
||||
|
||||
nsIDKey key(aClass);
|
||||
nsServiceEntry* entry = (nsServiceEntry*)mServices->Get(&key);
|
||||
|
||||
if (entry) {
|
||||
nsISupports* service;
|
||||
rv = entry->mService->QueryInterface(aIID, (void**)&service);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = entry->AddListener(shutdownListener);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*result = service;
|
||||
|
||||
// If someone else requested the service to be shut down,
|
||||
// and we just asked to get it again before it could be
|
||||
// released, then cancel their shutdown request:
|
||||
if (entry->mShuttingDown) {
|
||||
entry->mShuttingDown = PR_FALSE;
|
||||
NS_ADDREF(service); // Released in UnregisterService
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
nsISupports* service;
|
||||
rv = nsComponentManager::CreateInstance(aClass, NULL, aIID, (void**)&service);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
entry = new nsServiceEntry(aClass, service);
|
||||
if (entry == NULL) {
|
||||
NS_RELEASE(service);
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
else {
|
||||
rv = entry->AddListener(shutdownListener);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mServices->Put(&key, entry);
|
||||
*result = service;
|
||||
NS_ADDREF(service); // Released in UnregisterService
|
||||
}
|
||||
else {
|
||||
NS_RELEASE(service);
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PR_CExitMonitor(this);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsServiceManagerImpl::ReleaseService(const nsCID& aClass, nsISupports* service,
|
||||
nsIShutdownListener* shutdownListener)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
PR_CEnterMonitor(this);
|
||||
|
||||
nsIDKey key(aClass);
|
||||
nsServiceEntry* entry = (nsServiceEntry*)mServices->Get(&key);
|
||||
|
||||
NS_ASSERTION(entry, "service not found");
|
||||
// NS_ASSERTION(entry->mService == service, "service looked failed");
|
||||
|
||||
if (entry) {
|
||||
rv = entry->RemoveListener(shutdownListener);
|
||||
nsrefcnt cnt;
|
||||
NS_RELEASE2(service, cnt);
|
||||
if (NS_SUCCEEDED(rv) && cnt == 0) {
|
||||
mServices->Remove(&key);
|
||||
delete entry;
|
||||
rv = nsComponentManager::FreeLibraries();
|
||||
}
|
||||
}
|
||||
|
||||
PR_CExitMonitor(this);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsServiceManagerImpl::RegisterService(const nsCID& aClass, nsISupports* aService)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
PR_CEnterMonitor(this);
|
||||
|
||||
nsIDKey key(aClass);
|
||||
nsServiceEntry* entry = (nsServiceEntry*)mServices->Get(&key);
|
||||
if (entry) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
else {
|
||||
entry = new nsServiceEntry(aClass, aService);
|
||||
if (entry == NULL)
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
else {
|
||||
mServices->Put(&key, entry);
|
||||
NS_ADDREF(aService); // Released in UnregisterService
|
||||
}
|
||||
}
|
||||
PR_CExitMonitor(this);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsServiceManagerImpl::UnregisterService(const nsCID& aClass)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
PR_CEnterMonitor(this);
|
||||
|
||||
nsIDKey key(aClass);
|
||||
nsServiceEntry* entry = (nsServiceEntry*)mServices->Get(&key);
|
||||
|
||||
if (entry == NULL) {
|
||||
rv = NS_ERROR_SERVICE_NOT_FOUND;
|
||||
}
|
||||
else {
|
||||
rv = entry->NotifyListeners(); // break the cycles
|
||||
entry->mShuttingDown = PR_TRUE;
|
||||
nsrefcnt cnt;
|
||||
NS_RELEASE2(entry->mService, cnt); // AddRef in GetService
|
||||
if (NS_SUCCEEDED(rv) && cnt == 0) {
|
||||
mServices->Remove(&key);
|
||||
delete entry;
|
||||
rv = nsComponentManager::FreeLibraries();
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_SERVICE_IN_USE;
|
||||
}
|
||||
|
||||
PR_CExitMonitor(this);
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// let's do it again, this time with ProgIDs...
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsServiceManagerImpl::RegisterService(const char* aProgID, nsISupports* aService)
|
||||
{
|
||||
nsCID aClass;
|
||||
nsresult rv;
|
||||
rv = nsComponentManager::ProgIDToCLSID(aProgID, &aClass);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return RegisterService(aClass, aService);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsServiceManagerImpl::UnregisterService(const char* aProgID)
|
||||
{
|
||||
nsCID aClass;
|
||||
nsresult rv;
|
||||
rv = nsComponentManager::ProgIDToCLSID(aProgID, &aClass);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return UnregisterService(aClass);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsServiceManagerImpl::GetService(const char* aProgID, const nsIID& aIID,
|
||||
nsISupports* *result,
|
||||
nsIShutdownListener* shutdownListener)
|
||||
{
|
||||
nsCID aClass;
|
||||
nsresult rv;
|
||||
rv = nsComponentManager::ProgIDToCLSID(aProgID, &aClass);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return GetService(aClass, aIID, result, shutdownListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsServiceManagerImpl::ReleaseService(const char* aProgID, nsISupports* service,
|
||||
nsIShutdownListener* shutdownListener)
|
||||
{
|
||||
nsCID aClass;
|
||||
nsresult rv;
|
||||
rv = nsComponentManager::ProgIDToCLSID(aProgID, &aClass);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return ReleaseService(aClass, service, shutdownListener);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewServiceManager(nsIServiceManager* *result)
|
||||
{
|
||||
nsServiceManagerImpl* servMgr = new nsServiceManagerImpl();
|
||||
if (servMgr == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(servMgr);
|
||||
*result = servMgr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Global service manager interface (see nsIServiceManager.h)
|
||||
|
||||
nsresult
|
||||
nsServiceManager::GetGlobalServiceManager(nsIServiceManager* *result)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (mGlobalServiceManager == NULL) {
|
||||
// XPCOM not initialized yet. Let us do initialization of our module.
|
||||
rv = NS_InitXPCOM(NULL);
|
||||
}
|
||||
// No ADDREF as we are advicing no release of this.
|
||||
if (NS_SUCCEEDED(rv)) *result = mGlobalServiceManager;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsServiceManager::ShutdownGlobalServiceManager(nsIServiceManager* *result)
|
||||
{
|
||||
if (mGlobalServiceManager != NULL) {
|
||||
NS_RELEASE(mGlobalServiceManager);
|
||||
mGlobalServiceManager = NULL;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsServiceManager::GetService(const nsCID& aClass, const nsIID& aIID,
|
||||
nsISupports* *result,
|
||||
nsIShutdownListener* shutdownListener)
|
||||
{
|
||||
nsIServiceManager* mgr;
|
||||
nsresult rv = GetGlobalServiceManager(&mgr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return mgr->GetService(aClass, aIID, result, shutdownListener);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsServiceManager::ReleaseService(const nsCID& aClass, nsISupports* service,
|
||||
nsIShutdownListener* shutdownListener)
|
||||
{
|
||||
nsIServiceManager* mgr;
|
||||
nsresult rv = GetGlobalServiceManager(&mgr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return mgr->ReleaseService(aClass, service, shutdownListener);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsServiceManager::RegisterService(const nsCID& aClass, nsISupports* aService)
|
||||
{
|
||||
nsIServiceManager* mgr;
|
||||
nsresult rv = GetGlobalServiceManager(&mgr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return mgr->RegisterService(aClass, aService);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsServiceManager::UnregisterService(const nsCID& aClass)
|
||||
{
|
||||
nsIServiceManager* mgr;
|
||||
nsresult rv = GetGlobalServiceManager(&mgr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return mgr->UnregisterService(aClass);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// let's do it again, this time with ProgIDs...
|
||||
|
||||
nsresult
|
||||
nsServiceManager::GetService(const char* aProgID, const nsIID& aIID,
|
||||
nsISupports* *result,
|
||||
nsIShutdownListener* shutdownListener)
|
||||
{
|
||||
nsIServiceManager* mgr;
|
||||
nsresult rv = GetGlobalServiceManager(&mgr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return mgr->GetService(aProgID, aIID, result, shutdownListener);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsServiceManager::ReleaseService(const char* aProgID, nsISupports* service,
|
||||
nsIShutdownListener* shutdownListener)
|
||||
{
|
||||
nsIServiceManager* mgr;
|
||||
nsresult rv = GetGlobalServiceManager(&mgr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return mgr->ReleaseService(aProgID, service, shutdownListener);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsServiceManager::RegisterService(const char* aProgID, nsISupports* aService)
|
||||
{
|
||||
nsIServiceManager* mgr;
|
||||
nsresult rv = GetGlobalServiceManager(&mgr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return mgr->RegisterService(aProgID, aService);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsServiceManager::UnregisterService(const char* aProgID)
|
||||
{
|
||||
nsIServiceManager* mgr;
|
||||
nsresult rv = GetGlobalServiceManager(&mgr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return mgr->UnregisterService(aProgID);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
158
mozilla/xpcom/components/nsXPComFactory.h
Normal file
158
mozilla/xpcom/components/nsXPComFactory.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsXPComFactory_h__
|
||||
#define nsXPComFactory_h__
|
||||
|
||||
#include "nsIFactory.h"
|
||||
|
||||
/*
|
||||
* This file contains a macro for the implementation of a simple XPCOM factory.
|
||||
*
|
||||
* To implement a factory for a given component, you need to declare the
|
||||
* factory class using the NS_DEF_FACTORY() macro.
|
||||
*
|
||||
* The first macro argument is the name for the factory.
|
||||
*
|
||||
* The second macro argument is a function (provided by you) which
|
||||
* can be called by your DLL's NSGetFactory(...) entry point.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* NS_DEF_FACTORY(SomeComponent,SomeComponentImpl)
|
||||
*
|
||||
* Declares:
|
||||
*
|
||||
* class nsSomeComponentFactory : public nsIFactory {};
|
||||
*
|
||||
* NOTE that the NS_DEF_FACTORY takes care of enforcing the "ns" prefix
|
||||
* and appending the "Factory" suffix to the given name.
|
||||
*
|
||||
* To use the new factory:
|
||||
*
|
||||
* nsresult NS_New_SomeComponent_Factory(nsIFactory** aResult)
|
||||
* {
|
||||
* nsresult rv = NS_OK;
|
||||
* nsIFactory* inst = new nsSomeComponentFactory;
|
||||
* if (NULL == inst) {
|
||||
* rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
* } else {
|
||||
* NS_ADDREF(inst);
|
||||
* }
|
||||
* *aResult = inst;
|
||||
* return rv;
|
||||
* }
|
||||
*
|
||||
* NOTE:
|
||||
* ----
|
||||
* The factories created by this macro are not thread-safe and do not
|
||||
* support aggregation.
|
||||
*
|
||||
*/
|
||||
#define NS_DEF_FACTORY(_name,_type) \
|
||||
class ns##_name##Factory : public nsIFactory \
|
||||
{ \
|
||||
public: \
|
||||
ns##_name##Factory() { NS_INIT_REFCNT(); } \
|
||||
\
|
||||
NS_IMETHOD_(nsrefcnt) AddRef (void) \
|
||||
{ \
|
||||
return ++mRefCnt; \
|
||||
} \
|
||||
\
|
||||
NS_IMETHOD_(nsrefcnt) Release(void) \
|
||||
{ \
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
|
||||
if (--mRefCnt == 0) { \
|
||||
NS_DELETEXPCOM(this); \
|
||||
return 0; \
|
||||
} \
|
||||
return mRefCnt; \
|
||||
} \
|
||||
\
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) \
|
||||
{ \
|
||||
if (NULL == aInstancePtr) { \
|
||||
return NS_ERROR_NULL_POINTER; \
|
||||
} \
|
||||
\
|
||||
*aInstancePtr = NULL; \
|
||||
\
|
||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); \
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); \
|
||||
if (aIID.Equals(kIFactoryIID)) { \
|
||||
*aInstancePtr = (void*) this; \
|
||||
NS_ADDREF_THIS(); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
if (aIID.Equals(kISupportsIID)) { \
|
||||
*aInstancePtr = (void*) ((nsISupports*)this); \
|
||||
NS_ADDREF_THIS(); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
return NS_NOINTERFACE; \
|
||||
} \
|
||||
\
|
||||
NS_IMETHOD CreateInstance(nsISupports *aOuter, \
|
||||
const nsIID &aIID, \
|
||||
void **aResult) \
|
||||
{ \
|
||||
nsresult rv; \
|
||||
\
|
||||
_type * inst; \
|
||||
\
|
||||
if (NULL == aResult) { \
|
||||
rv = NS_ERROR_NULL_POINTER; \
|
||||
goto done; \
|
||||
} \
|
||||
*aResult = NULL; \
|
||||
if (NULL != aOuter) { \
|
||||
rv = NS_ERROR_NO_AGGREGATION; \
|
||||
goto done; \
|
||||
} \
|
||||
\
|
||||
NS_NEWXPCOM(inst, _type); \
|
||||
if (NULL == inst) { \
|
||||
rv = NS_ERROR_OUT_OF_MEMORY; \
|
||||
goto done; \
|
||||
} \
|
||||
NS_ADDREF(inst); \
|
||||
rv = inst->QueryInterface(aIID, aResult); \
|
||||
NS_RELEASE(inst); \
|
||||
\
|
||||
done: \
|
||||
return rv; \
|
||||
} \
|
||||
\
|
||||
NS_IMETHOD LockFactory(PRBool aLock) \
|
||||
{ \
|
||||
return NS_OK; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
protected: \
|
||||
virtual ~ns##_name##Factory() \
|
||||
{ \
|
||||
NS_ASSERTION(mRefCnt == 0, "non-zero refcnt at destruction"); \
|
||||
} \
|
||||
\
|
||||
nsrefcnt mRefCnt; \
|
||||
};
|
||||
|
||||
#endif /* nsXPComFactory_h__ */
|
||||
273
mozilla/xpcom/components/xcDll.cpp
Normal file
273
mozilla/xpcom/components/xcDll.cpp
Normal file
@@ -0,0 +1,273 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/* nsDll
|
||||
*
|
||||
* Abstraction of a Dll. Stores modifiedTime and size for easy detection of
|
||||
* change in dll.
|
||||
*
|
||||
* dp Suresh <dp@netscape.com>
|
||||
*/
|
||||
|
||||
#include "xcDll.h"
|
||||
#include "plstr.h" // strdup and strfree
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
// MAC ONLY
|
||||
nsDll::nsDll(const char *codeDllName, int type)
|
||||
: m_dllName(NULL), m_dllSpec(NULL), m_modDate(0), m_size(0),
|
||||
m_instance(NULL), m_status(DLL_OK)
|
||||
|
||||
{
|
||||
if (!codeDllName || !*codeDllName)
|
||||
{
|
||||
m_status = DLL_INVALID_PARAM;
|
||||
return;
|
||||
}
|
||||
m_dllName = PL_strdup(codeDllName);
|
||||
if (!m_dllName)
|
||||
{
|
||||
m_status = DLL_NO_MEM;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsDll::nsDll(nsIFileSpec *dllSpec)
|
||||
: m_dllName(NULL), m_dllSpec(dllSpec), m_modDate(0), m_size(0),
|
||||
m_instance(NULL), m_status(DLL_OK)
|
||||
{
|
||||
Init(dllSpec);
|
||||
}
|
||||
|
||||
nsDll::nsDll(const char *libPersistentDescriptor)
|
||||
: m_dllName(NULL), m_dllSpec(NULL), m_modDate(0), m_size(0),
|
||||
m_instance(NULL), m_status(DLL_OK)
|
||||
{
|
||||
Init(libPersistentDescriptor);
|
||||
}
|
||||
|
||||
nsDll::nsDll(const char *libPersistentDescriptor, PRUint32 modDate, PRUint32 fileSize)
|
||||
: m_dllName(NULL), m_dllSpec(NULL), m_modDate(0), m_size(0),
|
||||
m_instance(NULL), m_status(DLL_OK)
|
||||
{
|
||||
Init(libPersistentDescriptor);
|
||||
|
||||
// and overwrite the modData and fileSize
|
||||
m_modDate = modDate;
|
||||
m_size = fileSize;
|
||||
}
|
||||
|
||||
void
|
||||
nsDll::Init(nsIFileSpec *dllSpec)
|
||||
{
|
||||
// Addref the m_dllSpec
|
||||
m_dllSpec = dllSpec;
|
||||
NS_ADDREF(m_dllSpec);
|
||||
|
||||
// Make sure we are dealing with a file
|
||||
PRBool isFile = PR_FALSE;
|
||||
nsresult rv = m_dllSpec->isFile(&isFile);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
m_status = DLL_INVALID_PARAM;
|
||||
return;
|
||||
}
|
||||
if (isFile == PR_FALSE)
|
||||
{
|
||||
// Not a file. Cant work with it.
|
||||
m_status = DLL_NOT_FILE;
|
||||
return;
|
||||
}
|
||||
|
||||
// Populate m_modDate and m_size
|
||||
if (NS_FAILED(m_dllSpec->GetModDate(&m_modDate)) ||
|
||||
NS_FAILED(m_dllSpec->GetFileSize(&m_size)))
|
||||
{
|
||||
m_status = DLL_INVALID_PARAM;
|
||||
return;
|
||||
}
|
||||
|
||||
m_status = DLL_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDll::Init(const char *libPersistentDescriptor)
|
||||
{
|
||||
nsresult rv;
|
||||
m_modDate = 0;
|
||||
m_size = 0;
|
||||
|
||||
if (libPersistentDescriptor == NULL)
|
||||
{
|
||||
m_status = DLL_INVALID_PARAM;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a FileSpec from the persistentDescriptor
|
||||
nsIFileSpec *dllSpec = NULL;
|
||||
NS_DEFINE_IID(kFileSpecIID, NS_IFILESPEC_IID);
|
||||
rv = nsComponentManager::CreateInstance(NS_FILESPEC_PROGID, NULL, kFileSpecIID, (void **) &dllSpec);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
m_status = DLL_INVALID_PARAM;
|
||||
return;
|
||||
}
|
||||
|
||||
rv = dllSpec->SetPersistentDescriptorString((char *)libPersistentDescriptor);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
m_status = DLL_INVALID_PARAM;
|
||||
return;
|
||||
}
|
||||
|
||||
Init(dllSpec);
|
||||
}
|
||||
|
||||
|
||||
nsDll::~nsDll(void)
|
||||
{
|
||||
if (m_instance != NULL)
|
||||
Unload();
|
||||
if (m_dllSpec)
|
||||
NS_RELEASE(m_dllSpec);
|
||||
if (m_dllName)
|
||||
PL_strfree(m_dllName);
|
||||
}
|
||||
|
||||
const char *
|
||||
nsDll::GetNativePath()
|
||||
{
|
||||
if (m_dllName)
|
||||
return m_dllName;
|
||||
char *nativePath = NULL;
|
||||
m_dllSpec->GetNativePath(&nativePath);
|
||||
return nativePath;
|
||||
}
|
||||
|
||||
const char *
|
||||
nsDll::GetPersistentDescriptorString()
|
||||
{
|
||||
if (m_dllName)
|
||||
return m_dllName;
|
||||
char *persistentDescriptor = NULL;
|
||||
m_dllSpec->GetPersistentDescriptorString(&persistentDescriptor);
|
||||
return persistentDescriptor;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsDll::HasChanged()
|
||||
{
|
||||
if (m_dllName)
|
||||
return PR_FALSE;
|
||||
|
||||
// If mod date has changed, then dll has changed
|
||||
PRBool modDateChanged = PR_FALSE;
|
||||
nsresult rv = m_dllSpec->modDateChanged(m_modDate, &modDateChanged);
|
||||
if (NS_FAILED(rv) || modDateChanged == PR_TRUE)
|
||||
return PR_TRUE;
|
||||
|
||||
// If size has changed, then dll has changed
|
||||
PRUint32 aSize = 0;
|
||||
rv = m_dllSpec->GetFileSize(&aSize);
|
||||
if (NS_FAILED(rv) || aSize != m_size)
|
||||
return PR_TRUE;
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PRBool nsDll::Load(void)
|
||||
{
|
||||
if (m_status != DLL_OK)
|
||||
{
|
||||
return (PR_FALSE);
|
||||
}
|
||||
if (m_instance != NULL)
|
||||
{
|
||||
// Already loaded
|
||||
return (PR_TRUE);
|
||||
}
|
||||
|
||||
if (m_dllName)
|
||||
{
|
||||
m_instance = PR_LoadLibrary(m_dllName);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *nsprPath = NULL;
|
||||
nsresult rv = m_dllSpec->GetNSPRPath(&nsprPath);
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
|
||||
#ifdef XP_MAC
|
||||
// NSPR path is / separated. This works for all NSPR functions
|
||||
// except Load Library. Translate to something NSPR can accepts.
|
||||
char *macFileName = PL_strdup(nsprPath);
|
||||
if (macFileName != NULL)
|
||||
{
|
||||
if (macFileName[0] == '/')
|
||||
{
|
||||
// convert '/' to ':'
|
||||
int c;
|
||||
char* str = macFileName;
|
||||
while ((c = *str++) != 0)
|
||||
{
|
||||
if (c == '/')
|
||||
str[-1] = ':';
|
||||
}
|
||||
m_instance = PR_LoadLibrary(&macFileName[1]); // skip over initial slash
|
||||
}
|
||||
else
|
||||
{
|
||||
m_instance = PR_LoadLibrary(macFileName);
|
||||
}
|
||||
PL_strfree(macFileName);
|
||||
}
|
||||
#else
|
||||
m_instance = PR_LoadLibrary(nsprPath);
|
||||
#endif /* XP_MAC */
|
||||
}
|
||||
return ((m_instance == NULL) ? PR_FALSE : PR_TRUE);
|
||||
}
|
||||
|
||||
PRBool nsDll::Unload(void)
|
||||
{
|
||||
if (m_status != DLL_OK || m_instance == NULL)
|
||||
return (PR_FALSE);
|
||||
PRStatus ret = PR_UnloadLibrary(m_instance);
|
||||
if (ret == PR_SUCCESS)
|
||||
{
|
||||
m_instance = NULL;
|
||||
return (PR_TRUE);
|
||||
}
|
||||
else
|
||||
return (PR_FALSE);
|
||||
}
|
||||
|
||||
void * nsDll::FindSymbol(const char *symbol)
|
||||
{
|
||||
if (symbol == NULL)
|
||||
return (NULL);
|
||||
|
||||
// If not already loaded, load it now.
|
||||
if (Load() != PR_TRUE)
|
||||
return (NULL);
|
||||
|
||||
return (PR_FindSymbol(m_instance, symbol));
|
||||
}
|
||||
82
mozilla/xpcom/components/xcDll.h
Normal file
82
mozilla/xpcom/components/xcDll.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/* Dll
|
||||
*
|
||||
* Programmatic representation of a dll. Stores modifiedTime and size for
|
||||
* easy detection of change in dll.
|
||||
*
|
||||
* dp Suresh <dp@netscape.com>
|
||||
*/
|
||||
|
||||
#include "prio.h"
|
||||
#include "prlink.h"
|
||||
#include "nsIFileSpec.h"
|
||||
|
||||
typedef enum nsDllStatus
|
||||
{
|
||||
DLL_OK = 0,
|
||||
DLL_NO_MEM = 1,
|
||||
DLL_STAT_ERROR = 2,
|
||||
DLL_NOT_FILE = 3,
|
||||
DLL_INVALID_PARAM = 4
|
||||
} nsDllStatus;
|
||||
|
||||
class nsDll
|
||||
{
|
||||
private:
|
||||
char *m_dllName; // Mac only. Stores the dllName to load.
|
||||
|
||||
nsIFileSpec *m_dllSpec; // Filespec representing the component
|
||||
PRUint32 m_modDate; // last modified time at creation of this object
|
||||
PRUint32 m_size; // size of the dynamic library at creation of this object
|
||||
|
||||
PRLibrary *m_instance; // Load instance
|
||||
nsDllStatus m_status; // holds current status
|
||||
|
||||
void Init(nsIFileSpec *dllSpec);
|
||||
void Init(const char *persistentDescriptor);
|
||||
|
||||
public:
|
||||
|
||||
nsDll(nsIFileSpec *dllSpec);
|
||||
nsDll(const char *persistentDescriptor);
|
||||
nsDll(const char *persistentDescriptor, PRUint32 modDate, PRUint32 fileSize);
|
||||
nsDll(const char *dll, int type /* dummy */);
|
||||
|
||||
~nsDll(void);
|
||||
|
||||
// Status checking on operations completed
|
||||
nsDllStatus GetStatus(void) { return (m_status); }
|
||||
|
||||
// Dll Loading
|
||||
PRBool Load(void);
|
||||
PRBool Unload(void);
|
||||
PRBool IsLoaded(void)
|
||||
{
|
||||
return ((m_instance != 0) ? PR_TRUE : PR_FALSE);
|
||||
}
|
||||
void *FindSymbol(const char *symbol);
|
||||
|
||||
PRBool HasChanged(void);
|
||||
const char *GetNativePath(void);
|
||||
const char *GetPersistentDescriptorString(void);
|
||||
PRUint32 GetLastModifiedTime(void) { return(m_modDate); }
|
||||
PRUint32 GetSize(void) { return(m_size); }
|
||||
PRLibrary *GetInstance(void) { return (m_instance); }
|
||||
};
|
||||
88
mozilla/xpcom/components/xcDllStore.cpp
Normal file
88
mozilla/xpcom/components/xcDllStore.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/* THIS FILE IS OBSOLETE */
|
||||
|
||||
/* nsDllStore
|
||||
*
|
||||
* Stores dll and their accociated info in a hash keyed on the system format
|
||||
* full dll path name e.g C:\Program Files\Netscape\Program\raptor.dll
|
||||
*
|
||||
* NOTE: dll names are considered to be case sensitive.
|
||||
*/
|
||||
|
||||
#include "xcDllStore.h"
|
||||
|
||||
static PR_CALLBACK PRIntn _deleteDllInfo(PLHashEntry *he, PRIntn i, void *arg)
|
||||
{
|
||||
delete (nsDll *)he->value;
|
||||
return (HT_ENUMERATE_NEXT);
|
||||
}
|
||||
|
||||
nsDllStore::nsDllStore(void) : m_dllHashTable(NULL)
|
||||
{
|
||||
PRUint32 initSize = 128;
|
||||
|
||||
m_dllHashTable = PL_NewHashTable(initSize, PL_HashString,
|
||||
PL_CompareStrings, PL_CompareValues, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
nsDllStore::~nsDllStore(void)
|
||||
{
|
||||
if (m_dllHashTable)
|
||||
{
|
||||
// Delete each of the nsDll stored before deleting the Hash Table
|
||||
PL_HashTableEnumerateEntries(m_dllHashTable, _deleteDllInfo, NULL);
|
||||
PL_HashTableDestroy(m_dllHashTable);
|
||||
}
|
||||
m_dllHashTable = NULL;
|
||||
}
|
||||
|
||||
|
||||
nsDll* nsDllStore::Get(const char *dll)
|
||||
{
|
||||
nsDll *dllInfo = NULL;
|
||||
if (m_dllHashTable)
|
||||
{
|
||||
dllInfo = (nsDll *)PL_HashTableLookup(m_dllHashTable, dll);
|
||||
}
|
||||
return (dllInfo);
|
||||
}
|
||||
|
||||
|
||||
nsDll* nsDllStore::Remove(const char *dll)
|
||||
{
|
||||
if (m_dllHashTable == NULL)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
nsDll *dllInfo = Get(dll);
|
||||
PL_HashTableRemove(m_dllHashTable, dll);
|
||||
return (dllInfo);
|
||||
}
|
||||
|
||||
PRBool nsDllStore::Put(const char *dll, nsDll *dllInfo)
|
||||
{
|
||||
if (m_dllHashTable == NULL)
|
||||
return(PR_FALSE);
|
||||
|
||||
PLHashEntry *entry =
|
||||
PL_HashTableAdd(m_dllHashTable, (void *)dll, (void *)dllInfo);
|
||||
return ((entry != NULL) ? PR_TRUE : PR_FALSE);
|
||||
}
|
||||
49
mozilla/xpcom/components/xcDllStore.h
Normal file
49
mozilla/xpcom/components/xcDllStore.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
|
||||
/* nsDllStore
|
||||
*
|
||||
* Stores dll and their accociated info in a hash keyed on the system format
|
||||
* full dll path name e.g C:\Program Files\Netscape\Program\raptor.dll
|
||||
*
|
||||
* NOTE: dll names are considered to be case sensitive.
|
||||
*/
|
||||
|
||||
#include "plhash.h"
|
||||
#include "xcDll.h"
|
||||
|
||||
class nsDllStore
|
||||
{
|
||||
private:
|
||||
PLHashTable *m_dllHashTable;
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
nsDllStore(void);
|
||||
~nsDllStore(void);
|
||||
|
||||
// Caller is not expected to delete nsDll returned
|
||||
// The nsDll returned in NOT removed from the hash
|
||||
nsDll* Get(const char *filename);
|
||||
PRBool Put(const char *filename, nsDll *dllInfo);
|
||||
|
||||
// The nsDll returned is removed from the hash
|
||||
// Caller is expected to delete the returned nsDll
|
||||
nsDll* Remove(const char *filename);
|
||||
};
|
||||
117
mozilla/xpcom/doc/ObjectModel.html
Normal file
117
mozilla/xpcom/doc/ObjectModel.html
Normal file
@@ -0,0 +1,117 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<META NAME="Author" CONTENT="Kipp E.B. Hickman">
|
||||
<META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (WinNT; I) [Netscape]">
|
||||
<TITLE>Gemini Object Model</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<H1>
|
||||
Gemini Object Model</H1>
|
||||
The gemini object model is a cross platform component object model modelled
|
||||
after win32's IUnknown and COM. We do not support a C API to gemini at
|
||||
this time.
|
||||
<H2>
|
||||
nsID</H2>
|
||||
Like OSF's DCE, we use an "interface id" which is a unique identifer which
|
||||
names the interface. The nsID and be used as a key into a cross platform
|
||||
registry service to discover an implementation of an interface. Here is
|
||||
the declaration of nsID:
|
||||
<UL><TT>struct nsID {</TT>
|
||||
<BR><TT> PRUint32 m0;</TT>
|
||||
<BR><TT> PRUint16 m1, m2;</TT>
|
||||
<BR><TT> PRUint8 m3[8];</TT>
|
||||
|
||||
<P><TT> inline nsbool Equals(const nsID& other) const {</TT>
|
||||
<BR><TT> return</TT>
|
||||
<BR><TT> (((PRUint32*) &m0)[0] == ((PRUint32*)
|
||||
&other.m0)[0]) &&</TT>
|
||||
<BR><TT> (((PRUint32*) &m0)[1] == ((PRUint32*)
|
||||
&other.m0)[1]) &&</TT>
|
||||
<BR><TT> (((PRUint32*) &m0)[2] == ((PRUint32*)
|
||||
&other.m0)[2]) &&</TT>
|
||||
<BR><TT> (((PRUint32*) &m0)[3] == ((PRUint32*)
|
||||
&other.m0)[3]);</TT>
|
||||
<BR><TT> }</TT>
|
||||
<BR><TT>};</TT></UL>
|
||||
On windows, the "uuidgen" program (provided with Visual C++) can be used
|
||||
to generate these identifiers.
|
||||
<H2>
|
||||
nsISupports</H2>
|
||||
This is the base class for all component objects. Not all objects are component
|
||||
objects; these rules apply to objects which expose an interface which is
|
||||
shared across dll/exe boundaries. Here is nsISupports:
|
||||
<UL><TT>typedef nsID nsIID;</TT>
|
||||
<BR><TT>class nsISupports {</TT>
|
||||
<BR><TT>public:</TT>
|
||||
<BR><TT> virtual nsqresult QueryInterface(const nsIID& aIID,</TT>
|
||||
<BR><TT>
|
||||
void** aInstancePtr) = 0;</TT>
|
||||
<BR><TT> virtual nsrefcnt AddRef() = 0;</TT>
|
||||
<BR><TT> virtual nsrefcnt Release() = 0;</TT>
|
||||
<BR><TT>};</TT></UL>
|
||||
The semantics of this interface are identical to win32's "COM" IUnknown
|
||||
interface. In addition, the types are carefully mapped and the names are
|
||||
the same so that if necessary we can "flip a switch" and have the windows
|
||||
version (or any other platform that embraces COM) use the native COM IUnknown
|
||||
without source code modification.
|
||||
<H2>
|
||||
Factory Procedures</H2>
|
||||
Factory procedures use this design pattern
|
||||
<UL><TT>nsqresult NS_NewFoo(nsIFoo** aInstancePtr, nsISupports* aOuter,
|
||||
...);</TT></UL>
|
||||
The return value is a status value (see nsISupports.h for the legal return
|
||||
values); the first argument is a pointer to a cell which will hold the
|
||||
new instance pointer if the factory procedure succeeds. The second argument
|
||||
is a pointer to a containing component object that wishes to aggregate
|
||||
in the Foo object. This pointer will be null if no aggregation is requested.
|
||||
If the factory procedure cannot support aggregation of the Foo type then
|
||||
it fails and returns an error if aggregation is requested.
|
||||
|
||||
<P>The following symbols are defined for standard error return values from
|
||||
<TT>QueryInterface</TT> and from factory procedures:
|
||||
<UL><TT>#define NS_FAILED(_nsresult) ((_nsresult) < 0)</TT>
|
||||
<BR><TT>#define NS_SUCCEEDED(_nsresult) ((_nsresult) >= 0)</TT>
|
||||
|
||||
<P><TT>// Standard "it worked" return value</TT>
|
||||
<BR><TT>#define NS_OK 0</TT>
|
||||
|
||||
<P><TT>// Some standard error codes we use</TT>
|
||||
<BR><TT>#define NS_ERROR_BASE ((nsresult) 0xC1F30000)</TT>
|
||||
<BR><TT>#define NS_ERROR_OUT_OF_MEMORY (NS_ERROR_BASE + 0)</TT>
|
||||
<BR><TT>#define NS_ERROR_NO_AGGREGATION (NS_ERROR_BASE + 1)</TT>
|
||||
<BR><TT>#define NS_NOINTERFACE ((nqresult) 0x80004002L)</TT></UL>
|
||||
|
||||
<H2>
|
||||
nsIFactory</H2>
|
||||
Factory classes should eventually replace factory procedures for major
|
||||
classes. They provide an easy mechanism for placing code in DLLs. The nsIFactory
|
||||
class is as follows:
|
||||
<BR>
|
||||
<UL><TT>class nsIFactory: public nsISupports {</TT>
|
||||
<BR><TT>public:</TT>
|
||||
<UL><TT>virtual nsresult CreateInstance(const nsIID &aIID,</TT>
|
||||
<BR><TT>
|
||||
nsISupports *aOuter,</TT>
|
||||
<BR><TT>
|
||||
void **aResult) = 0;</TT>
|
||||
<BR><TT>virtual void LockFactory(PRBool aLock) = 0;</TT></UL>
|
||||
<TT>};</TT></UL>
|
||||
This interface is again identical to the COM version. More on registering
|
||||
factories shortly.
|
||||
<H2>
|
||||
Error Handling</H2>
|
||||
Because no exceptions are returned, error handling is done in the traditional
|
||||
"error status value" method.
|
||||
<H2>
|
||||
Cross Platform Registry</H2>
|
||||
A cross platform registry was written for the SmartUpdate feature of Communicator.
|
||||
We will investigate it's usefulness for our purposes.
|
||||
<H2>
|
||||
Library Management</H2>
|
||||
NSPR 2.x provides the cross platform mechanism for loading and unloading
|
||||
libraries, and run time linking.
|
||||
<BR>
|
||||
</BODY>
|
||||
</HTML>
|
||||
254
mozilla/xpcom/doc/TODO.html
Normal file
254
mozilla/xpcom/doc/TODO.html
Normal file
@@ -0,0 +1,254 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Mozilla/4.51 [en] (WinNT; U) [Netscape]">
|
||||
<meta name="Author" content="Suresh Duddi">
|
||||
<title>TODO List for XPCOM</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<center>
|
||||
<h1>
|
||||
TODO List for XPCOM</h1></center>
|
||||
|
||||
<center>Last updated: 25 March 1999
|
||||
<br><a href="mailto:dp@netscape.com">Suresh Duddi</a></center>
|
||||
|
||||
<table BORDER WIDTH="100%" NOSAVE >
|
||||
<tr NOSAVE>
|
||||
<th NOSAVE>Task</th>
|
||||
|
||||
<th NOSAVE><a href="http://bugzilla.mozilla.org/bug_status.html#priority">Priority</a></th>
|
||||
|
||||
<th NOSAVE>Owner</th>
|
||||
|
||||
<th NOSAVE>MileStone complete/Status</th>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#33CCFF" NOSAVE>
|
||||
<td NOSAVE>Move xpcom from using NR_*() functions (modules/libreg) to nsIRegistry
|
||||
(xpcom/src/nsRegistry.cpp)
|
||||
<ul>
|
||||
<li>
|
||||
Mainly you want to change all the Platform*() functions in nsComponentManager.cpp</li>
|
||||
|
||||
<li>
|
||||
Now we open/close the registry all the time. I want to keep the registry
|
||||
open all the time. That would get performance up.</li>
|
||||
|
||||
<li>
|
||||
Platform*() functions use the NR_*Raw() functions in some places. I wonder
|
||||
if the nsRegistry has a equivalent. If not we need to create them.</li>
|
||||
</ul>
|
||||
Mostly, there is equivalence between NR_*() calls and nsRegistry calls. </td>
|
||||
|
||||
<td>P2</td>
|
||||
|
||||
<td>Nick Ambrose <<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
|
||||
|
||||
<td>3/22/1999 started
|
||||
<br>3/27/1999 Patch submitted
|
||||
<br>3/30/1999 landing
|
||||
<br><b>DONE</b></td>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#33CCFF">
|
||||
<td>RegisterFactory() and RegisterComponent(..persist=0) ignoring PROGID.
|
||||
Needs Fix.</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td>Nick Ambrose <<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
|
||||
|
||||
<td>4/6/1999 started
|
||||
<br>4/7/1999 Patch submitted
|
||||
<br>4/12/1999 Patch Checked in
|
||||
<br><b>DONE</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Startup components: Some components need to be created at startup.
|
||||
Have a framework for them.</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>nsIRegistry access via Javascript.</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td>IDL of nsIRegistry will fix this says <a href="mailto:jband@netscape.com">John
|
||||
Bandhauer</a></td>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#33CCFF" NOSAVE>
|
||||
<td NOSAVE>API changes: Remove all pathlist. XPCOM should support only
|
||||
paths.</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
|
||||
|
||||
<td>4/2/1999 Checked in
|
||||
<br><b>DONE</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Fix xpcom from being initialized before main from static variables.</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
|
||||
|
||||
<td>3/22/1999 Started.
|
||||
<br>- checked in a fixed xpcom initialization sequence.
|
||||
<br>- Now got to fix all code statically calling it. I know Netlib does.
|
||||
<br>- 4/1/1999 Fixed netlib on unix from static intialization. WIN is left.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Path handling: Use nsFileSpec instead of file path names. Char * pathnames
|
||||
are not intl, and cannot be stored in the registry. Plus that wont support
|
||||
mac aliases.
|
||||
<ul>
|
||||
<li>
|
||||
Possibly move autoreg out of xpcom</li>
|
||||
</ul>
|
||||
</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a>
|
||||
<br><a href="mailto:rjc@netscape.com">Robert Churchill</a></td>
|
||||
|
||||
<td>3/24/1999 started
|
||||
<br><b>Blocked </b>on deciding which solution to pick.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Registry dump utility (regExport exists on windows) and about:registry
|
||||
(or) better yet an rdf data source for the registry.</td>
|
||||
|
||||
<td>P3</td>
|
||||
|
||||
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
|
||||
|
||||
<td>4/5/1999 Fixed regExport to accurately dump the registry on win and
|
||||
unix.
|
||||
<br>- regExport needs to be compiled on the mac.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Replace use of nsVector (PL_Vector) with nsISupportsArray</td>
|
||||
|
||||
<td>P3</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>PATH argument to NSRegisterSelf() and NSUnregisterSelf() to be a nsISupports</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#33CCFF" NOSAVE>
|
||||
<td NOSAVE>Code Cleanup:
|
||||
<ul>
|
||||
<li>
|
||||
Registry path strings in nsComponentManager.cpp #defined</li>
|
||||
</ul>
|
||||
</td>
|
||||
|
||||
<td>P3</td>
|
||||
|
||||
<td>Nick Ambrose <<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
|
||||
|
||||
<td>4/1/1999 started
|
||||
<br>4/5/1999 Patch submitted and checked in
|
||||
<br><b>DONE</b></td>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#33CCFF">
|
||||
<td>Performance
|
||||
<ul>
|
||||
<li>
|
||||
Cache commonly used registry keys</li>
|
||||
</ul>
|
||||
</td>
|
||||
|
||||
<td>P1</td>
|
||||
|
||||
<td>Nick Ambrose <<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
|
||||
|
||||
<td>4/1/1999 started
|
||||
<br>4/5/1999 Patch submitted and checked in
|
||||
<br><b>DONE</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Factories: Use previously created factories for object creation instead
|
||||
of creating the factory everytime the object needs to be created.
|
||||
<ul>
|
||||
<li>
|
||||
This is very tricky as the factory is owned by the component and when it
|
||||
decides to unload itself on a CanUnload() call, the factory will be released.
|
||||
Got to make sure that the component manager gets notified of this if it
|
||||
caches the factory.</li>
|
||||
</ul>
|
||||
</td>
|
||||
|
||||
<td>P2</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr BGCOLOR="#33CCFF" NOSAVE>
|
||||
<td NOSAVE>nsIAllocator: wrap it in a static api</td>
|
||||
|
||||
<td>P2</td>
|
||||
|
||||
<td><a href="mailto:jband@netscape.com">John Bandhauer</a></td>
|
||||
|
||||
<td NOSAVE>3/31/1999 started
|
||||
<br>4/2/1999 Check in
|
||||
<br><b>DONE</b></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>
|
||||
Documentation on XPCOM</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="TODO.html">TODO List</a> <<i>this page></i></li>
|
||||
|
||||
<li>
|
||||
XPCOM main page : <a href="http://www.mozilla.org/projects/xpcom">http://www.mozilla.org/projects/xpcom</a></li>
|
||||
|
||||
<li>
|
||||
<a href="xpcom-code-faq.html">Code FAQ</a></li>
|
||||
|
||||
<li>
|
||||
<a href="xpcom-component-registration.html">Component Registration</a></li>
|
||||
</ul>
|
||||
|
||||
<hr WIDTH="100%">
|
||||
</body>
|
||||
</html>
|
||||
93
mozilla/xpcom/doc/c++tips.html
Normal file
93
mozilla/xpcom/doc/c++tips.html
Normal file
@@ -0,0 +1,93 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<META NAME="Author" CONTENT="Kipp E.B. Hickman">
|
||||
<META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (WinNT; U) [Netscape]">
|
||||
<TITLE>C++ Tips</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<H1>
|
||||
C++ Tips</H1>
|
||||
This is a compilation of tips on how to write cross-platform C++ code that
|
||||
compiles everywhere.
|
||||
<H2>
|
||||
General</H2>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
Always use the nspr types for intrinsic integer types. The only exception
|
||||
to this rule is when writing machine dependent code that is called from
|
||||
xp code. In this case you will probably need to bridge the type systems
|
||||
and cast from an nspr type to a native type. The other exception is floating
|
||||
point; nspr defines PRFloat as a double (!).</LI>
|
||||
|
||||
<LI>
|
||||
Exceptions do not work everywhere so don't use them anywhere except in
|
||||
machine specific code, and then if you do use them in machine specific
|
||||
code you must catch all exceptions there because you can't throw the exception
|
||||
across xp code.</LI>
|
||||
|
||||
<LI>
|
||||
Templates do not work everywhere so don't use them anywhere.</LI>
|
||||
|
||||
<LI>
|
||||
Do not wrap include statements with an #ifdef. The reason is that when
|
||||
the symbol is not defined, other compiler symbols will not be defined and
|
||||
it will be hard to test the code on all platforms. An example of what <B>not</B>
|
||||
to do:</LI>
|
||||
|
||||
<BR>
|
||||
<UL><TT>#ifdef X</TT>
|
||||
<BR><TT>#include "foo.h"</TT>
|
||||
<BR><TT>#endif</TT>
|
||||
<BR><TT></TT> </UL>
|
||||
|
||||
<LI>
|
||||
For types that do not need operator= or a copy constructor, declare them
|
||||
yourselves and make them private. Example:</LI>
|
||||
|
||||
<BR>
|
||||
<UL><TT>class foo {</TT>
|
||||
<BR><TT>...</TT>
|
||||
<BR><TT>private:</TT>
|
||||
<BR><TT> // These are not supported and are not implemented!</TT>
|
||||
<BR><TT> foo(const foo& x);</TT>
|
||||
<BR><TT> foo& operator=(const foo& x);</TT>
|
||||
<BR><TT>};</TT></UL>
|
||||
|
||||
<LI>
|
||||
</LI>
|
||||
</UL>
|
||||
|
||||
<H2>
|
||||
Windows Compatability</H2>
|
||||
|
||||
<H2>
|
||||
Metroworks Compatability</H2>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
MAC compilers do not handle #include path names in the same manner as other
|
||||
systems. Consequently #include statements should not contain path names,
|
||||
just simple file names. An example of what <B>not</B> to do:</LI>
|
||||
|
||||
<BR>
|
||||
<UL>#include "gemini/nsICSSParser.h"
|
||||
<BR> </UL>
|
||||
|
||||
<LI>
|
||||
</LI>
|
||||
</UL>
|
||||
|
||||
<H2>
|
||||
G++ Compatability</H2>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
Use void in argument lists for functions that have no arguments (this works
|
||||
around a bug in g++ 2.6.3)</LI>
|
||||
</UL>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
279
mozilla/xpcom/doc/xpcom-code-faq.html
Normal file
279
mozilla/xpcom/doc/xpcom-code-faq.html
Normal file
@@ -0,0 +1,279 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Mozilla/4.51 [en] (WinNT; U) [Netscape]">
|
||||
<meta name="Author" content="Suresh Duddi">
|
||||
<title>XPCOM Code FAQ</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>
|
||||
XPCOM Code FAQ</h2>
|
||||
Suresh Duddi <<a href="mailto:dp@netscape.com">dp@netscape.com</a>>
|
||||
<br>Last Modified: April 2 1999
|
||||
<br>
|
||||
<hr WIDTH="100%">
|
||||
<br>I am documenting things randomly as I am replying to people's questions.
|
||||
So this looks more like an FAQ.
|
||||
<h3>
|
||||
Table of Contents</h3>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<a href="#What are the Global Objects that XPCOM maintains">What are the
|
||||
Global Objects that XPCOM maintains</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#What are the static classes that XPCOM maintains">What are the
|
||||
static classes that XPCOM maintains</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Is there any restriction on which static class I should call fi">Is
|
||||
there any restriction on which static class I should call first</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#What is the order of creation of the ServiceManager, ComponentM">What
|
||||
is the order of creation of the ServiceManager, ComponentManager and Registry</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Is there a global Registry being maintained">Is there a global
|
||||
Registry being maintained</a></li>
|
||||
|
||||
<li>
|
||||
<font color="#000000"><a href="#ComponentManager Vs ServiceManager">ComponentManager
|
||||
Vs ServiceManager</a></font></li>
|
||||
|
||||
<li>
|
||||
<a href="#ProgID Vs CLSID">ProgID Vs CLSID</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#How to debug components ?">How to debug components ?</a></li>
|
||||
</ol>
|
||||
|
||||
<hr WIDTH="100%">
|
||||
<h4>
|
||||
<a NAME="What are the Global Objects that XPCOM maintains"></a>What are
|
||||
the Global Objects that XPCOM maintains</h4>
|
||||
|
||||
<ul>mGlobalServiceManager
|
||||
<br>mGlobalComponentManager</ul>
|
||||
|
||||
<h4>
|
||||
<a NAME="What are the static classes that XPCOM maintains"></a>What are
|
||||
the static classes that XPCOM maintains</h4>
|
||||
|
||||
<blockquote>nsComponentManager
|
||||
<br>nsServiceManager</blockquote>
|
||||
|
||||
<h4>
|
||||
<a NAME="Is there any restriction on which static class I should call fi"></a>Is
|
||||
there any restriction on which static class I should call first</h4>
|
||||
|
||||
<blockquote>No restrictions. You can call any function from the static
|
||||
classes nsComponentManager and nsServiceManager. XPCOM will do the right
|
||||
thing to initialize itself at both places.
|
||||
<p>Autoregistration() can happen only after Init_XPCOM() is called since
|
||||
the registy might be required by SelfRegister() functions of the dlls and
|
||||
it is only in Init_XPCOM() do we create register the RegistryFactory()
|
||||
with the ComponentManager.</blockquote>
|
||||
|
||||
<h4>
|
||||
<a NAME="What is the order of creation of the ServiceManager, ComponentM"></a>What
|
||||
is the order of creation of the ServiceManager, ComponentManager and Registry</h4>
|
||||
|
||||
<blockquote>Init_XPCOM()
|
||||
<blockquote>
|
||||
<li>
|
||||
create the global service manager</li>
|
||||
|
||||
<li>
|
||||
create the global component manager and register as service with the global
|
||||
service manager</li>
|
||||
|
||||
<li>
|
||||
RegisterFactory(...RegistryFactory...) Register the RegistryFactory
|
||||
with the component manager so that new registry objects can be created.</li>
|
||||
</blockquote>
|
||||
Now the hard problem is when to trigger Init_XPCOM() There are two static
|
||||
objects nsComponentManager and nsServiceManager. Any function in either
|
||||
of them can be called first. Today nsServiceManager::GetService() is the
|
||||
first one that gets called. All the members of the static nsServiceManager
|
||||
use the NS_GetGlobalServiceManager() to get to the global service manager.
|
||||
All members of the static nsComponentManager use the NS_GetGlobalComponentManager()
|
||||
to get to the global component manager. Hence if we trigger Init_XPCOM()
|
||||
from both NS_GetGlobalComponentManager() and NS_GetGlobalServiceManager()
|
||||
we will be safe.</blockquote>
|
||||
|
||||
<h4>
|
||||
<a NAME="Is there a global Registry being maintained"></a>Is there a global
|
||||
Registry being maintained</h4>
|
||||
|
||||
<blockquote>No. The nsIRegistry is designed to be lightweight access to
|
||||
the registry. Consumers who need to access the registry should use the
|
||||
component manager to create the their own registry access object. This
|
||||
is required because the open() call is supported by the nsIRegistry() and
|
||||
if we maintain a global registry arbitrating which registry file is opened
|
||||
is going to be a major headach.
|
||||
<p>The ProgID for the registry will be <font color="#990000">component://netscape/registry</font>
|
||||
<br> </blockquote>
|
||||
|
||||
<h4>
|
||||
<a NAME="ComponentManager Vs ServiceManager"></a><font color="#000000">ComponentManager
|
||||
Vs ServiceManager</font></h4>
|
||||
|
||||
<blockquote><font color="#000000">ComponentManager is the only way for
|
||||
component creation. ComponentManager always uses the component's factory
|
||||
to create the component instance. Clients (code that calls CreateInstance()
|
||||
to create and use a component) call the ComponentManager to create instances.
|
||||
Components (the code that implemented NSRegisterSelf()) calls the ComponentManager
|
||||
to register itself and gets called when a Client wants to instantiate a
|
||||
component.</font>
|
||||
<p><font color="#000000">ServiceManager is a convinience for getting singleton
|
||||
components, components for which only one instance stays alive for the
|
||||
entire application e.g Netlib. It enforces only one of a kind of a component
|
||||
to exist. Hence the notion of getting a service not creating one. (as opposed
|
||||
to the notion of Creating instances with the componentManager). ServiceManager
|
||||
is a convenience because components can technically force singletonism
|
||||
by making their factory return the same instance if one was created already.
|
||||
The other big use of ServiceManager is the (still unimplemented) notion
|
||||
of Shutting down a service.</font>
|
||||
<p><b><i><font color="#000000">Client</font></i></b>
|
||||
<ul>
|
||||
<li>
|
||||
<i><font color="#000000">When does a client use the service manager vs
|
||||
component manager</font></i></li>
|
||||
|
||||
<br><font color="#000000">When a client knows that the component that they
|
||||
are trying to instantiate is a singleton, they need to call service manager
|
||||
instead of component manager. Clients dont have to worry about calling
|
||||
the ComponentManager at all in this case. The ServiceManager will take
|
||||
care of creating the instance if the first one doesn't exist already.</font>
|
||||
<br>
|
||||
<li>
|
||||
<i><font color="#000000">When does a client use the Component Manager as
|
||||
opposed to Service Manager</font></i></li>
|
||||
|
||||
<br><font color="#000000">When a client wants a private instance of a component,
|
||||
they call the Component Manager. From the Clients point of view, a new
|
||||
xpcom object creation happens everytime they call CreateInstance() Anything
|
||||
else is an implementation detail that the Client need not worry about.</font>
|
||||
<br>
|
||||
<li>
|
||||
<i><font color="#000000">How does a Client know that they have to instantiate
|
||||
a singleton</font></i></li>
|
||||
|
||||
<br><font color="#000000">For now, the Client just has to know. There is
|
||||
no way of telling which component is a Service and which isn't. In fact,
|
||||
in todays xpcom (Mar 1999) any component can be accessed as a Service.
|
||||
Use your judgement until there is a proper method or service manager is
|
||||
eliminated. There is nothing even in the code that detects Services from
|
||||
Instances.</font>
|
||||
<p><b><font color="#CC0000">Need a solution for this. Email suggestion
|
||||
to <a href="mailto:warren@netscape.com,dp@netscape.com">warren@netscape.com,
|
||||
dp@netscape.com</a></font></b>
|
||||
<br> </ul>
|
||||
<b><i><font color="#000000">Component</font></i></b>
|
||||
<ul>
|
||||
<li>
|
||||
<i><font color="#000000">Can a component enforce use only as a Service</font></i></li>
|
||||
|
||||
<br><font color="#000000">No. The notion of the ServiceManager is available
|
||||
only to Clients.</font>
|
||||
<p><font color="#000000">Note that at some points when a component wants
|
||||
another component, it actually behaves as a client and hence follows the
|
||||
rules of the Client above to either CreateInstance() or GetService() the
|
||||
needed component.</font>
|
||||
<p><b><tt><font color="#990000">Workaround:</font></tt></b><font color="#000000">
|
||||
If however a component wants only one of its instances to exist and cannot
|
||||
ensure that Clients understand well enough only to use the Service Manager
|
||||
to get it, it can implement singletonism in its factory. Basically the
|
||||
factory on first instance creation should hang on to the instance. On subsequence
|
||||
instance creations, addref the instance it is holding to and return that
|
||||
instead creating a new one.</font>
|
||||
<ul>
|
||||
<br><font color="#000000">E.g preferences does this.</font> Code sample
|
||||
at
|
||||
<a href="http://lxr.mozilla.org/seamonkey/source/modules/libpref/src/nsPref.cpp#621">nsPref.cpp
|
||||
nsPrefFactory::CreateInstance()</a> and <a href="http://lxr.mozilla.org/seamonkey/source/modules/libpref/src/nsPref.cpp#227">nsPref.cpp
|
||||
nsPref::GetInstance()</a> With this implementation, whether Clients get
|
||||
to it by calling nsIServiceManager::GetService() or nsIComponentManager::CreateInstance(),
|
||||
the same object will be returned hence guaranteeing singletonism.</ul>
|
||||
|
||||
<li>
|
||||
<i><font color="#000000">Should a component do anything at creation to
|
||||
become a Service</font></i></li>
|
||||
|
||||
<br><font color="#000000">No. Again, the notion of a ServiceManager is
|
||||
available only to Clients.</font>
|
||||
<br>
|
||||
<li>
|
||||
<i><font color="#000000">Can a component advertise that it is a service
|
||||
so clients can use it as one</font></i></li>
|
||||
|
||||
<br>No. There isn't a way other than a comment in the interface of the
|
||||
header file.</ul>
|
||||
</blockquote>
|
||||
|
||||
<h4>
|
||||
<a NAME="ProgID Vs CLSID"></a>ProgID Vs CLSID</h4>
|
||||
|
||||
<blockquote>ClassID or CLSID is the unique indentification of a component.
|
||||
It is a structure of huge numbers generated by using uuidgen on a windows
|
||||
box. It is represented as a string in documentation as {108d75a0-bab5-11d2-96c4-0060b0fb9956}
|
||||
<p>ProgID is the string identification of an implementation of a component
|
||||
the client is looking for. The representation takes a URI syntax. Eg. <i>component://netscape/network/protocol?name=http;description=Http%20Protocol%20Handler</i>
|
||||
<br>Some simplify this to, ProgID is a more readable string form of a CLSID.
|
||||
That is acceptable on the periphery. The ProgID is a Client thing. Components
|
||||
register with component manager to claim that they are the implementation
|
||||
for a ProgID. A component can register to be the implementation for multiple
|
||||
ProgIDs (not implemented yet).
|
||||
<p><b><i>Client</i></b>
|
||||
<ul>
|
||||
<li>
|
||||
<i>Should CreateInstance() calls use ProgID or CLSID</i></li>
|
||||
|
||||
<br>ProgID is what Clients should use to CreateInstances. Clients should
|
||||
not even know about the CLSID unless they are hell bent on creating a particular
|
||||
implementation of a component.
|
||||
<br> </ul>
|
||||
<b><i>Component</i></b>
|
||||
<ul>
|
||||
<li>
|
||||
<i>Should Components register with both a CID and ProgID</i></li>
|
||||
|
||||
<br>Absolutely.</ul>
|
||||
</blockquote>
|
||||
|
||||
<h4>
|
||||
<a NAME="How to debug components ?"></a>How to debug components ?</h4>
|
||||
|
||||
<blockquote>XPCOM provides log output. To enable the logging:
|
||||
<blockquote><tt>setenv NSPR_LOG_MODULES nsComponentManager:5</tt>
|
||||
<br><tt>setenv NSPR_LOG_FILE xpcom.log</tt></blockquote>
|
||||
Start your application after setting the above environment variables. Debug
|
||||
log from xpcom would be in the file <tt>xpcom.log</tt>
|
||||
<p>Since components are dynamically loaded only on demand, debugging them
|
||||
could be a hard. Here are some tips to debugging components.
|
||||
<p><b><i>Windows: VC5.0 VC6.0</i></b>
|
||||
<ul>Include your component library in the Project->Settings, Additional
|
||||
Dll. drop down. After that breakpoints can be enabled.</ul>
|
||||
<b><i>Unix: gdb</i></b>
|
||||
<blockquote>Let the program run until you are sure that your component
|
||||
is loaded. Type Control-C. Now all symbols from your component will be
|
||||
available in gdb. Put your breakpoints and restart the app. Gdb will complain
|
||||
that it cannot set the breakpoint, and that it is temporarily disabling
|
||||
it, but when the *.so is loaded, the breakpoint is enabled automatically.
|
||||
- <<a href="mailto:erik@netscape.com">Eric Van Der Poel</a>>
|
||||
<p>I think typing "dir components" (assuming you're in dist/bin) will also
|
||||
allow you to see the symbols in your stack the first time. - <<a href="mailto:alecf@netscape.com">Alec
|
||||
Flett</a>></blockquote>
|
||||
<b><i>Mac: Codewarrior</i></b>
|
||||
<blockquote>Just open the appropriate .xSYM file in the debugger; the debugger
|
||||
will target the library when the application is run. - <<a href="mailto:sfraser@netscape.com">Simon
|
||||
Fraser</a>></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<hr WIDTH="100%">
|
||||
</body>
|
||||
</html>
|
||||
543
mozilla/xpcom/doc/xpcom-component-registration.html
Normal file
543
mozilla/xpcom/doc/xpcom-component-registration.html
Normal file
@@ -0,0 +1,543 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Suresh Duddi">
|
||||
<meta name="GENERATOR" content="Mozilla/4.51 [en] (X11; U; Linux 2.0.36 i686) [Netscape]">
|
||||
<title>XPCOM Dynamic Component Registration</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<center>
|
||||
<h2>
|
||||
XPCOM Dynamic Component Registration</h2></center>
|
||||
|
||||
<center>Suresh Duddi <<a href="mailto:dp@netscape.com">dp@netscape.com</a>>
|
||||
<hr WIDTH="100%"></center>
|
||||
|
||||
<p>Dynamic object registration in XPCOM is achieved by interaction of the
|
||||
following components:
|
||||
<ul>
|
||||
<li>
|
||||
The Component Registry</li>
|
||||
|
||||
<li>
|
||||
The Repository</li>
|
||||
|
||||
<li>
|
||||
The Service Manager</li>
|
||||
|
||||
<li>
|
||||
Component dll implementing <tt>NSRegisterSelf()</tt></li>
|
||||
</ul>
|
||||
The registration mechanism for XPCOM components is similar in many ways
|
||||
to that of COM. The XPCOM component dlls will have the opportunity to register
|
||||
themselves with the registry. The exact time of installation would be either
|
||||
at install time or as a result of <b>autodetection</b> by the Repository
|
||||
Manager at runtime.
|
||||
<br>
|
||||
<hr WIDTH="100%">
|
||||
<h3>
|
||||
<a NAME="The Registry: XPCOM Hierarchy"></a>The Component Registry</h3>
|
||||
There are three types of Component Registries:
|
||||
<ol>
|
||||
<li>
|
||||
<b>App-Component-Registry<br>
|
||||
</b>Each application has its own Component Registry that lives along with
|
||||
the app in its <exe-dir>/components directory. The Component Registry
|
||||
is created on installation or first run. It is be used read-only by XPCOM</li>
|
||||
|
||||
<li>
|
||||
<b>User-Component-Registry</b></li>
|
||||
|
||||
<br>Each user can install additional components under their user home directory.
|
||||
These components will be shared across all XPCOM applications that the
|
||||
user runs.
|
||||
<li>
|
||||
<b>Meta-Component-Registry</b></li>
|
||||
|
||||
<br>Sharing Components between application: This can happen in two ways.
|
||||
The installer of an application can find the other application's components
|
||||
by looking for the application specifically and registering them with this
|
||||
app's component registry. The second and more preferable approach is to
|
||||
keep a machine wide Meta-Components-Registry that would aggregate all the
|
||||
app component registries.</ol>
|
||||
The difference component registries will be searched in the following order:
|
||||
<ol>
|
||||
<li>
|
||||
User Components Registry</li>
|
||||
|
||||
<li>
|
||||
App Component Registry</li>
|
||||
|
||||
<li>
|
||||
Meta Component Registry</li>
|
||||
</ol>
|
||||
The user component registry is the only one that will be updated on the
|
||||
fly by XPCOM. JS will be given the option to update either the App-Component-Registry
|
||||
or the User-Component-Registry and this may succeed fail based on write
|
||||
permission, although the general guideline is to update the User-Component-Registry.
|
||||
JS will have to do special things to update the App-Component-Registry.
|
||||
<p>Profiles are a notion of the app (navigator) and xpcom has nothing to
|
||||
do with it. The app will store app specific data in a Data-Registry that
|
||||
will be stored under the user's home directory.
|
||||
<h4>
|
||||
How does this Solve our problems</h4>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Multiple installations of mozilla and xpcom based apps</li>
|
||||
|
||||
<br>Since each installation is going run with their own App-Component-Registry,
|
||||
basically both apps will work. No inter process locking is essential. Since
|
||||
both processes will operate on the User-Component-Registry, inter process
|
||||
locking of the User-Component-Registry will be required.
|
||||
<li>
|
||||
Third Party components installation</li>
|
||||
|
||||
<br>Third parties can install components in their own directories and update
|
||||
the App-Component-Registry (preferable) or User-Component-Registry depending
|
||||
on if the sharing of component needs to be specific to the user or for
|
||||
all users. Facilities for updating the registry would be to use JS or write
|
||||
XPCOM code in their installer. The other option would be to add their components
|
||||
in their own directory, create a App-Component-Registry of their own in
|
||||
their directory and reference it in the Global Meta-Components-Registry.
|
||||
This will get their components used by all applications.
|
||||
<li>
|
||||
Registry used to store app specific data</li>
|
||||
|
||||
<br>This is a totally separate registry: the Data-Registry. The theory
|
||||
is that this will reside in the user's home directory. The registry hierarchy
|
||||
is app specific.
|
||||
<li>
|
||||
User Specific components</li>
|
||||
|
||||
<br>This is basically the User-Component-Registry. Inter process locking
|
||||
is required as all processes with XPCOM will access the same User-Component-Registry.
|
||||
<li>
|
||||
Embedding</li>
|
||||
|
||||
<br>This is requires more thought. The fact is when say Gecko is embedded
|
||||
into an application, Gecko is running most probably in the process space
|
||||
of that application and hence the XPCOM used will look for components in
|
||||
this embedding applications directory. The embedding procedure should create
|
||||
a App-Component-Reqistry for the embedding application that should contain
|
||||
all the components from different apps this app would like to use. This
|
||||
is however not required, if the Meta-Component-Registry exists.
|
||||
<li>
|
||||
User not having permission to the place where the global registry lives,
|
||||
if there is one.</li>
|
||||
|
||||
<br>First the App-Component-Registry is written to only when there is a
|
||||
new component or a component has gone away. New components come with installers
|
||||
or the user calls regFactory.exe with the dll as an argument or clicks
|
||||
on a button that says "refresh my user components" which will cause autoregistration
|
||||
of user components. For deleted app components, annotations will be made
|
||||
in the User-Component-Registry. Deleted user components is a non-issue.
|
||||
<li>
|
||||
NFS mounted home directories and app directories</li>
|
||||
|
||||
<br>NFS mounted home directories requires inter-machine locking of the
|
||||
User-Component-Registry. NFS mounted app directories dont have a
|
||||
problem as the App-Component-Registry is only used read-only by XPCOM.</ol>
|
||||
So in summary,
|
||||
<ul>
|
||||
<li>
|
||||
App-Component-Registry pretty much solves the top problem of Multiple applications.
|
||||
With some help from the installer, Third party components will also be
|
||||
solved.</li>
|
||||
|
||||
<li>
|
||||
User-Component-Registry solves the User Specific Components problem.</li>
|
||||
|
||||
<li>
|
||||
Meta-Component-Registry enables the dynamic sharing of components between
|
||||
apps which eases embedding.</li>
|
||||
</ul>
|
||||
As a first cut, I am going to implement the App-Component-Registry for
|
||||
M8.
|
||||
<h4>
|
||||
Hierarchy Used by Component Registry</h4>
|
||||
XPCOM uses the nsRegistry to store mappings between CLSIDs and their implementations.
|
||||
The Registry provides persistent storage of hierarchical keys and name-value
|
||||
pairs associated with each key. Each key also keeps a default value.
|
||||
<p>XPCOM will use the following registry hierarchy:
|
||||
<blockquote><tt>ROOTKEY_COMMON</tt>
|
||||
<br><tt> Common</tt>
|
||||
<br><tt> Classes</tt>
|
||||
<br><tt>
|
||||
CLSID</tt>
|
||||
<br><tt>
|
||||
<b><font color="#CC0000">{108d75a0-bab5-11d2-96c4-0060b0fb9956}</font></b></tt>
|
||||
<br><tt><nobr>
|
||||
InprocServer (S) = <font color="#CC0000">/home/dp/dist/bin/components/libnfs-protocol.so</font></nobr></tt>
|
||||
<br><tt><nobr>
|
||||
ProgID (S) = <b><font color="#CC0000">component://netscape/network-protocol&type=nfs</font></b></nobr></tt>
|
||||
<br><tt><nobr>
|
||||
ClassName (S) = <b><font color="#CC0000">NFS Protocol
|
||||
Handler</font></b></nobr></tt>
|
||||
<p><tt> <font color="#CC0000">component://netscape/network-protocol&type=nfs</font></tt>
|
||||
<br><tt><nobr>
|
||||
CLSID (S) = <font color="#CC0000">{108d75a0-bab5-11d2-96c4-0060b0fb9956}</font></nobr></tt>
|
||||
<p><tt><i> </i>Software</tt>
|
||||
<br><tt> Netscape</tt>
|
||||
<br><tt>
|
||||
XPCOM</tt>
|
||||
<br><tt>
|
||||
VersionString (S)
|
||||
= <font color="#CC0000">alpha0.20</font></tt>
|
||||
<p><tt>
|
||||
<font color="#CC0000">/home/dp/dist/bin/components/libnfs-protocol.so</font></tt>
|
||||
<br><tt>
|
||||
ComponentsCount (Int) = <font color="#CC0000">1</font></tt>
|
||||
<br><tt>
|
||||
FileSize (Int)
|
||||
= <font color="#CC0000">78965</font></tt>
|
||||
<br><tt>
|
||||
LastModTimeStamp (S) = <font color="#CC0000">Wed
|
||||
Feb 24 11:24:06 PST 1999</font></tt>
|
||||
<p><tt><font color="#CC0000">
|
||||
</font><font color="#000000">Events</font></tt>
|
||||
<br><tt><font color="#000000">
|
||||
Startup</font></tt>
|
||||
<br><tt><font color="#000000">
|
||||
</font><font color="#CC0000">{108d75a0-bab5-11d2-96c4-0060b0fb9956}</font></tt>
|
||||
<br><tt><font color="#CC0000">
|
||||
{17894983-ab78-8d75-a0bb-511d296c4006}</font></tt>
|
||||
<p><tt><font color="#000000">
|
||||
Shutdown</font></tt>
|
||||
<br><tt><font color="#000000">
|
||||
</font><font color="#CC0000">{748958ea-abab-511d-296c-40060b0fb995}</font></tt>
|
||||
<br><tt><font color="#CC0000">
|
||||
{45617894-983a-b788-d75a-0bab11d296c4}</font></tt>
|
||||
<br> </blockquote>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="The Repository: Object instance creation"></a>The
|
||||
Repository: Object instance creation</h3>
|
||||
All object creation happens via The Repository. <tt>nsIRepository::CreateInstance()</tt>
|
||||
will be the primary way of creation of object instances. The steps in instantiation
|
||||
of an object that implements the IID interface and of class CLSID is as
|
||||
follows:
|
||||
<ol>
|
||||
<li>
|
||||
The CLSID of the component that would need to create the object instance
|
||||
is identified.</li>
|
||||
|
||||
<ol>Callers use <tt>nsIRepository::ProgIDToCLSID()</tt> to convert the
|
||||
ProgID string to the CLSID.</ol>
|
||||
|
||||
<li>
|
||||
Load the dll associated with the CLSID after consulting the Registry</li>
|
||||
|
||||
<li>
|
||||
Instantiate the class factory by calling a globally exported dll function
|
||||
<tt>NSGetFactory()</tt>.
|
||||
This returns an instance of the class factory that implements the <tt>nsIFactory</tt>
|
||||
interface.</li>
|
||||
|
||||
<li>
|
||||
The actual object creation is delegated to this <tt>nsIFactory</tt> instance
|
||||
with a call to <tt>nsIFactory::CreateInstance()</tt>.</li>
|
||||
</ol>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="The Service Manager"></a>The Service Manager</h3>
|
||||
All globally created system services are available via the <tt>nsIServiceManager</tt>,
|
||||
including the <tt>nsIRepository</tt> and <tt>nsIRegistry</tt>. Although
|
||||
the <tt>nsIServiceManager</tt> uses the Registry and Repository in the
|
||||
creation and maintenance of other services, the circular dependency is
|
||||
broken by not letting the <tt>nsIServiceManager</tt> create the <tt>nsIRepository</tt>
|
||||
and <tt>nsIRegistry</tt> instance and registering them specially with the
|
||||
<tt>nsIServiceManager</tt>.
|
||||
The nsIServiceManager is passed into NSGetFactory() for assisting the DLL
|
||||
in the Factory creation process.
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="Component Registration"></a>Component Registration</h3>
|
||||
Either at installation time of the Component or at times when the XPCOM
|
||||
library autodetect new/changed dlls, component registration is activated.
|
||||
The autodetection happens at startup time of the navigator or via a javascript
|
||||
trigger <tt>navigator.repository.autodetect()</tt>. The steps in component
|
||||
registration would be:
|
||||
<ol>
|
||||
<li>
|
||||
The dll is loaded</li>
|
||||
|
||||
<li>
|
||||
The component is allowed to self register by a call to a globally exported
|
||||
dll function <tt>NSRegisterSelf()</tt>. The <tt>nsIServiceManager</tt>
|
||||
and the fullpath of the dll are passed in to assist in the registration
|
||||
process. The dll is expected to create/modify its entries in the Registry
|
||||
according to the guidelines of the <a href="#The Registry: XPCOM Hierarchy">XPCOM
|
||||
hierarchy</a> in the registry. <tt>nsIRepository</tt>, which can be queried
|
||||
from the <tt>nsIServiceManager</tt>, has useful registration functions
|
||||
that would easen the process.</li>
|
||||
|
||||
<li>
|
||||
The dll is unloaded</li>
|
||||
</ol>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="Autodetection of Components"></a>Autodetection
|
||||
of Components</h3>
|
||||
Autodetection of changed dlls happened by storing the dll's last modified
|
||||
time and its size in the Registry automatically. If either the last modified
|
||||
time stamp or the filesize differs from that stored in the Registry for
|
||||
the dll, re-registration takes place. Before re-registration, the existing
|
||||
instances of the objects created by the classes in the dll are not freed
|
||||
because the <tt>nsIRepository</tt> has no list of them. The <tt>NSCanUnload()</tt>
|
||||
will be called with input parameter <i>force</i> set to <tt>true</tt>.
|
||||
The dll has to prepare for getting unloaded. After this call returns, the
|
||||
dll <b>will</b> be unloaded if the return value is <tt>true</tt>. If the
|
||||
dll detects that it cannot properly prepare for unloading, then it can
|
||||
return <tt>false</tt>. XPCOM will not let the re-registration of the modified
|
||||
dll proceed in this case. There is nothing much that XPCOM library can
|
||||
do to salvage this situation other than warning the user of possible instability
|
||||
and advice a restart upon which the re-registration will happen.
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="ProgID Spec"></a>ProgID Spec</h3>
|
||||
The general format of ProgIDs is <i><b><font color="#990000">component://</font></b>netscape<b><font color="#990000">/</font></b>compname<b><font color="#990000">?</font></b>var<b><font color="#990000">=</font></b>value<b><font color="#990000">;</font></b>var<b><font color="#990000">=</font></b>value<b><font color="#990000">;</font></b>var<b><font color="#990000">=</font></b>value...</i>
|
||||
<p>Let us consider some more examples:
|
||||
<ol>
|
||||
<li>
|
||||
A pluggable protocol that implementes the nfs protocol</li>
|
||||
|
||||
<li>
|
||||
A converter that can handle application/x-zip</li>
|
||||
|
||||
<li>
|
||||
A plugin that can handle image/gif</li>
|
||||
|
||||
<li>
|
||||
A widget that can do a toolbar</li>
|
||||
|
||||
<li>
|
||||
A datasource that can handle mail</li>
|
||||
|
||||
<li>
|
||||
A helperapp that deals with application/postscript</li>
|
||||
</ol>
|
||||
All the above have what type they are and one or more arguments on what
|
||||
they particularly do.
|
||||
<p>The ProgID for these would look like
|
||||
<ol>
|
||||
<li>
|
||||
<tt>component://netscape/network-protocol?type=nfs</tt></li>
|
||||
|
||||
<li>
|
||||
<tt>component://netscape/data-converter?type=application/x-zip</tt></li>
|
||||
|
||||
<li>
|
||||
<tt>component://netscape/plugin?type=image/gif;name=ImageMedia%20Gif%20Image%20Plugin;Description=Renders%20GIF%20Images....</tt></li>
|
||||
|
||||
<li>
|
||||
<tt>component://netscape/widget?type=toolbar</tt></li>
|
||||
|
||||
<li>
|
||||
<tt>component://netscape/rdf/datsource?type=mail</tt></li>
|
||||
|
||||
<li>
|
||||
<tt>component://netscape/helperapp?type=application/postscript</tt></li>
|
||||
</ol>
|
||||
{Assume proper escaping of all above URI}
|
||||
<p>The above semantics would let ProgID be an extensible mechanism that
|
||||
could be searched on multiple ways. And
|
||||
<br>query on a progid should match only whatever was passed in. So a query
|
||||
for
|
||||
<br>component://netscape/plugin?type=image/gif should pass for the progid
|
||||
specified above. We could extend this
|
||||
<br>mechanism with wildcards, but I dont want to go there yet... :-)
|
||||
<br>
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="Startup Components"></a>Components created on
|
||||
events</h3>
|
||||
<b><font color="#990000">NOTE: THIS IS NOT BEING DONE. We are going to
|
||||
expect the apps to this themselves by using the registry.</font></b>
|
||||
<p>Some dlls have components that want to be created on certain events
|
||||
namely Startup, Shutdown (for now). Example is xpinstall.
|
||||
<blockquote>RegisterComponentForEvent(..., RegisterationTime when, ...)
|
||||
<br>RegisterFactoryForEvent(..., RegistrationTime when,...)</blockquote>
|
||||
exists for this purpose. When an application wants to Fire the particular
|
||||
event, it calls
|
||||
<blockquote>nsComponentManager::FireEvent(RegistrationTime when)</blockquote>
|
||||
ComponentManager will look for components that are registered to be created
|
||||
on these events and do the following for each of the components:
|
||||
<ol>
|
||||
<li>
|
||||
CreateInstance(...,CID, knsIStartupComponentIID, &obj);</li>
|
||||
|
||||
<br>For a shutdown event, knsIShutdownComponentIID would be used.
|
||||
<br>
|
||||
<li>
|
||||
obj->Release();</li>
|
||||
|
||||
<br>The component needs to take adequate measures to keep itself alive
|
||||
and figure out how it would delete the object, since a Release() happens
|
||||
immediately after a CreateInstace()</ol>
|
||||
<b><i>Warning: </i></b>Order of creation of multiple components registered
|
||||
on the same event is not defined. Component dependencies aren't thought
|
||||
of yet.
|
||||
<br>
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="How will all this help me"></a>How will all this
|
||||
help me</h3>
|
||||
For Component Developers:
|
||||
<ul>
|
||||
<li>
|
||||
Component dlls developed could be dropped into a directory, a JS function
|
||||
called after which your component is in business without even a restart
|
||||
of the browser. Of course, there needs to be someone accessing it.</li>
|
||||
|
||||
<li>
|
||||
No need to export you CLSID or run around finding where to advertise your
|
||||
CLSID</li>
|
||||
</ul>
|
||||
For Component Users:
|
||||
<blockquote>
|
||||
<li>
|
||||
No more hacking in calls to <tt>nsIRepository::RegisterFactory()</tt></li>
|
||||
|
||||
<li>
|
||||
No need to know the CLSID of components that you want to instantiate. Component
|
||||
creation can happen like this</li>
|
||||
|
||||
<br><tt>nsIRepository::CreateInstance(<b>"<font color="#CC0000">component://netscape/network-protocol&type=nfs</font>"</b>,
|
||||
NULL, kProtocolIID, &result);</tt>
|
||||
<br>instead of
|
||||
<br><strike>nsIRepository::CreateInstance(NFS_PROTOCOL_CID, NULL, domIID,
|
||||
&result);</strike></blockquote>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="What has happened so far"></a>What has happened
|
||||
so far</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Autoregistration implemented to grovel for components from the current
|
||||
directory</li>
|
||||
|
||||
<li>
|
||||
nsRepository is a global object. Not nsIRepository exists.</li>
|
||||
|
||||
<li>
|
||||
nsRepository::ProgIDToCLSID() implemented</li>
|
||||
</ul>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="Changes to XPCOM happening"></a>Changes to XPCOM
|
||||
happening</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
API changes to get ProgID in entire registration process for factories
|
||||
and components</li>
|
||||
|
||||
<li>
|
||||
ProgID cache to improve performance of ProgID queries</li>
|
||||
|
||||
<li>
|
||||
Notion of Component dlls living in a <b>Components directory </b>and autoregistration
|
||||
will load/manage only these components. Other components that are linked
|
||||
in to the app need to call <tt>nsRepository::RegisterFactory()</tt> from
|
||||
the app. <b>To make this happen we need a list of these.</b></li>
|
||||
|
||||
<li>
|
||||
<b>nsRegistry:</b> Enabling the new nsRegistry developed by Bill Law <law@netscape.com></li>
|
||||
|
||||
<li>
|
||||
Service Manager and Repository: Merge them</li>
|
||||
|
||||
<li>
|
||||
Convenience function to createIntance(progid)</li>
|
||||
|
||||
<li>
|
||||
Base ProgID in the interface ID header file</li>
|
||||
</ul>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="What should I do"></a>What should I do</h3>
|
||||
|
||||
<ul><b><font color="#CC0000">Component Developers</font></b>
|
||||
<ul>
|
||||
<li>
|
||||
<font color="#000000">Implement <tt>NSRegisterSelf()</tt> for your component
|
||||
dlls. Sample implementation that perf</font> <a href="http://cvs-mirror.mozilla.org/webtools/lxr/source/modules/libpref/src/nsPref.cpp#608">http://cvs-mirror.mozilla.org/webtools/lxr/source/modules/libpref/src/nsPref.cpp#608</a></li>
|
||||
|
||||
<li>
|
||||
Use <tt>nsRepository::RegisterComponent()</tt> instead of <tt>nsRepository::RegisterFactory()</tt>
|
||||
if your component lives in a DLL</li>
|
||||
|
||||
<li>
|
||||
<b>Dont use static constructors in loadable components</b></li>
|
||||
</ul>
|
||||
|
||||
<p><br><b><font color="#CC0000">Component Users</font></b>
|
||||
<ul>
|
||||
<li>
|
||||
Create all your components using ProgID rather than CID</li>
|
||||
|
||||
<li>
|
||||
If you were thinking of managing creation of components yourself, think
|
||||
again. The repository may be already doing that.</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>
|
||||
|
||||
<hr WIDTH="100%"><a NAME="Issues"></a>Issues</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Need support for questions like:</li>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Enumerate all CLSIDs that implement a particular interface.</li>
|
||||
|
||||
<li>
|
||||
Let a particular CLSID be the preferable implementation for an interface.</li>
|
||||
|
||||
<br>I dont know how this a XPCOM component user could use it unless there
|
||||
could be a call like:
|
||||
<br><tt>nsIRepository::CreateInstance(<b>NULL</b>, NULL, nsWidgetIID, &result);</tt>
|
||||
<li>
|
||||
Enumerate all interfaces supported by a CLSID</li>
|
||||
</ol>
|
||||
|
||||
<li>
|
||||
Resolving naming conflicts between ProgID</li>
|
||||
|
||||
<li>
|
||||
Store component specific name-values under <tt>ROOTKEY_COMMON\\<i>component.class.version\\</i></tt></li>
|
||||
|
||||
<li>
|
||||
Add a registry entry under <tt>ROOTKEY_COMMON\\<i>component.class.version\\</i></tt>to
|
||||
indicate the willingness for a CLSID to behave as a Service.</li>
|
||||
|
||||
<li>
|
||||
Add quick registration support functions in <tt>nsIRepository</tt> for
|
||||
components to use.</li>
|
||||
|
||||
<li>
|
||||
Is the hierarchy <tt>ROOTKEY_COMMON\\<b>Classes</b>\\CLSID </tt>acceptable.</li>
|
||||
|
||||
<li>
|
||||
Should we have a nsIRepository. JS needs it so that they can reflect it
|
||||
in javascript. Remove &'s in the API.</li>
|
||||
</ul>
|
||||
|
||||
<hr WIDTH="100%">
|
||||
<br><i><font size=-1>Last Modified: 28 Jan 1998</font></i>
|
||||
<br><font size=-1><i>Feedback to: </i><a href="news:netscape.public.mozilla.xpcom">netscape.public.mozilla.xpcom</a></font>
|
||||
</body>
|
||||
</html>
|
||||
161
mozilla/xpcom/doc/xpcom_faq.html
Normal file
161
mozilla/xpcom/doc/xpcom_faq.html
Normal file
@@ -0,0 +1,161 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="pnunn">
|
||||
<meta name="GENERATOR" content="Mozilla/4.5 [en]C-NSCP (WinNT; U) [Netscape]">
|
||||
<title>xpCom FAQ</title>
|
||||
</head>
|
||||
<body>
|
||||
<b><font size=+3>XPCOM FAQ</font></b>
|
||||
<p>Get out your decoder rings kids!
|
||||
<p>Having a basic understanding of COM is only the first
|
||||
<br>step. To get CMonkey code to build and run,
|
||||
<br>you need to translate your COM ideas into Netscape
|
||||
<br>speak.
|
||||
<p>Feel free to add to this document or change incorrect info.
|
||||
<br>Hopefully more info and more examples will help new
|
||||
<br>people reach XPCOM nirvana more quickly.
|
||||
<p><b>To mentally translate XPCOM to COM.</b>
|
||||
<br>
|
||||
<table BORDER COLS=2 WIDTH="100%" >
|
||||
<tr>
|
||||
<td BGCOLOR="#CCCCCC"><b>vanilla COM</b></td>
|
||||
|
||||
<td BGCOLOR="#FFCCCC"><b>XPCOM</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#CCCCCC"> IUnknown</td>
|
||||
|
||||
<td BGCOLOR="#FFCCCC">nsISupports</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#CCCCCC">IClassFactory</td>
|
||||
|
||||
<td BGCOLOR="#FFCCCC">nsIFactory</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#CCCCCC">virtual void _stdcall</td>
|
||||
|
||||
<td BGCOLOR="#FFCCCC">NS_IMETHOD</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#CCCCCC">interface ID = IID</td>
|
||||
|
||||
<td BGCOLOR="#FFCCCC">nsID = nsIID = IID</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#CCCCCC">class ID = CLSID </td>
|
||||
|
||||
<td BGCOLOR="#FFCCCC">nsCID = CID</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>Not too difficult.
|
||||
<br>But wait. There's more.
|
||||
<br><b>-------------------------------------------</b>
|
||||
<p><b><font size=+1>Why don't those classes have AddRef?</font></b>
|
||||
<p>Actually, those classes do have AddRef. It is hidden
|
||||
<br>in a macro. There are alot of macros that are alot of help
|
||||
<br>once you know :
|
||||
<br> 1) They exist.
|
||||
<p> 2) Where they are defined. (They aren't always mnemonic
|
||||
or onomatipeic.
|
||||
<br>
|
||||
You might want to print them out.)
|
||||
<p> mozilla/xpcom/public/nsCom.h
|
||||
<br>
|
||||
mozilla/xpcom/public/nsISupports.h
|
||||
<p> 3)What they are
|
||||
<br>
|
||||
Here's a short list to give you an idea of what you've been missing.
|
||||
<br>
|
||||
The include files listed above are the real reference.
|
||||
<p> 4) A quick way to expand pesky macros:
|
||||
<br>
|
||||
For macros in foo.cpp, 'make foo.i'
|
||||
<p> This
|
||||
will pump the foo.cpp file through C preprocessing
|
||||
<br>
|
||||
and expand all the macros for you. The output can be
|
||||
<br>
|
||||
hard to read, but if you search for unique strings
|
||||
<br>
|
||||
in the area you aredebugging, you can navigate
|
||||
<br>
|
||||
the file pretty easily.
|
||||
<br>
|
||||
(thanks to hshaw@netscape.com)
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<table BORDER COLS=2 WIDTH="100%" BGCOLOR="#CCCCCC" >
|
||||
<tr>
|
||||
<td BGCOLOR="#FFCCCC"><b><font size=+1>Netscape MACRO</font></b></td>
|
||||
|
||||
<td><b><font size=+1>Expansion of macro</font></b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#FFCCCC">NSADDREF(factoryinstname)</td>
|
||||
|
||||
<td>Factory->AddRef();</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#FFCCCC">NS_IMETHOD</td>
|
||||
|
||||
<td>virtual nsresult __stdcall</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#FFCCCC">NS_INIT_REFCNT()</td>
|
||||
|
||||
<td>mRefCnt = 0</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#FFCCCC">NS_INIT_ISUPPORTS()</td>
|
||||
|
||||
<td>NS_INIT_REFCNT()</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td BGCOLOR="#FFCCCC">NS_DECL_ISUPPORTS</td>
|
||||
|
||||
<td>public:
|
||||
<br> NS_IMETHOD QueryInterface(REFNSIID
|
||||
aIID,
|
||||
<br>
|
||||
void** aInstancePtr);
|
||||
<br> NS_IMETHOD_(nsrefcnt)
|
||||
AddRef(void);
|
||||
<br> NS_IMETHOD_(nsrefcnt)
|
||||
Release(void);
|
||||
<br> protected:
|
||||
<br> nsrefcnt mRefCnt;</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> <font size=+1>Useful Links to COM Documents:</font>
|
||||
<p><a href="http://www.mozilla.org/projects/xpcom/">XPCOM Page</a>
|
||||
<br><a href="http://www.mozilla.org/projects/xpcom/nsCOMPtr.html">nsCOMPtr</a>
|
||||
<br><a href="http://warp.netscape.com/client/raptor/codingconventions.html">Coding
|
||||
Conventions</a>
|
||||
<br><a href="http://warp/client/bam/eng/howto.html">Getting BAMmed</a>
|
||||
<br><a href="http://warp/client/bam/eng/comdoc.html">How to COM</a>
|
||||
<br><a href="http://www.mozilla.org/docs/tplist/catFlow/modunote.htm">Modularization
|
||||
Techniques</a>
|
||||
<br><a href="http://www.mozilla.org/docs/tplist/catBuild/portable-cpp.html">C++
|
||||
Portability Guide</a>
|
||||
<br><a href="http://www.mozilla.org/newlayout/">NGLayout</a>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
||||
28
mozilla/xpcom/ds/MANIFEST
Normal file
28
mozilla/xpcom/ds/MANIFEST
Normal file
@@ -0,0 +1,28 @@
|
||||
nsBTree.h
|
||||
nsCRT.h
|
||||
nsDeque.h
|
||||
nsEnumeratorUtils.h
|
||||
nsHashtable.h
|
||||
nsIArena.h
|
||||
nsIAtom.h
|
||||
nsIBuffer.h
|
||||
nsIByteBuffer.h
|
||||
nsIObserverList.h
|
||||
nsIPageManager.h
|
||||
nsIProperties.h
|
||||
nsISimpleEnumerator.h
|
||||
nsISizeOfHandler.h
|
||||
nsIUnicharBuffer.h
|
||||
nsIVariant.h
|
||||
nsInt64.h
|
||||
nsQuickSort.h
|
||||
nsRBTree.h
|
||||
nsStr.h
|
||||
nsString.h
|
||||
nsString2.h
|
||||
nsTime.h
|
||||
nsUnitConversion.h
|
||||
nsVector.h
|
||||
nsVoidArray.h
|
||||
nsXPIDLString.h
|
||||
plvector.h
|
||||
5
mozilla/xpcom/ds/MANIFEST_IDL
Normal file
5
mozilla/xpcom/ds/MANIFEST_IDL
Normal file
@@ -0,0 +1,5 @@
|
||||
nsICollection.idl
|
||||
nsIEnumerator.idl
|
||||
nsIObserver.idl
|
||||
nsIObserverService.idl
|
||||
nsISupportsArray.idl
|
||||
117
mozilla/xpcom/ds/Makefile.in
Normal file
117
mozilla/xpcom/ds/Makefile.in
Normal file
@@ -0,0 +1,117 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
LIBRARY_NAME = xpcomds_s
|
||||
|
||||
MODULE = xpcom
|
||||
|
||||
XPIDL_MODULE = xpcom_ds
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsICollection.idl \
|
||||
nsIEnumerator.idl \
|
||||
nsIObserver.idl \
|
||||
nsIObserverService.idl \
|
||||
nsISupportsArray.idl \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsArena.cpp \
|
||||
nsAtomTable.cpp \
|
||||
nsBTree.cpp \
|
||||
nsBuffer.cpp \
|
||||
nsByteBuffer.cpp \
|
||||
nsCRT.cpp \
|
||||
nsConjoiningEnumerator.cpp \
|
||||
nsDeque.cpp \
|
||||
nsEmptyEnumerator.cpp \
|
||||
nsEnumeratorUtils.cpp \
|
||||
nsHashtable.cpp \
|
||||
nsObserver.cpp \
|
||||
nsObserverList.cpp \
|
||||
nsObserverService.cpp \
|
||||
nsPageMgr.cpp \
|
||||
nsProperties.cpp \
|
||||
nsQuickSort.cpp \
|
||||
nsRBTree.cpp \
|
||||
nsSizeOfHandler.cpp \
|
||||
nsStr.cpp \
|
||||
nsString.cpp \
|
||||
nsString2.cpp \
|
||||
nsSupportsArray.cpp \
|
||||
nsSupportsArrayEnumerator.cpp \
|
||||
nsUnicharBuffer.cpp \
|
||||
nsVariant.cpp \
|
||||
nsVoidArray.cpp \
|
||||
nsXPIDLString.cpp \
|
||||
plvector.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
nsBTree.h \
|
||||
nsCRT.h \
|
||||
nsDeque.h \
|
||||
nsEnumeratorUtils.h \
|
||||
nsHashtable.h \
|
||||
nsIArena.h \
|
||||
nsIAtom.h \
|
||||
nsIBuffer.h \
|
||||
nsIByteBuffer.h \
|
||||
nsIObserverList.h \
|
||||
nsIPageManager.h \
|
||||
nsIProperties.h \
|
||||
nsISimpleEnumerator.h \
|
||||
nsISizeOfHandler.h \
|
||||
nsIUnicharBuffer.h \
|
||||
nsIVariant.h \
|
||||
nsInt64.h \
|
||||
nsQuickSort.h \
|
||||
nsRBTree.h \
|
||||
nsStr.h \
|
||||
nsString.h \
|
||||
nsString2.h \
|
||||
nsTime.h \
|
||||
nsUnitConversion.h \
|
||||
nsVector.h \
|
||||
nsVoidArray.h \
|
||||
nsXPIDLString.h \
|
||||
plvector.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
DEFINES = -D_IMPL_NS_COM -D_IMPL_NS_BASE
|
||||
|
||||
REQUIRES = xpcom uconv unicharutil
|
||||
|
||||
MKSHLIB :=
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
override NO_SHARED_LIB=1
|
||||
override NO_STATIC_LIB=
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
896
mozilla/xpcom/ds/bufferRoutines.h
Normal file
896
mozilla/xpcom/ds/bufferRoutines.h
Normal file
@@ -0,0 +1,896 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/******************************************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
This file contains the workhorse copy and shift functions used in nsStrStruct.
|
||||
Ultimately, I plan to make the function pointers in this system available for
|
||||
use by external modules. They'll be able to install their own "handlers".
|
||||
Not so, today though.
|
||||
|
||||
*******************************************************************************************/
|
||||
|
||||
#ifndef _BUFFERROUTINES_H
|
||||
#define _BUFFERROUTINES_H
|
||||
|
||||
#include "nsCRT.h"
|
||||
|
||||
#ifndef RICKG_TESTBED
|
||||
#include "nsUnicharUtilCIID.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsICaseConversion.h"
|
||||
#endif
|
||||
|
||||
#define KSHIFTLEFT (0)
|
||||
#define KSHIFTRIGHT (1)
|
||||
|
||||
|
||||
inline PRUnichar GetUnicharAt(const char* aString,PRUint32 anIndex) {
|
||||
return ((PRUnichar*)aString)[anIndex];
|
||||
}
|
||||
|
||||
inline PRUnichar GetCharAt(const char* aString,PRUint32 anIndex) {
|
||||
return (PRUnichar)aString[anIndex];
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to shift the contents of a char buffer.
|
||||
// The functions are differentiated by shift direction and the underlying charsize.
|
||||
//
|
||||
|
||||
/**
|
||||
* This method shifts single byte characters left by a given amount from an given offset.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is a ptr to a cstring where left-shift is to be performed
|
||||
* @param aLength is the known length of aDest
|
||||
* @param anOffset is the index into aDest where shifting shall begin
|
||||
* @param aCount is the number of chars to be "cut"
|
||||
*/
|
||||
void ShiftCharsLeft(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
|
||||
PRUint32 theMax=aLength-anOffset;
|
||||
PRUint32 theLength=(theMax<aCount) ? theMax : aCount;
|
||||
|
||||
char* first= aDest+anOffset+aCount;
|
||||
char* last = aDest+aLength;
|
||||
char* to = aDest+anOffset;
|
||||
|
||||
//now loop over characters, shifting them left...
|
||||
while(first<=last) {
|
||||
*to=*first;
|
||||
to++;
|
||||
first++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method shifts single byte characters right by a given amount from an given offset.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is a ptr to a cstring where the shift is to be performed
|
||||
* @param aLength is the known length of aDest
|
||||
* @param anOffset is the index into aDest where shifting shall begin
|
||||
* @param aCount is the number of chars to be "inserted"
|
||||
*/
|
||||
void ShiftCharsRight(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
|
||||
char* last = aDest+aLength;
|
||||
char* first= aDest+anOffset-1;
|
||||
char* to = aDest+aLength+aCount;
|
||||
|
||||
//Copy rightmost chars, up to offset+theDelta...
|
||||
while(first<=last) {
|
||||
*to=*last;
|
||||
to--;
|
||||
last--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method shifts unicode characters by a given amount from an given offset.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is a ptr to a cstring where the shift is to be performed
|
||||
* @param aLength is the known length of aDest
|
||||
* @param anOffset is the index into aDest where shifting shall begin
|
||||
* @param aCount is the number of chars to be "cut"
|
||||
*/
|
||||
void ShiftDoubleCharsLeft(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
|
||||
PRUint32 theMax=aLength-anOffset;
|
||||
PRUint32 theLength=(theMax<aCount) ? theMax : aCount;
|
||||
|
||||
PRUnichar* theBuf=(PRUnichar*)aDest;
|
||||
PRUnichar* first= theBuf+anOffset+aCount;
|
||||
PRUnichar* last = theBuf+aLength;
|
||||
PRUnichar* to = theBuf+anOffset;
|
||||
|
||||
//now loop over characters, shifting them left...
|
||||
while(first<=last) {
|
||||
*to=*first;
|
||||
to++;
|
||||
first++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method shifts unicode characters by a given amount from an given offset.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is a ptr to a cstring where the shift is to be performed
|
||||
* @param aLength is the known length of aDest
|
||||
* @param anOffset is the index into aDest where shifting shall begin
|
||||
* @param aCount is the number of chars to be "inserted"
|
||||
*/
|
||||
void ShiftDoubleCharsRight(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
|
||||
PRUnichar* theBuf=(PRUnichar*)aDest;
|
||||
PRUnichar* last = theBuf+aLength;
|
||||
PRUnichar* first= theBuf+anOffset-1;
|
||||
PRUnichar* to = theBuf+aLength+aCount;
|
||||
|
||||
//Copy rightmost chars, up to offset+theDelta...
|
||||
while(first<=last) {
|
||||
*to=*last;
|
||||
to--;
|
||||
last--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef void (*ShiftChars)(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount);
|
||||
ShiftChars gShiftChars[2][2]= {
|
||||
{&ShiftCharsLeft,&ShiftCharsRight},
|
||||
{&ShiftDoubleCharsLeft,&ShiftDoubleCharsRight}
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to copy one buffer onto another.
|
||||
// The functions are differentiated by the size of source and dest character sizes.
|
||||
// WARNING: Your destination buffer MUST be big enough to hold all the source bytes.
|
||||
// We don't validate these ranges here (this should be done in higher level routines).
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* Going 1 to 1 is easy, since we assume ascii. No conversions are necessary.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the destination buffer
|
||||
* @param aDestOffset is the pos to start copy to in the dest buffer
|
||||
* @param aSource is the source buffer
|
||||
* @param anOffset is the offset to start copying from in the source buffer
|
||||
* @param aCount is the (max) number of chars to copy
|
||||
*/
|
||||
void CopyChars1To1(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
|
||||
|
||||
char* to = aDest+anDestOffset;
|
||||
const char* first= aSource+anOffset;
|
||||
const char* last = first+aCount;
|
||||
|
||||
//now loop over characters, shifting them left...
|
||||
while(first<last) {
|
||||
*to=*first;
|
||||
to++;
|
||||
first++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Going 1 to 2 requires a conversion from ascii to unicode. This can be expensive.
|
||||
* @param aDest is the destination buffer
|
||||
* @param aDestOffset is the pos to start copy to in the dest buffer
|
||||
* @param aSource is the source buffer
|
||||
* @param anOffset is the offset to start copying from in the source buffer
|
||||
* @param aCount is the (max) number of chars to copy
|
||||
*/
|
||||
void CopyChars1To2(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
|
||||
|
||||
PRUnichar* theDest=(PRUnichar*)aDest;
|
||||
PRUnichar* to = theDest+anDestOffset;
|
||||
const unsigned char* first= (const unsigned char*)aSource+anOffset;
|
||||
const unsigned char* last = first+aCount;
|
||||
|
||||
//now loop over characters, shifting them left...
|
||||
while(first<last) {
|
||||
*to=(PRUnichar)(*first);
|
||||
to++;
|
||||
first++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Going 2 to 1 requires a conversion from unicode down to ascii. This can be lossy.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the destination buffer
|
||||
* @param aDestOffset is the pos to start copy to in the dest buffer
|
||||
* @param aSource is the source buffer
|
||||
* @param anOffset is the offset to start copying from in the source buffer
|
||||
* @param aCount is the (max) number of chars to copy
|
||||
*/
|
||||
void CopyChars2To1(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
|
||||
char* to = aDest+anDestOffset;
|
||||
PRUnichar* theSource=(PRUnichar*)aSource;
|
||||
const PRUnichar* first= theSource+anOffset;
|
||||
const PRUnichar* last = first+aCount;
|
||||
|
||||
//now loop over characters, shifting them left...
|
||||
while(first<last) {
|
||||
if(*first<256)
|
||||
*to=(char)*first;
|
||||
else *to='.';
|
||||
to++;
|
||||
first++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Going 2 to 2 is fast and efficient.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the destination buffer
|
||||
* @param aDestOffset is the pos to start copy to in the dest buffer
|
||||
* @param aSource is the source buffer
|
||||
* @param anOffset is the offset to start copying from in the source buffer
|
||||
* @param aCount is the (max) number of chars to copy
|
||||
*/
|
||||
void CopyChars2To2(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
|
||||
PRUnichar* theDest=(PRUnichar*)aDest;
|
||||
PRUnichar* to = theDest+anDestOffset;
|
||||
PRUnichar* theSource=(PRUnichar*)aSource;
|
||||
PRUnichar* from= theSource+anOffset;
|
||||
|
||||
memcpy((void*)to,(void*)from,aCount*2);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
typedef void (*CopyChars)(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount);
|
||||
|
||||
CopyChars gCopyChars[2][2]={
|
||||
{&CopyChars1To1,&CopyChars1To2},
|
||||
{&CopyChars2To1,&CopyChars2To2}
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to search a buffer looking for a char.
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer for the given char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest is the buffer to be searched
|
||||
* @param aLength is the size (in char-units, not bytes) of the buffer
|
||||
* @param anOffset is the start pos to begin searching
|
||||
* @param aChar is the target character we're looking for
|
||||
* @param aIgnorecase tells us whether to use a case sensitive search
|
||||
* @return index of pos if found, else -1 (kNotFound)
|
||||
*/
|
||||
inline PRInt32 FindChar1(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
|
||||
PRUnichar theCmpChar=(aIgnoreCase ? nsCRT::ToUpper(aChar) : aChar);
|
||||
PRInt32 theIndex=0;
|
||||
PRInt32 theLength=(PRInt32)aLength;
|
||||
for(theIndex=(PRInt32)anOffset;theIndex<theLength;theIndex++){
|
||||
PRUnichar theChar=GetCharAt(aDest,theIndex);
|
||||
if(aIgnoreCase)
|
||||
theChar=nsCRT::ToUpper(theChar);
|
||||
if(theChar==theCmpChar)
|
||||
return theIndex;
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer for the given char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest is the buffer to be searched
|
||||
* @param aLength is the size (in char-units, not bytes) of the buffer
|
||||
* @param anOffset is the start pos to begin searching
|
||||
* @param aChar is the target character we're looking for
|
||||
* @param aIgnorecase tells us whether to use a case sensitive search
|
||||
* @return index of pos if found, else -1 (kNotFound)
|
||||
*/
|
||||
inline PRInt32 FindChar2(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
|
||||
PRUnichar theCmpChar=(aIgnoreCase ? nsCRT::ToUpper(aChar) : aChar);
|
||||
PRInt32 theIndex=0;
|
||||
PRInt32 theLength=(PRInt32)aLength;
|
||||
for(theIndex=(PRInt32)anOffset;theIndex<theLength;theIndex++){
|
||||
PRUnichar theChar=GetUnicharAt(aDest,theIndex);
|
||||
if(aIgnoreCase)
|
||||
theChar=nsCRT::ToUpper(theChar);
|
||||
if(theChar==theCmpChar)
|
||||
return theIndex;
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer (in reverse) for the given char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest is the buffer to be searched
|
||||
* @param aLength is the size (in char-units, not bytes) of the buffer
|
||||
* @param anOffset is the start pos to begin searching
|
||||
* @param aChar is the target character we're looking for
|
||||
* @param aIgnorecase tells us whether to use a case sensitive search
|
||||
* @return index of pos if found, else -1 (kNotFound)
|
||||
*/
|
||||
inline PRInt32 RFindChar1(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
|
||||
PRUnichar theCmpChar=(aIgnoreCase ? nsCRT::ToUpper(aChar) : aChar);
|
||||
PRInt32 theIndex=0;
|
||||
PRInt32 thePos=(PRInt32)aLength-anOffset-1;
|
||||
for(theIndex=thePos;theIndex>=0;theIndex--){
|
||||
PRUnichar theChar=GetCharAt(aDest,theIndex);
|
||||
if(aIgnoreCase)
|
||||
theChar=nsCRT::ToUpper(theChar);
|
||||
if(theChar==theCmpChar)
|
||||
return theIndex;
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer for the given char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest is the buffer to be searched
|
||||
* @param aLength is the size (in char-units, not bytes) of the buffer
|
||||
* @param anOffset is the start pos to begin searching
|
||||
* @param aChar is the target character we're looking for
|
||||
* @param aIgnorecase tells us whether to use a case sensitive search
|
||||
* @return index of pos if found, else -1 (kNotFound)
|
||||
*/
|
||||
inline PRInt32 RFindChar2(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
|
||||
PRUnichar theCmpChar=(aIgnoreCase ? nsCRT::ToUpper(aChar) : aChar);
|
||||
PRInt32 theIndex=0;
|
||||
PRInt32 thePos=(PRInt32)aLength-anOffset-1;
|
||||
for(theIndex=thePos;theIndex>=0;theIndex--){
|
||||
PRUnichar theChar=GetUnicharAt(aDest,theIndex);
|
||||
if(aIgnoreCase)
|
||||
theChar=nsCRT::ToUpper(theChar);
|
||||
if(theChar==theCmpChar)
|
||||
return theIndex;
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
typedef PRInt32 (*FindChars)(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase);
|
||||
FindChars gFindChars[]={&FindChar1,&FindChar2};
|
||||
FindChars gRFindChars[]={&RFindChar1,&RFindChar2};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to compare one buffer onto another.
|
||||
// The functions are differentiated by the size of source and dest character sizes.
|
||||
// WARNING: Your destination buffer MUST be big enough to hold all the source bytes.
|
||||
// We don't validate these ranges here (this should be done in higher level routines).
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* This method compares the data in one buffer with another
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
PRInt32 Compare1To1(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
|
||||
PRInt32 result=0;
|
||||
if(aIgnoreCase)
|
||||
result=nsCRT::strncasecmp(aStr1,aStr2,aCount);
|
||||
else result=strncmp(aStr1,aStr2,aCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method compares the data in one buffer with another
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
PRInt32 Compare2To2(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
|
||||
PRInt32 result=0;
|
||||
if(aIgnoreCase)
|
||||
result=nsCRT::strncasecmp((PRUnichar*)aStr1,(PRUnichar*)aStr2,aCount);
|
||||
else result=nsCRT::strncmp((PRUnichar*)aStr1,(PRUnichar*)aStr2,aCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method compares the data in one buffer with another
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
PRInt32 Compare2To1(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
|
||||
PRInt32 result;
|
||||
if(aIgnoreCase)
|
||||
result=nsCRT::strncasecmp((PRUnichar*)aStr1,aStr2,aCount);
|
||||
else result=nsCRT::strncmp((PRUnichar*)aStr1,aStr2,aCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method compares the data in one buffer with another
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
PRInt32 Compare1To2(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
|
||||
PRInt32 result;
|
||||
if(aIgnoreCase)
|
||||
result=nsCRT::strncasecmp((PRUnichar*)aStr2,aStr1,aCount)*-1;
|
||||
else result=nsCRT::strncmp((PRUnichar*)aStr2,aStr1,aCount)*-1;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
typedef PRInt32 (*CompareChars)(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase);
|
||||
CompareChars gCompare[2][2]={
|
||||
{&Compare1To1,&Compare1To2},
|
||||
{&Compare2To1,&Compare2To2},
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to convert the case of strings...
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* This method performs a case conversion the data in the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be case shifted
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aToUpper tells us whether to convert to upper or lower
|
||||
* @return 0
|
||||
*/
|
||||
PRInt32 ConvertCase1(char* aString,PRUint32 aCount,PRBool aToUpper){
|
||||
PRInt32 result=0;
|
||||
|
||||
typedef char chartype;
|
||||
chartype* cp = (chartype*)aString;
|
||||
chartype* end = cp + aCount-1;
|
||||
while (cp <= end) {
|
||||
chartype ch = *cp;
|
||||
if(aToUpper) {
|
||||
if ((ch >= 'a') && (ch <= 'z')) {
|
||||
*cp = 'A' + (ch - 'a');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((ch >= 'A') && (ch <= 'Z')) {
|
||||
*cp = 'a' + (ch - 'A');
|
||||
}
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef RICKG_TESTBED
|
||||
class HandleCaseConversionShutdown3 : public nsIShutdownListener {
|
||||
public :
|
||||
NS_IMETHOD OnShutdown(const nsCID& cid, nsISupports* service);
|
||||
HandleCaseConversionShutdown3(void) { NS_INIT_REFCNT(); }
|
||||
virtual ~HandleCaseConversionShutdown3(void) {}
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
|
||||
static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
|
||||
static NS_DEFINE_IID(kICaseConversionIID, NS_ICASECONVERSION_IID);
|
||||
static NS_DEFINE_IID(kIShutdownListenerIID, NS_ISHUTDOWNLISTENER_IID);
|
||||
static nsICaseConversion * gCaseConv = 0;
|
||||
|
||||
NS_IMPL_ISUPPORTS(HandleCaseConversionShutdown3, kIShutdownListenerIID);
|
||||
|
||||
nsresult HandleCaseConversionShutdown3::OnShutdown(const nsCID& cid, nsISupports* service) {
|
||||
if (cid.Equals(kUnicharUtilCID)) {
|
||||
NS_ASSERTION(service == gCaseConv, "wrong service!");
|
||||
if(gCaseConv){
|
||||
gCaseConv->Release();
|
||||
gCaseConv = 0;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
class CCaseConversionServiceInitializer {
|
||||
public:
|
||||
CCaseConversionServiceInitializer(){
|
||||
mListener = new HandleCaseConversionShutdown3();
|
||||
if(mListener){
|
||||
mListener->AddRef();
|
||||
nsresult result=nsServiceManager::GetService(kUnicharUtilCID, kICaseConversionIID,(nsISupports**) &gCaseConv, mListener);
|
||||
}
|
||||
}
|
||||
protected:
|
||||
HandleCaseConversionShutdown3* mListener;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* This method performs a case conversion the data in the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be case shifted
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aToUpper tells us whether to convert to upper or lower
|
||||
* @return 0
|
||||
*/
|
||||
PRInt32 ConvertCase2(char* aString,PRUint32 aCount,PRBool aToUpper){
|
||||
PRUnichar* cp = (PRUnichar*)aString;
|
||||
PRUnichar* end = cp + aCount-1;
|
||||
PRInt32 result=0;
|
||||
|
||||
#ifndef RICKG_TESTBED
|
||||
static CCaseConversionServiceInitializer gCaseConversionServiceInitializer;
|
||||
|
||||
// I18N code begin
|
||||
if(gCaseConv) {
|
||||
nsresult err=(aToUpper) ? gCaseConv->ToUpper(cp, cp, aCount) : gCaseConv->ToLower(cp, cp, aCount);
|
||||
if(NS_SUCCEEDED(err))
|
||||
return 0;
|
||||
}
|
||||
// I18N code end
|
||||
#endif
|
||||
|
||||
|
||||
while (cp <= end) {
|
||||
PRUnichar ch = *cp;
|
||||
if(aToUpper) {
|
||||
if ((ch >= 'a') && (ch <= 'z')) {
|
||||
*cp = 'A' + (ch - 'a');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((ch >= 'A') && (ch <= 'Z')) {
|
||||
*cp = 'a' + (ch - 'A');
|
||||
}
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef PRInt32 (*CaseConverters)(char*,PRUint32,PRBool);
|
||||
CaseConverters gCaseConverters[]={&ConvertCase1,&ConvertCase2};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used strip chars from a given buffer...
|
||||
//
|
||||
|
||||
/**
|
||||
* This method removes chars (given in aSet) from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param anOffset is starting pos in buffer for manipulation
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aSet tells us which chars to remove from given buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 StripChars1(char* aString,PRUint32 anOffset,PRUint32 aCount,const char* aSet){
|
||||
PRInt32 result=0;
|
||||
|
||||
typedef char chartype;
|
||||
chartype* from = (chartype*)&aString[anOffset];
|
||||
chartype* end = (chartype*)from + aCount-1;
|
||||
chartype* to = from;
|
||||
|
||||
if(aSet){
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
while (from <= end) {
|
||||
chartype ch = *from;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
*to++=*from;
|
||||
}
|
||||
from++;
|
||||
}
|
||||
*to = 0;
|
||||
}
|
||||
return to - (chartype*)aString;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method removes chars (given in aSet) from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param anOffset is starting pos in buffer for manipulation
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aSet tells us which chars to remove from given buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 StripChars2(char* aString,PRUint32 anOffset,PRUint32 aCount,const char* aSet){
|
||||
PRInt32 result=0;
|
||||
|
||||
typedef PRUnichar chartype;
|
||||
chartype* from = (chartype*)&aString[anOffset];
|
||||
chartype* end = (chartype*)from + aCount-1;
|
||||
chartype* to = from;
|
||||
|
||||
if(aSet){
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
while (from <= end) {
|
||||
chartype ch = *from;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
*to++=*from;
|
||||
}
|
||||
from++;
|
||||
}
|
||||
*to = 0;
|
||||
}
|
||||
return to - (chartype*)aString;
|
||||
}
|
||||
|
||||
typedef PRInt32 (*StripChars)(char* aString,PRUint32 aDestOffset,PRUint32 aCount,const char* aSet);
|
||||
StripChars gStripChars[]={&StripChars1,&StripChars2};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used trim chars from the edges of a buffer...
|
||||
//
|
||||
|
||||
/**
|
||||
* This method trims chars (given in aSet) from the edges of given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param aLength is the length of the buffer
|
||||
* @param aSet tells us which chars to remove from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 TrimChars1(char* aString,PRUint32 aLength,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing){
|
||||
PRInt32 result=0;
|
||||
|
||||
typedef char chartype;
|
||||
chartype* from = (chartype*)aString;
|
||||
chartype* end = from + aLength -1;
|
||||
chartype* to = from;
|
||||
|
||||
if(aSet) {
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
//begin by find the first char not in aTrimSet
|
||||
if(aEliminateLeading) {
|
||||
while (from <= end) {
|
||||
chartype ch = *from;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
break;
|
||||
}
|
||||
from++;
|
||||
}
|
||||
}
|
||||
//Now, find last char not in aTrimSet
|
||||
if(aEliminateTrailing) {
|
||||
while(from<=end) {
|
||||
chartype ch = *end;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
break;
|
||||
}
|
||||
end--;
|
||||
}
|
||||
}
|
||||
//now rewrite your string without unwanted
|
||||
//leading or trailing characters.
|
||||
if (from != to) {
|
||||
while (from <= end) {
|
||||
*to++ = *from++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
to = ++end;
|
||||
}
|
||||
|
||||
*to = 0;
|
||||
}
|
||||
return to - (chartype*)aString;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method trims chars (given in aSet) from the edges of given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param aLength is the length of the buffer
|
||||
* @param aSet tells us which chars to remove from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 TrimChars2(char* aString,PRUint32 aLength,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing){
|
||||
PRInt32 result=0;
|
||||
|
||||
typedef PRUnichar chartype;
|
||||
chartype* from = (chartype*)aString;
|
||||
chartype* end = from + aLength -1;
|
||||
chartype* to = from;
|
||||
|
||||
if(aSet) {
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
//begin by find the first char not in aTrimSet
|
||||
if(aEliminateLeading) {
|
||||
while (from <= end) {
|
||||
chartype ch = *from;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
break;
|
||||
}
|
||||
from++;
|
||||
}
|
||||
}
|
||||
//Now, find last char not in aTrimSet
|
||||
if(aEliminateTrailing) {
|
||||
while(from<=end) {
|
||||
chartype ch = *end;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
break;
|
||||
}
|
||||
end--;
|
||||
}
|
||||
}
|
||||
//now rewrite your string without unwanted
|
||||
//leading or trailing characters.
|
||||
if (from != to) {
|
||||
while (from <= end) {
|
||||
*to++ = *from++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
to = ++end;
|
||||
}
|
||||
|
||||
*to = 0;
|
||||
}
|
||||
return to - (chartype*)aString;
|
||||
}
|
||||
|
||||
typedef PRInt32 (*TrimChars)(char* aString,PRUint32 aCount,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing);
|
||||
TrimChars gTrimChars[]={&TrimChars1,&TrimChars2};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used compress char sequences in a buffer...
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* This method compresses duplicate runs of a given char from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param aLength is the length of the buffer
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 CompressChars1(char* aString,PRUint32 aLength,const char* aSet,PRUint32 aChar,PRBool aEliminateLeading,PRBool aEliminateTrailing){
|
||||
PRInt32 result=0;
|
||||
|
||||
TrimChars1(aString,aLength,aSet,aEliminateLeading,aEliminateTrailing);
|
||||
|
||||
typedef char chartype;
|
||||
chartype* from = aString;
|
||||
chartype* end = aString + aLength-1;
|
||||
chartype* to = from;
|
||||
|
||||
//this code converts /n, /t, /r into normal space ' ';
|
||||
//it also compresses runs of whitespace down to a single char...
|
||||
if(aSet){
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
while (from <= end) {
|
||||
chartype ch = *from++;
|
||||
if(kNotFound!=FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
*to++ = (char)aChar;
|
||||
while (from <= end) {
|
||||
ch = *from++;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
*to++ = ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*to++ = ch;
|
||||
}
|
||||
}
|
||||
*to = 0;
|
||||
}
|
||||
return to - (chartype*)aString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method compresses duplicate runs of a given char from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param aLength is the length of the buffer
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 CompressChars2(char* aString,PRUint32 aLength,const char* aSet,PRUint32 aChar,PRBool aEliminateLeading,PRBool aEliminateTrailing){
|
||||
PRInt32 result=0;
|
||||
|
||||
TrimChars2(aString,aLength,aSet,aEliminateLeading,aEliminateTrailing);
|
||||
|
||||
typedef PRUnichar chartype;
|
||||
chartype* from = (chartype*)aString;
|
||||
chartype* end = from + aLength-1;
|
||||
chartype* to = from;
|
||||
|
||||
//this code converts /n, /t, /r into normal space ' ';
|
||||
//it also compresses runs of whitespace down to a single char...
|
||||
if(aSet){
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
while (from <= end) {
|
||||
chartype ch = *from++;
|
||||
if(kNotFound!=FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
*to++ = (PRUnichar)aChar;
|
||||
while (from <= end) {
|
||||
ch = *from++;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
*to++ = ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*to++ = ch;
|
||||
}
|
||||
}
|
||||
*to = 0;
|
||||
}
|
||||
return to - (chartype*)aString;
|
||||
}
|
||||
|
||||
typedef PRInt32 (*CompressChars)(char* aString,PRUint32 aCount,const char* aSet,PRUint32 aChar,PRBool aEliminateLeading,PRBool aEliminateTrailing);
|
||||
CompressChars gCompressChars[]={&CompressChars1,&CompressChars2};
|
||||
|
||||
|
||||
#endif
|
||||
118
mozilla/xpcom/ds/makefile.win
Normal file
118
mozilla/xpcom/ds/makefile.win
Normal file
@@ -0,0 +1,118 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
DEPTH=..\..
|
||||
MODULE = xpcom
|
||||
|
||||
################################################################################
|
||||
## exports
|
||||
|
||||
EXPORTS = \
|
||||
nsBTree.h \
|
||||
nsCRT.h \
|
||||
nsDeque.h \
|
||||
nsEnumeratorUtils.h \
|
||||
nsHashtable.h \
|
||||
nsIArena.h \
|
||||
nsIAtom.h \
|
||||
nsIBuffer.h \
|
||||
nsIByteBuffer.h \
|
||||
nsIObserverList.h \
|
||||
nsIPageManager.h \
|
||||
nsIProperties.h \
|
||||
nsISimpleEnumerator.h \
|
||||
nsISizeOfHandler.h \
|
||||
nsIUnicharBuffer.h \
|
||||
nsIVariant.h \
|
||||
nsInt64.h \
|
||||
nsQuickSort.h \
|
||||
nsRBTree.h \
|
||||
nsStr.h \
|
||||
nsString.h \
|
||||
nsString2.h \
|
||||
nsTime.h \
|
||||
nsUnitConversion.h \
|
||||
nsVector.h \
|
||||
nsVoidArray.h \
|
||||
nsXPIDLString.h \
|
||||
plvector.h \
|
||||
$(NULL)
|
||||
|
||||
XPIDL_MODULE = xpcom_ds
|
||||
|
||||
XPIDLSRCS = \
|
||||
.\nsICollection.idl \
|
||||
.\nsIEnumerator.idl \
|
||||
.\nsIObserver.idl \
|
||||
.\nsIObserverService.idl \
|
||||
.\nsISupportsArray.idl \
|
||||
$(NULL)
|
||||
|
||||
################################################################################
|
||||
## library
|
||||
|
||||
LIBRARY_NAME=xpcomds_s
|
||||
|
||||
LINCS = \
|
||||
-I$(PUBLIC)\xpcom \
|
||||
-I$(PUBLIC)\uconv \
|
||||
-I$(PUBLIC)\unicharutil \
|
||||
$(NULL)
|
||||
|
||||
LCFLAGS = -D_IMPL_NS_COM -D_IMPL_NS_BASE -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
CPP_OBJS = \
|
||||
.\$(OBJDIR)\nsArena.obj \
|
||||
.\$(OBJDIR)\nsAtomTable.obj \
|
||||
.\$(OBJDIR)\nsBTree.obj \
|
||||
.\$(OBJDIR)\nsBuffer.obj \
|
||||
.\$(OBJDIR)\nsByteBuffer.obj \
|
||||
.\$(OBJDIR)\nsCRT.obj \
|
||||
.\$(OBJDIR)\nsConjoiningEnumerator.obj \
|
||||
.\$(OBJDIR)\nsDeque.obj \
|
||||
.\$(OBJDIR)\nsEmptyEnumerator.obj \
|
||||
.\$(OBJDIR)\nsEnumeratorUtils.obj \
|
||||
.\$(OBJDIR)\nsHashtable.obj \
|
||||
.\$(OBJDIR)\nsObserver.obj \
|
||||
.\$(OBJDIR)\nsObserverList.obj \
|
||||
.\$(OBJDIR)\nsObserverService.obj \
|
||||
.\$(OBJDIR)\nsPageMgr.obj \
|
||||
.\$(OBJDIR)\nsProperties.obj \
|
||||
.\$(OBJDIR)\nsQuickSort.obj \
|
||||
.\$(OBJDIR)\nsRBTree.obj \
|
||||
.\$(OBJDIR)\nsSizeOfHandler.obj \
|
||||
.\$(OBJDIR)\nsStr.obj \
|
||||
.\$(OBJDIR)\nsString.obj \
|
||||
.\$(OBJDIR)\nsString2.obj \
|
||||
.\$(OBJDIR)\nsSupportsArray.obj \
|
||||
.\$(OBJDIR)\nsSupportsArrayEnumerator.obj \
|
||||
.\$(OBJDIR)\nsUnicharBuffer.obj \
|
||||
.\$(OBJDIR)\nsVariant.obj \
|
||||
.\$(OBJDIR)\nsVoidArray.obj \
|
||||
.\$(OBJDIR)\nsXPIDLString.obj \
|
||||
.\$(OBJDIR)\plvector.obj \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
libs:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
86
mozilla/xpcom/ds/nsArena.cpp
Normal file
86
mozilla/xpcom/ds/nsArena.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsArena.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
NS_IMETHODIMP
|
||||
ArenaImpl::Init(PRUint32 aBlockSize)
|
||||
{
|
||||
if (aBlockSize < NS_MIN_ARENA_BLOCK_SIZE) {
|
||||
aBlockSize = NS_DEFAULT_ARENA_BLOCK_SIZE;
|
||||
}
|
||||
PL_INIT_ARENA_POOL(&mPool, "nsIArena", aBlockSize);
|
||||
mBlockSize = aBlockSize;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(ArenaImpl, nsIArena::GetIID())
|
||||
|
||||
ArenaImpl::~ArenaImpl()
|
||||
{
|
||||
PL_FinishArenaPool(&mPool);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void*)
|
||||
ArenaImpl::Alloc(PRUint32 size)
|
||||
{
|
||||
// Adjust size so that it's a multiple of sizeof(double)
|
||||
PRUint32 align = size & (sizeof(double) - 1);
|
||||
if (0 != align) {
|
||||
size += sizeof(double) - align;
|
||||
}
|
||||
|
||||
void* p;
|
||||
PL_ARENA_ALLOCATE(p, &mPool, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
ArenaImpl::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
ArenaImpl* it = new ArenaImpl();
|
||||
if (nsnull == it)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(it);
|
||||
nsresult rv = it->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(it);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_COM nsresult NS_NewHeapArena(nsIArena** aInstancePtrResult,
|
||||
PRUint32 aArenaBlockSize)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIArena* arena;
|
||||
rv = ArenaImpl::Create(NULL, nsIArena::GetIID(), (void**)&arena);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = arena->Init(aArenaBlockSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(arena);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*aInstancePtrResult = arena;
|
||||
return rv;
|
||||
}
|
||||
47
mozilla/xpcom/ds/nsArena.h
Normal file
47
mozilla/xpcom/ds/nsArena.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsArena_h__
|
||||
#define nsArena_h__
|
||||
|
||||
#include "nsIArena.h"
|
||||
|
||||
#define PL_ARENA_CONST_ALIGN_MASK 7
|
||||
#include "plarena.h"
|
||||
|
||||
// Simple arena implementation layered on plarena
|
||||
class ArenaImpl : public nsIArena {
|
||||
public:
|
||||
ArenaImpl(void) { NS_INIT_REFCNT(); }
|
||||
virtual ~ArenaImpl();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
NS_IMETHOD Init(PRUint32 arenaBlockSize);
|
||||
|
||||
NS_IMETHOD_(void*) Alloc(PRUint32 size);
|
||||
|
||||
protected:
|
||||
PLArenaPool mPool;
|
||||
PRUint32 mBlockSize;
|
||||
};
|
||||
|
||||
#endif // nsArena_h__
|
||||
135
mozilla/xpcom/ds/nsAtomTable.cpp
Normal file
135
mozilla/xpcom/ds/nsAtomTable.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsAtomTable.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCRT.h"
|
||||
#include "plhash.h"
|
||||
#include "nsISizeOfHandler.h"
|
||||
|
||||
/**
|
||||
* The shared hash table for atom lookups.
|
||||
*/
|
||||
static nsrefcnt gAtoms;
|
||||
static struct PLHashTable* gAtomHashTable;
|
||||
|
||||
AtomImpl::AtomImpl()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
// Every live atom holds a reference on the atom hashtable
|
||||
gAtoms++;
|
||||
}
|
||||
|
||||
AtomImpl::~AtomImpl()
|
||||
{
|
||||
NS_PRECONDITION(nsnull != gAtomHashTable, "null atom hashtable");
|
||||
if (nsnull != gAtomHashTable) {
|
||||
PL_HashTableRemove(gAtomHashTable, mString);
|
||||
nsrefcnt cnt = --gAtoms;
|
||||
if (0 == cnt) {
|
||||
// When the last atom is destroyed, the atom arena is destroyed
|
||||
NS_ASSERTION(0 == gAtomHashTable->nentries, "bad atom table");
|
||||
PL_HashTableDestroy(gAtomHashTable);
|
||||
gAtomHashTable = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static NS_DEFINE_IID(kIAtomIID, NS_IATOM_IID);
|
||||
NS_IMPL_ISUPPORTS(AtomImpl, kIAtomIID);
|
||||
|
||||
void* AtomImpl::operator new(size_t size, const PRUnichar* us, PRInt32 uslen)
|
||||
{
|
||||
size = size + uslen * sizeof(PRUnichar);
|
||||
AtomImpl* ii = (AtomImpl*) ::operator new(size);
|
||||
nsCRT::memcpy(ii->mString, us, uslen * sizeof(PRUnichar));
|
||||
ii->mString[uslen] = 0;
|
||||
return ii;
|
||||
}
|
||||
|
||||
void AtomImpl::ToString(nsString& aBuf) const
|
||||
{
|
||||
aBuf.SetLength(0);
|
||||
aBuf.Append(mString, nsCRT::strlen(mString));
|
||||
}
|
||||
|
||||
const PRUnichar* AtomImpl::GetUnicode() const
|
||||
{
|
||||
return mString;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AtomImpl::SizeOf(nsISizeOfHandler* aHandler) const
|
||||
{
|
||||
aHandler->Add(sizeof(*this) + nsCRT::strlen(mString) * sizeof(PRUnichar));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
static PLHashNumber HashKey(const PRUnichar* k)
|
||||
{
|
||||
return (PLHashNumber) nsCRT::HashValue(k);
|
||||
}
|
||||
|
||||
static PRIntn CompareKeys(const PRUnichar* k1, const PRUnichar* k2)
|
||||
{
|
||||
return nsCRT::strcmp(k1, k2) == 0;
|
||||
}
|
||||
|
||||
NS_COM nsIAtom* NS_NewAtom(const char* isolatin1)
|
||||
{
|
||||
nsAutoString tmp(isolatin1);
|
||||
return NS_NewAtom(tmp.GetUnicode());
|
||||
}
|
||||
|
||||
NS_COM nsIAtom* NS_NewAtom(const nsString& aString)
|
||||
{
|
||||
return NS_NewAtom(aString.GetUnicode());
|
||||
}
|
||||
|
||||
NS_COM nsIAtom* NS_NewAtom(const PRUnichar* us)
|
||||
{
|
||||
if (nsnull == gAtomHashTable) {
|
||||
gAtomHashTable = PL_NewHashTable(8, (PLHashFunction) HashKey,
|
||||
(PLHashComparator) CompareKeys,
|
||||
(PLHashComparator) nsnull,
|
||||
nsnull, nsnull);
|
||||
}
|
||||
PRUint32 uslen;
|
||||
PRUint32 hashCode = nsCRT::HashValue(us, &uslen);
|
||||
PLHashEntry** hep = PL_HashTableRawLookup(gAtomHashTable, hashCode, us);
|
||||
PLHashEntry* he = *hep;
|
||||
if (nsnull != he) {
|
||||
nsIAtom* id = (nsIAtom*) he->value;
|
||||
NS_ADDREF(id);
|
||||
return id;
|
||||
}
|
||||
AtomImpl* id = new(us, uslen) AtomImpl();
|
||||
PL_HashTableRawAdd(gAtomHashTable, hep, hashCode, id->mString, id);
|
||||
NS_ADDREF(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
NS_COM nsrefcnt NS_GetNumberOfAtoms(void)
|
||||
{
|
||||
if (nsnull != gAtomHashTable) {
|
||||
NS_PRECONDITION(nsrefcnt(gAtomHashTable->nentries) == gAtoms, "bad atom table");
|
||||
}
|
||||
return gAtoms;
|
||||
}
|
||||
48
mozilla/xpcom/ds/nsAtomTable.h
Normal file
48
mozilla/xpcom/ds/nsAtomTable.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsAtomTable_h__
|
||||
#define nsAtomTable_h__
|
||||
|
||||
#include "nsIAtom.h"
|
||||
|
||||
class AtomImpl : public nsIAtom {
|
||||
public:
|
||||
AtomImpl();
|
||||
virtual ~AtomImpl();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
void* operator new(size_t size, const PRUnichar* us, PRInt32 uslen);
|
||||
|
||||
void operator delete(void* ptr) {
|
||||
::operator delete(ptr);
|
||||
}
|
||||
|
||||
virtual void ToString(nsString& aBuf) const;
|
||||
|
||||
virtual const PRUnichar* GetUnicode() const;
|
||||
|
||||
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const;
|
||||
|
||||
// Actually more; 0 terminated. This slot is reserved for the
|
||||
// terminating zero.
|
||||
PRUnichar mString[1];
|
||||
};
|
||||
|
||||
#endif // nsAtomTable_h__
|
||||
402
mozilla/xpcom/ds/nsBTree.cpp
Normal file
402
mozilla/xpcom/ds/nsBTree.cpp
Normal file
@@ -0,0 +1,402 @@
|
||||
|
||||
/**
|
||||
* This file defines the binary tree class and it
|
||||
* nsNode child class.
|
||||
*
|
||||
* This simple version stores nodes, and the
|
||||
* nodes store void* ptrs.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
||||
#include "nsBTree.h"
|
||||
|
||||
/**
|
||||
* default constructor
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
*/
|
||||
nsNode::nsNode(){
|
||||
mLeft=0;
|
||||
mRight=0;
|
||||
mParent=0;
|
||||
mColor=eBlack;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsNode::nsNode(const nsNode& aNode){
|
||||
mLeft=aNode.mLeft;
|
||||
mRight=aNode.mRight;
|
||||
mParent=aNode.mParent;
|
||||
mColor=aNode.mColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* destructor
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
*/
|
||||
nsNode::~nsNode(){
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive ptr to parent node
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @return ptr to parent node
|
||||
*/
|
||||
nsNode* nsNode::GetParentNode(void) const{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve ptr to left (less) node
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @return ptr to left (may be NULL)
|
||||
*/
|
||||
nsNode* nsNode::GetLeftNode(void) const{
|
||||
return mLeft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve ptr to right (more) node
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @return ptr to right node (may be NULL)
|
||||
*/
|
||||
nsNode* nsNode::GetRightNode(void) const{
|
||||
return mRight;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsNode& nsNode::operator=(const nsNode& aNode){
|
||||
if(this!=&aNode){
|
||||
mLeft=aNode.mLeft;
|
||||
mRight=aNode.mRight;
|
||||
mParent=aNode.mParent;
|
||||
mColor=aNode.mColor;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* Here comes the BTREE class...
|
||||
********************************************************/
|
||||
|
||||
/**
|
||||
* nsBTree constructor
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
*/
|
||||
nsBTree::nsBTree(){
|
||||
mRoot=0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* destructor
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
*/
|
||||
nsBTree::~nsBTree(){
|
||||
if(mRoot){
|
||||
//walk the tree and destroy the children.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a node, we're supposed to add it into
|
||||
* our tree.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param aNode to be added to tree
|
||||
* @return ptr to added node or NULL
|
||||
*/
|
||||
nsNode* nsBTree::Add(nsNode& aNode){
|
||||
|
||||
nsNode* node1=mRoot; //x
|
||||
nsNode* node2=0; //y
|
||||
while(node1) {
|
||||
node2=node1;
|
||||
if(aNode<*node1)
|
||||
node1=node1->mLeft;
|
||||
else node1=node1->mRight;
|
||||
}
|
||||
aNode.mParent=node2;
|
||||
if(!node2){
|
||||
mRoot=&aNode;
|
||||
}
|
||||
else{
|
||||
if(aNode<*node2)
|
||||
node2->mLeft=&aNode;
|
||||
else node2->mRight=&aNode;
|
||||
}
|
||||
|
||||
return &aNode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes given node from tree if present.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param aNode to be found and removed
|
||||
* @return ptr to remove node, or NULL
|
||||
*/
|
||||
nsNode* nsBTree::Remove(nsNode& aNode){
|
||||
nsNode* result=0;
|
||||
nsNode* node3=Find(aNode);
|
||||
|
||||
if(node3) {
|
||||
nsNode* node1;
|
||||
nsNode* node2;
|
||||
|
||||
if((!node3->mLeft) || (!node3->mRight))
|
||||
node2=node3;
|
||||
else node2=After(*node3);
|
||||
|
||||
if(node2->mLeft)
|
||||
node1=node2->mLeft;
|
||||
else node1=node2->mRight;
|
||||
|
||||
if(node1)
|
||||
node1->mParent=node2->mParent;
|
||||
|
||||
if(node2->mParent) {
|
||||
if(node2==node2->mParent->mLeft)
|
||||
node2->mParent->mLeft=node1;
|
||||
else node2->mParent->mRight=node1;
|
||||
}
|
||||
else mRoot=node1;
|
||||
|
||||
if(node2!=node3)
|
||||
(*node3)==(*node2);
|
||||
|
||||
if(node2->mColor == nsNode::eBlack)
|
||||
ReBalance(*node1);
|
||||
|
||||
delete node2;
|
||||
result=&aNode;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the tree of any data.
|
||||
* Be careful here if your objects are heap based!
|
||||
* This method doesn't free the objects, so if you
|
||||
* don't have your own pointers, they will become
|
||||
* orphaned.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return this
|
||||
*/
|
||||
nsBTree& nsBTree::Empty(nsNode* aNode) {
|
||||
mRoot=0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method destroys all the objects in the tree.
|
||||
* WARNING: Never call this method on stored objects
|
||||
* that are stack-based!
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return this
|
||||
*/
|
||||
nsBTree& nsBTree::Erase(nsNode* aNode){
|
||||
// nsNode* node1 =(aNode) ? aNode : mRoot;
|
||||
|
||||
if(aNode) {
|
||||
Erase(aNode->mLeft); //begin by walking left side
|
||||
Erase(aNode->mRight); //then search right side
|
||||
delete aNode; //until a leaf, then delete
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve ptr to first node in tree
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @return
|
||||
*/
|
||||
nsNode* nsBTree::First(void) const{
|
||||
if(mRoot)
|
||||
return First(*mRoot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive ptr to first node rel to given node
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param node to begin scan from
|
||||
* @return ptr to first node from given node or NULL
|
||||
*/
|
||||
nsNode* nsBTree::First(const nsNode& aNode) const{
|
||||
nsNode* result=0;
|
||||
|
||||
if(mRoot) {
|
||||
result=mRoot;
|
||||
while(result->GetLeftNode()) {
|
||||
result=result->GetLeftNode();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive ptr to last node
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @return ptr to last node rel to root or NULL
|
||||
*/
|
||||
nsNode* nsBTree::Last(void) const{
|
||||
if(mRoot)
|
||||
return Last(*mRoot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive ptr to last node rel to given node
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param node to begin scan from
|
||||
* @return ptr to first node from given node or NULL
|
||||
*/
|
||||
nsNode* nsBTree::Last(const nsNode& aNode) const{
|
||||
nsNode* result=0;
|
||||
|
||||
if(mRoot) {
|
||||
result=mRoot;
|
||||
while(result->GetRightNode()) {
|
||||
result=result->GetRightNode();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrive ptr to prior node rel to given node
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param node to begin scan from
|
||||
* @return ptr to prior node from given node or NULL
|
||||
*/
|
||||
nsNode* nsBTree::Before(const nsNode& aNode) const{
|
||||
|
||||
if(aNode.GetLeftNode())
|
||||
return Last(*aNode.GetLeftNode());
|
||||
|
||||
//otherwise...
|
||||
|
||||
nsNode* node1=(nsNode*)&aNode;
|
||||
nsNode* node2=aNode.GetParentNode();
|
||||
|
||||
while((node2) && (node1==node2->GetLeftNode())) {
|
||||
node1=node2;
|
||||
node2=node2->GetParentNode();
|
||||
}
|
||||
return node2;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrive ptr to next node rel to given node
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param node to begin scan from
|
||||
* @return ptr to next node from given node or NULL
|
||||
*/
|
||||
nsNode* nsBTree::After(const nsNode& aNode) const{
|
||||
|
||||
if(aNode.GetRightNode())
|
||||
return First(*aNode.GetRightNode());
|
||||
|
||||
//otherwise...
|
||||
|
||||
nsNode* node1=(nsNode*)&aNode;
|
||||
nsNode* node2=aNode.GetParentNode();
|
||||
|
||||
while((node2) && (node1==node2->GetRightNode())) {
|
||||
node1=node2;
|
||||
node2=node2->GetParentNode();
|
||||
}
|
||||
|
||||
return node2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan for given node
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param node to find
|
||||
* @return ptr to given node, or NULL
|
||||
*/
|
||||
nsNode* nsBTree::Find(const nsNode& aNode) const{
|
||||
nsNode* result=mRoot;
|
||||
|
||||
while((result) && (!(aNode==(*result)))) {
|
||||
if(aNode<*result)
|
||||
result=result->mLeft;
|
||||
else result=result->mRight;
|
||||
}
|
||||
return (nsNode*)result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebalances tree around the given node. This only
|
||||
* needs to be called after a node is deleted.
|
||||
* This method does nothing for btrees, but is
|
||||
* needed for RBTrees.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param aNode -- node to balance around
|
||||
* @return this
|
||||
*/
|
||||
nsBTree& nsBTree::ReBalance(nsNode& aNode){
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
const nsBTree& nsBTree::ForEach(nsNodeFunctor& aFunctor,nsNode* aNode) const{
|
||||
nsNode* node1 =(aNode) ? aNode : mRoot;
|
||||
|
||||
if(node1) {
|
||||
if(node1->mLeft)
|
||||
ForEach(aFunctor,node1->mLeft); //begin by walking left side
|
||||
aFunctor(*node1);
|
||||
if(node1->mRight)
|
||||
ForEach(aFunctor,node1->mRight); //then search right side
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
283
mozilla/xpcom/ds/nsBTree.h
Normal file
283
mozilla/xpcom/ds/nsBTree.h
Normal file
@@ -0,0 +1,283 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file defines the binary tree class and it
|
||||
* nsNode child class. Note that like all nsBTree
|
||||
* containers, this one does not automatically balance.
|
||||
* (Find for random data, bad for pre-ordered data).
|
||||
*
|
||||
* This simple version stores nodes, and the
|
||||
* nodes store void* ptrs.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* nsNode
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
||||
#ifndef _BTREE_H
|
||||
#define _BTREE_H
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
struct NS_COM nsNode {
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess4/20/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsNode();
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
* @update gess 4/11/98
|
||||
*/
|
||||
nsNode(const nsNode& aNode);
|
||||
|
||||
/**
|
||||
* destructor
|
||||
* @update gess 4/11/98
|
||||
*/
|
||||
virtual ~nsNode();
|
||||
|
||||
/**
|
||||
* Retrieve parent node
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @return
|
||||
*/
|
||||
nsNode* GetParentNode(void) const;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsNode* GetLeftNode() const;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsNode* GetRightNode() const;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual nsNode& operator=(const nsNode& aNode);
|
||||
|
||||
|
||||
/**
|
||||
* This method gets called to determine which of
|
||||
* two nodes is less. When you create your own
|
||||
* subclass of nsNode, this is the most important
|
||||
* method for you to overload.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual PRBool operator<(const nsNode& aNode) const=0;
|
||||
|
||||
/**
|
||||
* This method gets called to determine which of
|
||||
* two nodes is less. When you create your own
|
||||
* subclass of nsNode, this is the most important
|
||||
* method for you to overload.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual PRBool operator==(const nsNode& aNode) const=0;
|
||||
|
||||
enum eRBColor {eRed,eBlack};
|
||||
|
||||
nsNode* mParent;
|
||||
nsNode* mLeft;
|
||||
nsNode* mRight;
|
||||
eRBColor mColor;
|
||||
};
|
||||
|
||||
/**
|
||||
* The Nodefunctor class is used when you want to create
|
||||
* callbacks between the nsRBTree and your generic code.
|
||||
*
|
||||
* @update gess4/20/98
|
||||
*/
|
||||
class NS_COM nsNodeFunctor {
|
||||
public:
|
||||
virtual nsNodeFunctor& operator()(nsNode& aNode)=0;
|
||||
};
|
||||
|
||||
|
||||
/****************************************************
|
||||
* Here comes the nsBTree class...
|
||||
****************************************************/
|
||||
|
||||
class NS_COM nsBTree {
|
||||
public:
|
||||
friend class nsBTreeIterator;
|
||||
|
||||
nsBTree();
|
||||
virtual ~nsBTree();
|
||||
|
||||
/**
|
||||
* Add given node reference into our tree.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param aNode is a ref to a node to be added
|
||||
* @return newly added node
|
||||
*/
|
||||
nsNode* Add(nsNode& aNode);
|
||||
|
||||
/**
|
||||
* Remove given node reference into our tree.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param aNode is a ref to a node to be removed
|
||||
* @return Ptr to node if found (and removed) or NULL
|
||||
*/
|
||||
nsNode* Remove(nsNode& aNode);
|
||||
|
||||
/**
|
||||
* Clears the tree of any data.
|
||||
* Be careful here if your objects are heap based!
|
||||
* This method doesn't free the objects, so if you
|
||||
* don't have your own pointers, they will become
|
||||
* orphaned.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return this
|
||||
*/
|
||||
nsBTree& Empty(nsNode* aNode=0);
|
||||
|
||||
/**
|
||||
* This method destroys all the objects in the tree.
|
||||
* WARNING: Never call this method on stored objects
|
||||
* that are stack-based!
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param
|
||||
* @return this
|
||||
*/
|
||||
nsBTree& Erase(nsNode* aNode=0);
|
||||
|
||||
/**
|
||||
* Retrieve ptr to 1st node in tree (starting at root)
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @return ptr to 1st node, possible to be NULL
|
||||
*/
|
||||
nsNode* First(void) const;
|
||||
|
||||
/**
|
||||
* Find first node in tree starting at given node
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param aNode node to begin 1st search from
|
||||
* @return ptr to 1st node below given node
|
||||
*/
|
||||
nsNode* First(const nsNode& aNode) const;
|
||||
|
||||
/**
|
||||
* Retrieve ptr to last node in tree relative to root.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @return ptr to last node or NULL
|
||||
*/
|
||||
nsNode* Last(void) const;
|
||||
|
||||
/**
|
||||
* Retrieve ptr to last node in tree relative to given node.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param node to find last node from
|
||||
* @return ptr to last node or NULL
|
||||
*/
|
||||
nsNode* Last(const nsNode& aNode) const;
|
||||
|
||||
/**
|
||||
* Retrieve a ptr to the node that preceeds given node
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param aNode used as reference to find prev.
|
||||
* @return ptr to prev node or NULL
|
||||
*/
|
||||
nsNode* Before(const nsNode& aNode) const;
|
||||
|
||||
/**
|
||||
* Retrieve a ptr to the node after given node
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param aNode used as reference to find next.
|
||||
* @return ptr to next node or NULL
|
||||
*/
|
||||
nsNode* After(const nsNode& aNode) const;
|
||||
|
||||
/**
|
||||
* Find given node in tree.
|
||||
* (Why would you want to find a node you already have?)
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param aNode is the node you're searching for
|
||||
* @return ptr to node if found, or NULL
|
||||
*/
|
||||
nsNode* Find(const nsNode& aNode) const;
|
||||
|
||||
/**
|
||||
* Walks the tree, starting with root.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
*/
|
||||
virtual const nsBTree& ForEach(nsNodeFunctor& aFunctor,nsNode* aNode=0) const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Rebalances tree around the given node. This only
|
||||
* needs to be called after a node is deleted.
|
||||
*
|
||||
* @update gess 4/11/98
|
||||
* @param aNode -- node to balance around
|
||||
* @return this
|
||||
*/
|
||||
virtual nsBTree& ReBalance(nsNode& aNode);
|
||||
|
||||
|
||||
nsNode* mRoot;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
705
mozilla/xpcom/ds/nsBuffer.cpp
Normal file
705
mozilla/xpcom/ds/nsBuffer.cpp
Normal file
@@ -0,0 +1,705 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsBuffer.h"
|
||||
#include "nsAutoLock.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIPageManager.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsBuffer::nsBuffer()
|
||||
: mGrowBySize(0),
|
||||
mMaxSize(0),
|
||||
mAllocator(nsnull),
|
||||
mBufferSize(0),
|
||||
mReadSegment(nsnull),
|
||||
mReadCursor(0),
|
||||
mWriteSegment(nsnull),
|
||||
mWriteCursor(0),
|
||||
mReaderClosed(PR_FALSE),
|
||||
mCondition(NS_OK)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
PR_INIT_CLIST(&mSegments);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::Init(PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIBufferObserver* observer, nsIAllocator* allocator)
|
||||
{
|
||||
NS_ASSERTION(sizeof(PRCList) <= SEGMENT_OVERHEAD,
|
||||
"need to change SEGMENT_OVERHEAD size");
|
||||
NS_ASSERTION(growBySize > SEGMENT_OVERHEAD, "bad growBySize");
|
||||
mGrowBySize = growBySize;
|
||||
mMaxSize = maxSize;
|
||||
mObserver = observer;
|
||||
NS_IF_ADDREF(mObserver);
|
||||
mAllocator = allocator;
|
||||
NS_ADDREF(mAllocator);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsBuffer::~nsBuffer()
|
||||
{
|
||||
NS_IF_RELEASE(mObserver);
|
||||
NS_IF_RELEASE(mAllocator);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsBuffer, nsIBuffer::GetIID());
|
||||
|
||||
NS_METHOD
|
||||
nsBuffer::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsBuffer* buf = new nsBuffer();
|
||||
if (buf == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(buf);
|
||||
nsresult rv = buf->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
nsBuffer::PushWriteSegment()
|
||||
{
|
||||
nsAutoCMonitor mon(this); // protect mSegments
|
||||
|
||||
if (mBufferSize >= mMaxSize) {
|
||||
if (mObserver) {
|
||||
nsresult rv = mObserver->OnFull(this);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// allocate a new segment to write into
|
||||
PRCList* header;
|
||||
|
||||
header = (PRCList*)mAllocator->Alloc(mGrowBySize);
|
||||
if (header == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mBufferSize += mGrowBySize;
|
||||
|
||||
PR_INSERT_BEFORE(header, &mSegments); // insert at end
|
||||
|
||||
// initialize the write segment
|
||||
mWriteSegment = header;
|
||||
mWriteSegmentEnd = (char*)mWriteSegment + mGrowBySize;
|
||||
mWriteCursor = (char*)mWriteSegment + sizeof(PRCList);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsBuffer::PopReadSegment()
|
||||
{
|
||||
nsresult rv;
|
||||
nsAutoCMonitor mon(this); // protect mSegments
|
||||
|
||||
PRCList* header = (PRCList*)mSegments.next;
|
||||
char* segment = (char*)header;
|
||||
|
||||
NS_ASSERTION(mReadSegment == header, "wrong segment");
|
||||
|
||||
// make sure that the writer isn't still in this segment (that the
|
||||
// reader is removing)
|
||||
NS_ASSERTION(!(segment <= mWriteCursor && mWriteCursor < segment + mGrowBySize),
|
||||
"removing writer's segment");
|
||||
|
||||
PR_REMOVE_LINK(header); // unlink from mSegments
|
||||
|
||||
mBufferSize -= mGrowBySize;
|
||||
|
||||
rv = mAllocator->Free(segment);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// initialize the read segment
|
||||
if (PR_CLIST_IS_EMPTY(&mSegments)) {
|
||||
mReadSegment = nsnull;
|
||||
mReadSegmentEnd = nsnull;
|
||||
mReadCursor = nsnull;
|
||||
if (mObserver) {
|
||||
rv = mObserver->OnEmpty(this);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mReadSegment = mSegments.next;
|
||||
mReadSegmentEnd = (char*)mReadSegment + mGrowBySize;
|
||||
mReadCursor = (char*)mReadSegment + sizeof(PRCList);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIBuffer methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::ReadSegments(nsWriteSegmentFun writer, void* closure, PRUint32 count,
|
||||
PRUint32 *readCount)
|
||||
{
|
||||
NS_ASSERTION(!mReaderClosed, "state change error");
|
||||
|
||||
nsAutoCMonitor mon(this);
|
||||
nsresult rv = NS_OK;
|
||||
PRUint32 readBufferLen;
|
||||
const char* readBuffer;
|
||||
|
||||
*readCount = 0;
|
||||
while (count > 0) {
|
||||
rv = GetReadSegment(0, &readBuffer, &readBufferLen);
|
||||
if (rv == NS_BASE_STREAM_EOF) { // all we're going to get
|
||||
return *readCount == 0 ? rv : NS_OK;
|
||||
}
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "GetReadSegment failed -- shouldn't happen");
|
||||
if (readBufferLen == 0) {
|
||||
return *readCount == 0 ? NS_BASE_STREAM_WOULD_BLOCK : NS_OK;
|
||||
}
|
||||
|
||||
readBufferLen = PR_MIN(readBufferLen, count);
|
||||
while (readBufferLen > 0) {
|
||||
PRUint32 writeCount;
|
||||
rv = writer(closure, readBuffer, *readCount, readBufferLen, &writeCount);
|
||||
NS_ASSERTION(rv != NS_BASE_STREAM_EOF, "Write should not return EOF");
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK || NS_FAILED(rv)) {
|
||||
// if we failed to write just report what we were
|
||||
// able to read so far
|
||||
return *readCount == 0 ? rv : NS_OK;
|
||||
}
|
||||
NS_ASSERTION(writeCount <= readBufferLen, "writer returned bad writeCount");
|
||||
readBuffer += writeCount;
|
||||
readBufferLen -= writeCount;
|
||||
*readCount += writeCount;
|
||||
count -= writeCount;
|
||||
|
||||
if (mReadCursor + writeCount == mReadSegmentEnd) {
|
||||
rv = PopReadSegment();
|
||||
if (NS_FAILED(rv)) {
|
||||
return *readCount == 0 ? rv : NS_OK;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mReadCursor += writeCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static NS_METHOD
|
||||
nsWriteToRawBuffer(void* closure,
|
||||
const char* fromRawSegment,
|
||||
PRUint32 offset,
|
||||
PRUint32 count,
|
||||
PRUint32 *writeCount)
|
||||
{
|
||||
char* toBuf = (char*)closure;
|
||||
nsCRT::memcpy(&toBuf[offset], fromRawSegment, count);
|
||||
*writeCount = count;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::Read(char* toBuf, PRUint32 bufLen, PRUint32 *readCount)
|
||||
{
|
||||
return ReadSegments(nsWriteToRawBuffer, toBuf, bufLen, readCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetReadSegment(PRUint32 segmentLogicalOffset,
|
||||
const char* *resultSegment,
|
||||
PRUint32 *resultSegmentLen)
|
||||
{
|
||||
nsAutoCMonitor mon(this);
|
||||
|
||||
// set the read segment and cursor if not already set
|
||||
if (mReadSegment == nsnull) {
|
||||
if (PR_CLIST_IS_EMPTY(&mSegments)) {
|
||||
*resultSegmentLen = 0;
|
||||
*resultSegment = nsnull;
|
||||
return mCondition ? mCondition : NS_OK;
|
||||
}
|
||||
else {
|
||||
mReadSegment = mSegments.next;
|
||||
mReadSegmentEnd = (char*)mReadSegment + mGrowBySize;
|
||||
mReadCursor = (char*)mReadSegment + sizeof(PRCList);
|
||||
}
|
||||
}
|
||||
|
||||
// now search for the segment starting from segmentLogicalOffset and return it
|
||||
PRCList* curSeg = mReadSegment;
|
||||
char* curSegStart = mReadCursor;
|
||||
char* curSegEnd = mReadSegmentEnd;
|
||||
PRInt32 amt;
|
||||
PRInt32 offset = (PRInt32)segmentLogicalOffset;
|
||||
while (offset >= 0) {
|
||||
// snapshot the write cursor into a local variable -- this allows
|
||||
// a writer to freely change it while we're reading while avoiding
|
||||
// using a lock
|
||||
char* snapshotWriteCursor = mWriteCursor; // atomic
|
||||
|
||||
// next check if the write cursor is in our segment
|
||||
if (curSegStart <= snapshotWriteCursor &&
|
||||
snapshotWriteCursor < curSegEnd) {
|
||||
// same segment -- read up to the snapshotWriteCursor
|
||||
curSegEnd = snapshotWriteCursor;
|
||||
|
||||
amt = curSegEnd - curSegStart;
|
||||
if (offset < amt) {
|
||||
// segmentLogicalOffset is in this segment, so read up to its end
|
||||
*resultSegmentLen = amt - offset;
|
||||
*resultSegment = curSegStart + offset;
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
// don't continue past the write segment
|
||||
*resultSegmentLen = 0;
|
||||
*resultSegment = nsnull;
|
||||
return mCondition ? mCondition : NS_OK;
|
||||
}
|
||||
}
|
||||
else {
|
||||
amt = curSegEnd - curSegStart;
|
||||
if (offset < amt) {
|
||||
// segmentLogicalOffset is in this segment, so read up to its end
|
||||
*resultSegmentLen = amt - offset;
|
||||
*resultSegment = curSegStart + offset;
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
curSeg = PR_NEXT_LINK(curSeg);
|
||||
if (curSeg == mReadSegment) {
|
||||
// been all the way around
|
||||
*resultSegmentLen = 0;
|
||||
*resultSegment = nsnull;
|
||||
return mCondition ? mCondition : NS_OK;
|
||||
}
|
||||
curSegEnd = (char*)curSeg + mGrowBySize;
|
||||
curSegStart = (char*)curSeg + sizeof(PRCList);
|
||||
offset -= amt;
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_NOTREACHED("nsBuffer::GetReadSegment failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetReadableAmount(PRUint32 *result)
|
||||
{
|
||||
NS_ASSERTION(!mReaderClosed, "state change error");
|
||||
|
||||
nsAutoCMonitor mon(this);
|
||||
*result = 0;
|
||||
|
||||
// first set the read segment and cursor if not already set
|
||||
if (mReadSegment == nsnull) {
|
||||
if (PR_CLIST_IS_EMPTY(&mSegments)) {
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
mReadSegment = mSegments.next;
|
||||
mReadSegmentEnd = (char*)mReadSegment + mGrowBySize;
|
||||
mReadCursor = (char*)mReadSegment + sizeof(PRCList);
|
||||
}
|
||||
}
|
||||
|
||||
// now search for the segment starting from segmentLogicalOffset and return it
|
||||
PRCList* curSeg = mReadSegment;
|
||||
char* curSegStart = mReadCursor;
|
||||
char* curSegEnd = mReadSegmentEnd;
|
||||
PRInt32 amt;
|
||||
while (PR_TRUE) {
|
||||
// snapshot the write cursor into a local variable -- this allows
|
||||
// a writer to freely change it while we're reading while avoiding
|
||||
// using a lock
|
||||
char* snapshotWriteCursor = mWriteCursor; // atomic
|
||||
|
||||
// next check if the write cursor is in our segment
|
||||
if (curSegStart <= snapshotWriteCursor &&
|
||||
snapshotWriteCursor < curSegEnd) {
|
||||
// same segment -- read up to the snapshotWriteCursor
|
||||
curSegEnd = snapshotWriteCursor;
|
||||
|
||||
amt = curSegEnd - curSegStart;
|
||||
*result += amt;
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
amt = curSegEnd - curSegStart;
|
||||
*result += amt;
|
||||
curSeg = PR_NEXT_LINK(curSeg);
|
||||
if (curSeg == mReadSegment) {
|
||||
// been all the way around
|
||||
return NS_OK;
|
||||
}
|
||||
curSegEnd = (char*)curSeg + mGrowBySize;
|
||||
curSegStart = (char*)curSeg + sizeof(PRCList);
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
typedef PRInt32 (*compare_t)(const char*, const char*, PRUint32);
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::Search(const char* string, PRBool ignoreCase,
|
||||
PRBool *found, PRUint32 *offsetSearchedTo)
|
||||
{
|
||||
NS_ASSERTION(!mReaderClosed, "state change error");
|
||||
|
||||
nsresult rv;
|
||||
const char* bufSeg1;
|
||||
PRUint32 bufSegLen1;
|
||||
PRUint32 segmentPos = 0;
|
||||
PRUint32 strLen = nsCRT::strlen(string);
|
||||
compare_t compare =
|
||||
ignoreCase ? (compare_t)nsCRT::strncasecmp : (compare_t)nsCRT::strncmp;
|
||||
|
||||
rv = GetReadSegment(segmentPos, &bufSeg1, &bufSegLen1);
|
||||
if (NS_FAILED(rv) || bufSegLen1 == 0) {
|
||||
*found = PR_FALSE;
|
||||
*offsetSearchedTo = segmentPos;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
while (PR_TRUE) {
|
||||
PRUint32 i;
|
||||
// check if the string is in the buffer segment
|
||||
for (i = 0; i < bufSegLen1 - strLen + 1; i++) {
|
||||
if (compare(&bufSeg1[i], string, strLen) == 0) {
|
||||
*found = PR_TRUE;
|
||||
*offsetSearchedTo = segmentPos + i;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// get the next segment
|
||||
const char* bufSeg2;
|
||||
PRUint32 bufSegLen2;
|
||||
segmentPos += bufSegLen1;
|
||||
rv = GetReadSegment(segmentPos, &bufSeg2, &bufSegLen2);
|
||||
if (NS_FAILED(rv) || bufSegLen2 == 0) {
|
||||
*found = PR_FALSE;
|
||||
if (mCondition != NS_OK) // XXX NS_FAILED?
|
||||
*offsetSearchedTo = segmentPos - bufSegLen1;
|
||||
else
|
||||
*offsetSearchedTo = segmentPos - bufSegLen1 - strLen + 1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// check if the string is straddling the next buffer segment
|
||||
PRUint32 limit = PR_MIN(strLen, bufSegLen2 + 1);
|
||||
for (i = 0; i < limit; i++) {
|
||||
PRUint32 strPart1Len = strLen - i - 1;
|
||||
PRUint32 strPart2Len = strLen - strPart1Len;
|
||||
const char* strPart2 = &string[strLen - strPart2Len];
|
||||
PRUint32 bufSeg1Offset = bufSegLen1 - strPart1Len;
|
||||
if (compare(&bufSeg1[bufSeg1Offset], string, strPart1Len) == 0 &&
|
||||
compare(bufSeg2, strPart2, strPart2Len) == 0) {
|
||||
*found = PR_TRUE;
|
||||
*offsetSearchedTo = segmentPos - strPart1Len;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// finally continue with the next buffer
|
||||
bufSeg1 = bufSeg2;
|
||||
bufSegLen1 = bufSegLen2;
|
||||
}
|
||||
NS_NOTREACHED("can't get here");
|
||||
return NS_ERROR_FAILURE; // keep compiler happy
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::ReaderClosed()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsAutoCMonitor mon(this); // protect mSegments
|
||||
|
||||
// first prevent any more writing
|
||||
mReaderClosed = PR_TRUE;
|
||||
|
||||
// then free any unread segments...
|
||||
|
||||
// first set the read segment and cursor if not already set
|
||||
if (mReadSegment == nsnull) {
|
||||
if (!PR_CLIST_IS_EMPTY(&mSegments)) {
|
||||
mReadSegment = mSegments.next;
|
||||
mReadSegmentEnd = (char*)mReadSegment + mGrowBySize;
|
||||
mReadCursor = (char*)mReadSegment + sizeof(PRCList);
|
||||
}
|
||||
}
|
||||
|
||||
while (mReadSegment) {
|
||||
// snapshot the write cursor into a local variable -- this allows
|
||||
// a writer to freely change it while we're reading while avoiding
|
||||
// using a lock
|
||||
char* snapshotWriteCursor = mWriteCursor; // atomic
|
||||
|
||||
// next check if the write cursor is in our segment
|
||||
if (mReadCursor <= snapshotWriteCursor &&
|
||||
snapshotWriteCursor < mReadSegmentEnd) {
|
||||
// same segment -- we've discarded all the unread segments we
|
||||
// can, so just updatethe read cursor
|
||||
mReadCursor = mWriteCursor;
|
||||
break;
|
||||
}
|
||||
// else advance to the next segment, freeing this one
|
||||
rv = PopReadSegment();
|
||||
if (NS_FAILED(rv)) break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRUint32 amt;
|
||||
const char* buf;
|
||||
rv = GetReadSegment(0, &buf, &amt);
|
||||
NS_ASSERTION(rv == NS_BASE_STREAM_EOF ||
|
||||
(NS_SUCCEEDED(rv) && amt == 0), "ReaderClosed failed");
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetCondition(nsresult *result)
|
||||
{
|
||||
*result = mCondition;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::WriteSegments(nsReadSegmentFun reader, void* closure, PRUint32 count,
|
||||
PRUint32 *writeCount)
|
||||
{
|
||||
nsAutoCMonitor mon(this);
|
||||
nsresult rv;
|
||||
if (mReaderClosed)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
if (NS_FAILED(mCondition))
|
||||
return mCondition;
|
||||
|
||||
*writeCount = 0;
|
||||
while (count > 0) {
|
||||
PRUint32 writeBufLen;
|
||||
char* writeBuf;
|
||||
rv = GetWriteSegment(&writeBuf, &writeBufLen);
|
||||
if (NS_FAILED(rv) || writeBufLen == 0) {
|
||||
// if we failed to allocate a new segment, we're probably out
|
||||
// of memory, but we don't care -- just report what we were
|
||||
// able to write so far
|
||||
return (*writeCount == 0) ? rv : NS_OK;
|
||||
}
|
||||
|
||||
writeBufLen = PR_MIN(writeBufLen, count);
|
||||
while (writeBufLen > 0) {
|
||||
PRUint32 readCount;
|
||||
rv = reader(closure, writeBuf, *writeCount, writeBufLen, &readCount);
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
// if the place we're putting the data would block (probably ran
|
||||
// out of room) just return what we were able to write so far
|
||||
return (*writeCount == 0) ? rv : NS_OK;
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
// save the failure condition so that we can get it again later
|
||||
nsresult rv2 = SetCondition(rv);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv2), "SetCondition failed");
|
||||
// if we failed to read just report what we were
|
||||
// able to write so far
|
||||
return (*writeCount == 0) ? rv : NS_OK;
|
||||
}
|
||||
NS_ASSERTION(readCount <= writeBufLen, "reader returned bad readCount");
|
||||
writeBuf += readCount;
|
||||
writeBufLen -= readCount;
|
||||
*writeCount += readCount;
|
||||
count -= readCount;
|
||||
|
||||
// set the write cursor after the data is valid
|
||||
if (mWriteCursor + readCount == mWriteSegmentEnd) {
|
||||
mWriteSegment = nsnull; // allocate a new segment next time around
|
||||
mWriteSegmentEnd = nsnull;
|
||||
mWriteCursor = nsnull;
|
||||
}
|
||||
else
|
||||
mWriteCursor += readCount;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static NS_METHOD
|
||||
nsReadFromRawBuffer(void* closure,
|
||||
char* toRawSegment,
|
||||
PRUint32 offset,
|
||||
PRUint32 count,
|
||||
PRUint32 *readCount)
|
||||
{
|
||||
const char* fromBuf = (const char*)closure;
|
||||
nsCRT::memcpy(toRawSegment, &fromBuf[offset], count);
|
||||
*readCount = count;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::Write(const char* fromBuf, PRUint32 bufLen, PRUint32 *writeCount)
|
||||
{
|
||||
return WriteSegments(nsReadFromRawBuffer, (void*)fromBuf, bufLen, writeCount);
|
||||
}
|
||||
|
||||
static NS_METHOD
|
||||
nsReadFromInputStream(void* closure,
|
||||
char* toRawSegment,
|
||||
PRUint32 offset,
|
||||
PRUint32 count,
|
||||
PRUint32 *readCount)
|
||||
{
|
||||
nsIInputStream* fromStream = (nsIInputStream*)closure;
|
||||
return fromStream->Read(toRawSegment, count, readCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::WriteFrom(nsIInputStream* fromStream, PRUint32 count, PRUint32 *writeCount)
|
||||
{
|
||||
return WriteSegments(nsReadFromInputStream, fromStream, count, writeCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetWriteSegment(char* *resultSegment,
|
||||
PRUint32 *resultSegmentLen)
|
||||
{
|
||||
nsAutoCMonitor mon(this);
|
||||
if (mReaderClosed)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
nsresult rv;
|
||||
*resultSegmentLen = 0;
|
||||
*resultSegment = nsnull;
|
||||
if (mWriteSegment == nsnull) {
|
||||
rv = PushWriteSegment();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_ASSERTION(mWriteSegment != nsnull, "failed to allocate segment");
|
||||
}
|
||||
|
||||
*resultSegmentLen = mWriteSegmentEnd - mWriteCursor;
|
||||
*resultSegment = mWriteCursor;
|
||||
NS_ASSERTION(*resultSegmentLen > 0, "Failed to get write segment.");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetWritableAmount(PRUint32 *amount)
|
||||
{
|
||||
if (mReaderClosed)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
nsresult rv;
|
||||
PRUint32 readableAmount;
|
||||
rv = GetReadableAmount(&readableAmount);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
*amount = mMaxSize - readableAmount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetReaderClosed(PRBool *result)
|
||||
{
|
||||
*result = mReaderClosed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::SetCondition(nsresult condition)
|
||||
{
|
||||
nsAutoCMonitor mon(this);
|
||||
if (mReaderClosed)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
mCondition = condition;
|
||||
mWriteSegment = nsnull; // allows reader to free last segment w/o asserting
|
||||
mWriteSegmentEnd = nsnull;
|
||||
// don't reset mWriteCursor here -- we need it for the EOF point in the buffer
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static NS_DEFINE_CID(kAllocatorCID, NS_ALLOCATOR_CID);
|
||||
|
||||
NS_COM nsresult
|
||||
NS_NewBuffer(nsIBuffer* *result,
|
||||
PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIBufferObserver* observer)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIAllocator, alloc, kAllocatorCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsBuffer* buf;
|
||||
rv = nsBuffer::Create(NULL, nsIBuffer::GetIID(), (void**)&buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = buf->Init(growBySize, maxSize, observer, alloc);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*result = buf;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static NS_DEFINE_CID(kPageManagerCID, NS_PAGEMANAGER_CID);
|
||||
|
||||
NS_COM nsresult
|
||||
NS_NewPageBuffer(nsIBuffer* *result,
|
||||
PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIBufferObserver* observer)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIAllocator, alloc, kPageManagerCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsBuffer* buf;
|
||||
rv = nsBuffer::Create(NULL, nsIBuffer::GetIID(), (void**)&buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = buf->Init(growBySize, maxSize, observer, alloc);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*result = buf;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
87
mozilla/xpcom/ds/nsBuffer.h
Normal file
87
mozilla/xpcom/ds/nsBuffer.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsBuffer_h___
|
||||
#define nsBuffer_h___
|
||||
|
||||
#include "nsIBuffer.h"
|
||||
#include "nscore.h"
|
||||
#include "prclist.h"
|
||||
#include "nsIAllocator.h"
|
||||
|
||||
class nsBuffer : public nsIBuffer {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
// nsIBuffer methods:
|
||||
NS_IMETHOD Init(PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIBufferObserver* observer, nsIAllocator* allocator);
|
||||
NS_IMETHOD Read(char* toBuf, PRUint32 bufLen, PRUint32 *readCount);
|
||||
NS_IMETHOD ReadSegments(nsWriteSegmentFun writer, void* closure, PRUint32 count,
|
||||
PRUint32 *readCount);
|
||||
NS_IMETHOD GetReadSegment(PRUint32 segmentLogicalOffset,
|
||||
const char* *resultSegment,
|
||||
PRUint32 *resultSegmentLen);
|
||||
NS_IMETHOD GetReadableAmount(PRUint32 *amount);
|
||||
NS_IMETHOD Search(const char* forString, PRBool ignoreCase,
|
||||
PRBool *found, PRUint32 *offsetSearchedTo);
|
||||
NS_IMETHOD ReaderClosed(void);
|
||||
NS_IMETHOD GetCondition(nsresult *result);
|
||||
|
||||
NS_IMETHOD Write(const char* fromBuf, PRUint32 bufLen, PRUint32 *writeCount);
|
||||
NS_IMETHOD WriteFrom(nsIInputStream* fromStream, PRUint32 count, PRUint32 *writeCount);
|
||||
NS_IMETHOD WriteSegments(nsReadSegmentFun reader, void* closure, PRUint32 count,
|
||||
PRUint32 *writeCount);
|
||||
NS_IMETHOD GetWriteSegment(char* *resultSegment,
|
||||
PRUint32 *resultSegmentLen);
|
||||
NS_IMETHOD GetWritableAmount(PRUint32 *amount);
|
||||
NS_IMETHOD GetReaderClosed(PRBool *result);
|
||||
NS_IMETHOD SetCondition(nsresult condition);
|
||||
|
||||
// nsBuffer methods:
|
||||
nsBuffer();
|
||||
virtual ~nsBuffer();
|
||||
|
||||
nsresult PushWriteSegment();
|
||||
nsresult PopReadSegment();
|
||||
|
||||
protected:
|
||||
PRUint32 mGrowBySize;
|
||||
PRUint32 mMaxSize;
|
||||
nsIAllocator* mAllocator;
|
||||
nsIBufferObserver* mObserver;
|
||||
|
||||
PRCList mSegments;
|
||||
PRUint32 mBufferSize;
|
||||
|
||||
PRCList* mReadSegment;
|
||||
char* mReadSegmentEnd;
|
||||
char* mReadCursor;
|
||||
|
||||
PRCList* mWriteSegment;
|
||||
char* mWriteSegmentEnd;
|
||||
char* mWriteCursor;
|
||||
|
||||
PRBool mReaderClosed;
|
||||
nsresult mCondition;
|
||||
};
|
||||
|
||||
#endif // nsBuffer_h___
|
||||
@@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
@@ -16,41 +16,25 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsWinRegValue_h__
|
||||
#define nsWinRegValue_h__
|
||||
#ifndef nsBufferPoolService_h___
|
||||
#define nsBufferPoolService_h___
|
||||
|
||||
#include "prtypes.h"
|
||||
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
struct nsWinRegValue {
|
||||
#include "nsIBufferPoolService.h"
|
||||
|
||||
class nsBufferPoolService : public nsIBufferPoolService {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
/* Public Fields */
|
||||
PRInt32 type;
|
||||
void* data;
|
||||
PRInt32 data_length;
|
||||
// nsIBufferPoolService methods:
|
||||
NS_IMETHOD NewBuffer(PRUint32 minSize, PRUint32 maxSize,
|
||||
nsIByteBuffer* *result);
|
||||
|
||||
/* Public Methods */
|
||||
nsWinRegValue(PRInt32 datatype, void* regdata, PRInt32 len)
|
||||
{
|
||||
type = datatype;
|
||||
data = regdata;
|
||||
data_length = len;
|
||||
}
|
||||
|
||||
/* should we copy the regdata? */
|
||||
private:
|
||||
|
||||
/* Private Fields */
|
||||
|
||||
|
||||
/* Private Methods */
|
||||
// nsBufferPoolService methods:
|
||||
nsBufferPoolService();
|
||||
virtual ~nsBufferPoolService();
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* nsWinRegValue_h__ */
|
||||
#endif // nsBufferPoolService_h___
|
||||
152
mozilla/xpcom/ds/nsByteBuffer.cpp
Normal file
152
mozilla/xpcom/ds/nsByteBuffer.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsByteBuffer.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
#define MIN_BUFFER_SIZE 32
|
||||
|
||||
ByteBufferImpl::ByteBufferImpl(void)
|
||||
: mBuffer(NULL), mSpace(0), mLength(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ByteBufferImpl::Init(PRUint32 aBufferSize)
|
||||
{
|
||||
if (aBufferSize < MIN_BUFFER_SIZE) {
|
||||
aBufferSize = MIN_BUFFER_SIZE;
|
||||
}
|
||||
mSpace = aBufferSize;
|
||||
mLength = 0;
|
||||
mBuffer = new char[aBufferSize];
|
||||
return mBuffer ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_DEFINE_IID(kByteBufferIID,NS_IBYTE_BUFFER_IID);
|
||||
NS_IMPL_ISUPPORTS(ByteBufferImpl,kByteBufferIID)
|
||||
|
||||
ByteBufferImpl::~ByteBufferImpl()
|
||||
{
|
||||
if (nsnull != mBuffer) {
|
||||
delete[] mBuffer;
|
||||
mBuffer = nsnull;
|
||||
}
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
ByteBufferImpl::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
ByteBufferImpl* it = new ByteBufferImpl();
|
||||
if (nsnull == it)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(it);
|
||||
nsresult rv = it->QueryInterface(aIID, (void**)aResult);
|
||||
NS_RELEASE(it);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRUint32)
|
||||
ByteBufferImpl::GetLength(void) const
|
||||
{
|
||||
return mLength;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRUint32)
|
||||
ByteBufferImpl::GetBufferSize(void) const
|
||||
{
|
||||
return mSpace;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(char*)
|
||||
ByteBufferImpl::GetBuffer(void) const
|
||||
{
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
ByteBufferImpl::Grow(PRUint32 aNewSize)
|
||||
{
|
||||
if (aNewSize < MIN_BUFFER_SIZE) {
|
||||
aNewSize = MIN_BUFFER_SIZE;
|
||||
}
|
||||
char* newbuf = new char[aNewSize];
|
||||
if (nsnull != newbuf) {
|
||||
if (0 != mLength) {
|
||||
nsCRT::memcpy(newbuf, mBuffer, mLength);
|
||||
}
|
||||
delete[] mBuffer;
|
||||
mBuffer = newbuf;
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRInt32)
|
||||
ByteBufferImpl::Fill(nsresult* aErrorCode, nsIInputStream* aStream,
|
||||
PRUint32 aKeep)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aStream, "null stream");
|
||||
NS_PRECONDITION(aKeep <= mLength, "illegal keep count");
|
||||
if ((nsnull == aStream) || (PRUint32(aKeep) > PRUint32(mLength))) {
|
||||
// whoops
|
||||
*aErrorCode = NS_BASE_STREAM_ILLEGAL_ARGS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != aKeep) {
|
||||
// Slide over kept data
|
||||
nsCRT::memmove(mBuffer, mBuffer + (mLength - aKeep), aKeep);
|
||||
}
|
||||
|
||||
// Read in some new data
|
||||
mLength = aKeep;
|
||||
PRUint32 nb;
|
||||
*aErrorCode = aStream->Read(mBuffer + aKeep, mSpace - aKeep, &nb);
|
||||
if (NS_SUCCEEDED(*aErrorCode)) {
|
||||
mLength += nb;
|
||||
}
|
||||
else
|
||||
nb = 0;
|
||||
return nb;
|
||||
}
|
||||
|
||||
NS_COM nsresult NS_NewByteBuffer(nsIByteBuffer** aInstancePtrResult,
|
||||
nsISupports* aOuter,
|
||||
PRUint32 aBufferSize)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIByteBuffer* buf;
|
||||
rv = ByteBufferImpl::Create(aOuter, nsIByteBuffer::GetIID(), (void**)&buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = buf->Init(aBufferSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(buf);
|
||||
return rv;
|
||||
}
|
||||
*aInstancePtrResult = buf;
|
||||
return rv;
|
||||
}
|
||||
47
mozilla/xpcom/ds/nsByteBuffer.h
Normal file
47
mozilla/xpcom/ds/nsByteBuffer.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsByteBuffer_h__
|
||||
#define nsByteBuffer_h__
|
||||
|
||||
#include "nsIByteBuffer.h"
|
||||
|
||||
class ByteBufferImpl : public nsIByteBuffer {
|
||||
public:
|
||||
ByteBufferImpl(void);
|
||||
virtual ~ByteBufferImpl();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
NS_IMETHOD Init(PRUint32 aBufferSize);
|
||||
NS_IMETHOD_(PRUint32) GetLength(void) const;
|
||||
NS_IMETHOD_(PRUint32) GetBufferSize(void) const;
|
||||
NS_IMETHOD_(char*) GetBuffer() const;
|
||||
NS_IMETHOD_(PRBool) Grow(PRUint32 aNewSize);
|
||||
NS_IMETHOD_(PRInt32) Fill(nsresult* aErrorCode, nsIInputStream* aStream,
|
||||
PRUint32 aKeep);
|
||||
|
||||
char* mBuffer;
|
||||
PRUint32 mSpace;
|
||||
PRUint32 mLength;
|
||||
};
|
||||
|
||||
#endif // nsByteBuffer_h__
|
||||
552
mozilla/xpcom/ds/nsCRT.cpp
Normal file
552
mozilla/xpcom/ds/nsCRT.cpp
Normal file
@@ -0,0 +1,552 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* MODULE NOTES:
|
||||
* @update gess7/30/98
|
||||
*
|
||||
* Much as I hate to do it, we were using string compares wrong.
|
||||
* Often, programmers call functions like strcmp(s1,s2), and pass
|
||||
* one or more null strings. Rather than blow up on these, I've
|
||||
* added quick checks to ensure that cases like this don't cause
|
||||
* us to fail.
|
||||
*
|
||||
* In general, if you pass a null into any of these string compare
|
||||
* routines, we simply return 0.
|
||||
*/
|
||||
|
||||
|
||||
#include "nsCRT.h"
|
||||
#include "nsUnicharUtilCIID.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsICaseConversion.h"
|
||||
|
||||
|
||||
// XXX Bug: These tables don't lowercase the upper 128 characters properly
|
||||
|
||||
// This table maps uppercase characters to lower case characters;
|
||||
// characters that are neither upper nor lower case are unaffected.
|
||||
static const unsigned char kUpper2Lower[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64,
|
||||
|
||||
// upper band mapped to lower [A-Z] => [a-z]
|
||||
97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
|
||||
112,113,114,115,116,117,118,119,120,121,122,
|
||||
|
||||
91, 92, 93, 94, 95,
|
||||
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
|
||||
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
|
||||
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
|
||||
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
|
||||
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
|
||||
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
|
||||
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
|
||||
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
|
||||
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
|
||||
};
|
||||
|
||||
static const unsigned char kLower2Upper[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
||||
96,
|
||||
|
||||
// lower band mapped to upper [a-z] => [A-Z]
|
||||
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
|
||||
|
||||
123,124,125,126,127,
|
||||
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
|
||||
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
|
||||
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
|
||||
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
|
||||
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
|
||||
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
|
||||
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
|
||||
};
|
||||
|
||||
// XXX bug: this doesn't map 0x80 to 0x9f properly
|
||||
const PRUnichar kIsoLatin1ToUCS2[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
||||
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
|
||||
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
|
||||
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
|
||||
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
|
||||
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
|
||||
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
|
||||
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
|
||||
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
|
||||
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#define TOLOWER(_ucs2) \
|
||||
(((_ucs2) < 128) ? PRUnichar(kUpper2Lower[_ucs2]) : _ToLower(_ucs2))
|
||||
|
||||
#define TOUPPER(_ucs2) \
|
||||
(((_ucs2) < 128) ? PRUnichar(kLower2Upper[_ucs2]) : _ToUpper(_ucs2))
|
||||
|
||||
class HandleCaseConversionShutdown : public nsIShutdownListener {
|
||||
public :
|
||||
NS_IMETHOD OnShutdown(const nsCID& cid, nsISupports* service);
|
||||
HandleCaseConversionShutdown(void) { NS_INIT_REFCNT(); }
|
||||
virtual ~HandleCaseConversionShutdown(void) {}
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
|
||||
static NS_DEFINE_IID(kICaseConversionIID, NS_ICASECONVERSION_IID);
|
||||
|
||||
static nsICaseConversion * gCaseConv = NULL;
|
||||
|
||||
static NS_DEFINE_IID(kIShutdownListenerIID, NS_ISHUTDOWNLISTENER_IID);
|
||||
NS_IMPL_ISUPPORTS(HandleCaseConversionShutdown, kIShutdownListenerIID);
|
||||
|
||||
nsresult
|
||||
HandleCaseConversionShutdown::OnShutdown(const nsCID& cid,
|
||||
nsISupports* aService)
|
||||
{
|
||||
if (cid.Equals(kUnicharUtilCID)) {
|
||||
NS_ASSERTION(aService == gCaseConv, "wrong service!");
|
||||
gCaseConv->Release();
|
||||
gCaseConv = NULL;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static HandleCaseConversionShutdown* gListener = NULL;
|
||||
|
||||
static void StartUpCaseConversion()
|
||||
{
|
||||
nsresult err;
|
||||
|
||||
if ( NULL == gListener )
|
||||
{
|
||||
gListener = new HandleCaseConversionShutdown();
|
||||
gListener->AddRef();
|
||||
}
|
||||
err = nsServiceManager::GetService(kUnicharUtilCID, kICaseConversionIID,
|
||||
(nsISupports**) &gCaseConv, gListener);
|
||||
}
|
||||
static void CheckCaseConversion()
|
||||
{
|
||||
if(NULL == gCaseConv )
|
||||
StartUpCaseConversion();
|
||||
|
||||
NS_ASSERTION( gCaseConv != NULL , "cannot obtain UnicharUtil");
|
||||
|
||||
}
|
||||
|
||||
static PRUnichar _ToLower(PRUnichar aChar)
|
||||
{
|
||||
PRUnichar oLower;
|
||||
CheckCaseConversion();
|
||||
nsresult err = gCaseConv->ToLower(aChar, &oLower);
|
||||
NS_ASSERTION( NS_SUCCEEDED(err), "failed to communicate to UnicharUtil");
|
||||
return ( NS_SUCCEEDED(err) ) ? oLower : aChar ;
|
||||
}
|
||||
|
||||
static PRUnichar _ToUpper(PRUnichar aChar)
|
||||
{
|
||||
nsresult err;
|
||||
PRUnichar oUpper;
|
||||
CheckCaseConversion();
|
||||
err = gCaseConv->ToUpper(aChar, &oUpper);
|
||||
NS_ASSERTION( NS_SUCCEEDED(err), "failed to communicate to UnicharUtil");
|
||||
return ( NS_SUCCEEDED(err) ) ? oUpper : aChar ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
PRUnichar nsCRT::ToUpper(PRUnichar aChar)
|
||||
{
|
||||
return TOUPPER(aChar);
|
||||
}
|
||||
|
||||
PRUnichar nsCRT::ToLower(PRUnichar aChar)
|
||||
{
|
||||
return TOLOWER(aChar);
|
||||
}
|
||||
|
||||
PRBool nsCRT::IsUpper(PRUnichar aChar)
|
||||
{
|
||||
return aChar != nsCRT::ToLower(aChar);
|
||||
}
|
||||
|
||||
PRBool nsCRT::IsLower(PRUnichar aChar)
|
||||
{
|
||||
return aChar != nsCRT::ToUpper(aChar);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// My lovely strtok routine
|
||||
|
||||
#define IS_DELIM(m, c) ((m)[(c) >> 3] & (1 << ((c) & 7)))
|
||||
#define SET_DELIM(m, c) ((m)[(c) >> 3] |= (1 << ((c) & 7)))
|
||||
#define DELIM_TABLE_SIZE 32
|
||||
|
||||
char* nsCRT::strtok(char* string, const char* delims, char* *newStr)
|
||||
{
|
||||
NS_ASSERTION(string, "Unlike regular strtok, the first argument cannot be null.");
|
||||
|
||||
char delimTable[DELIM_TABLE_SIZE];
|
||||
PRUint32 i;
|
||||
char* result;
|
||||
char* str = string;
|
||||
|
||||
for (i = 0; i < DELIM_TABLE_SIZE; i++)
|
||||
delimTable[i] = '\0';
|
||||
|
||||
for (i = 0; i < DELIM_TABLE_SIZE && delims[i]; i++) {
|
||||
SET_DELIM(delimTable, delims[i]);
|
||||
}
|
||||
NS_ASSERTION(delims[i] == '\0', "too many delimiters");
|
||||
|
||||
// skip to beginning
|
||||
while (*str && IS_DELIM(delimTable, *str)) {
|
||||
str++;
|
||||
}
|
||||
result = str;
|
||||
|
||||
// fix up the end of the token
|
||||
while (*str) {
|
||||
if (IS_DELIM(delimTable, *str)) {
|
||||
*str++ = '\0';
|
||||
break;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
*newStr = str;
|
||||
|
||||
return str == result ? NULL : result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PRUint32 nsCRT::strlen(const PRUnichar* s)
|
||||
{
|
||||
PRUint32 len = 0;
|
||||
if(s) {
|
||||
while (*s++ != 0) {
|
||||
len++;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare unichar string ptrs, stopping at the 1st null
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 and s2 both point to unichar strings
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strcmp(const PRUnichar* s1, const PRUnichar* s2)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
for (;;) {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = *s2++;
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare unichar string ptrs, stopping at the 1st null or nth char.
|
||||
* NOTE: If either is null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 and s2 both point to unichar strings
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strncmp(const PRUnichar* s1, const PRUnichar* s2, PRUint32 n)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
if(n != 0) {
|
||||
do {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = *s2++;
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare unichar string ptrs without regard to case
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 and s2 both point to unichar strings
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strcasecmp(const PRUnichar* s1, const PRUnichar* s2)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
for (;;) {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = *s2++;
|
||||
if (c1 != c2) {
|
||||
c1 = TOLOWER(c1);
|
||||
c2 = TOLOWER(c2);
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare unichar string ptrs, stopping at the 1st null or nth char;
|
||||
* also ignoring the case of characters.
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 and s2 both point to unichar strings
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strncasecmp(const PRUnichar* s1, const PRUnichar* s2, PRUint32 n)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
if(n != 0){
|
||||
do {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = *s2++;
|
||||
if (c1 != c2) {
|
||||
c1 = TOLOWER(c1);
|
||||
c2 = TOLOWER(c2);
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare a unichar string ptr to cstring.
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 points to unichar string
|
||||
* @param s2 points to cstring
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strcmp(const PRUnichar* s1, const char* s2)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
for (;;) {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare a unichar string ptr to cstring, up to N chars.
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 points to unichar string
|
||||
* @param s2 points to cstring
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strncmp(const PRUnichar* s1, const char* s2, PRUint32 n)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
if(n != 0){
|
||||
do {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare a unichar string ptr to cstring without regard to case
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 points to unichar string
|
||||
* @param s2 points to cstring
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strcasecmp(const PRUnichar* s1, const char* s2)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
for (;;) {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
|
||||
if (c1 != c2) {
|
||||
c1 = TOLOWER(c1);
|
||||
c2 = TOLOWER(c2);
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caseless compare up to N chars between unichar string ptr to cstring.
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 points to unichar string
|
||||
* @param s2 points to cstring
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strncasecmp(const PRUnichar* s1, const char* s2, PRUint32 n)
|
||||
{
|
||||
if(s1 && s2){
|
||||
if(n != 0){
|
||||
do {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
|
||||
if (c1 != c2) {
|
||||
c1 = TOLOWER(c1);
|
||||
c2 = TOLOWER(c2);
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (c1 == 0) break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRUnichar* nsCRT::strdup(const PRUnichar* str)
|
||||
{
|
||||
PRUint32 len = nsCRT::strlen(str) + 1; // add one for null
|
||||
PRUnichar* rslt = new PRUnichar[len];
|
||||
if (rslt == NULL) return NULL;
|
||||
nsCRT::memcpy(rslt, str, len * sizeof(PRUnichar));
|
||||
return rslt;
|
||||
}
|
||||
|
||||
PRUint32 nsCRT::HashValue(const char* us)
|
||||
{
|
||||
PRUint32 rv = 0;
|
||||
if(us) {
|
||||
char ch;
|
||||
while ((ch = *us++) != 0) {
|
||||
// FYI: rv = rv*37 + ch
|
||||
rv = ((rv << 5) + (rv << 2) + rv) + ch;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRUint32 nsCRT::HashValue(const char* us, PRUint32* uslenp)
|
||||
{
|
||||
PRUint32 rv = 0;
|
||||
PRUint32 len = 0;
|
||||
char ch;
|
||||
while ((ch = *us++) != 0) {
|
||||
// FYI: rv = rv*37 + ch
|
||||
rv = ((rv << 5) + (rv << 2) + rv) + ch;
|
||||
len++;
|
||||
}
|
||||
*uslenp = len;
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRUint32 nsCRT::HashValue(const PRUnichar* us)
|
||||
{
|
||||
PRUint32 rv = 0;
|
||||
if(us) {
|
||||
PRUnichar ch;
|
||||
while ((ch = *us++) != 0) {
|
||||
// FYI: rv = rv*37 + ch
|
||||
rv = ((rv << 5) + (rv << 2) + rv) + ch;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRUint32 nsCRT::HashValue(const PRUnichar* us, PRUint32* uslenp)
|
||||
{
|
||||
PRUint32 rv = 0;
|
||||
PRUint32 len = 0;
|
||||
PRUnichar ch;
|
||||
while ((ch = *us++) != 0) {
|
||||
// FYI: rv = rv*37 + ch
|
||||
rv = ((rv << 5) + (rv << 2) + rv) + ch;
|
||||
len++;
|
||||
}
|
||||
*uslenp = len;
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32 nsCRT::atoi( const PRUnichar *string )
|
||||
{
|
||||
return atoi(string);
|
||||
}
|
||||
|
||||
231
mozilla/xpcom/ds/nsCRT.h
Normal file
231
mozilla/xpcom/ds/nsCRT.h
Normal file
@@ -0,0 +1,231 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#ifndef nsCRT_h___
|
||||
#define nsCRT_h___
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "plstr.h"
|
||||
#include "nscore.h"
|
||||
#include "prtypes.h"
|
||||
|
||||
#define CR '\015'
|
||||
#define LF '\012'
|
||||
#define VTAB '\013'
|
||||
#define FF '\014'
|
||||
#define TAB '\011'
|
||||
#define CRLF "\015\012" /* A CR LF equivalent string */
|
||||
|
||||
#ifdef XP_MAC
|
||||
# define NS_LINEBREAK "\015"
|
||||
# define NS_LINEBREAK_LEN 1
|
||||
#else
|
||||
# ifdef XP_PC
|
||||
# define NS_LINEBREAK "\015\012"
|
||||
# define NS_LINEBREAK_LEN 2
|
||||
# else
|
||||
# if defined(XP_UNIX) || defined(XP_BEOS)
|
||||
# define NS_LINEBREAK "\012"
|
||||
# define NS_LINEBREAK_LEN 1
|
||||
# endif /* XP_UNIX */
|
||||
# endif /* XP_PC */
|
||||
#endif /* XP_MAC */
|
||||
|
||||
|
||||
extern const PRUnichar kIsoLatin1ToUCS2[256];
|
||||
|
||||
|
||||
// This macro can be used in a class declaration for classes that want
|
||||
// to ensure that their instance memory is zeroed.
|
||||
#define NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW \
|
||||
void* operator new(size_t sz) { \
|
||||
void* rv = ::operator new(sz); \
|
||||
if (rv) { \
|
||||
nsCRT::zero(rv, sz); \
|
||||
} \
|
||||
return rv; \
|
||||
} \
|
||||
void operator delete(void* ptr) { \
|
||||
::operator delete(ptr); \
|
||||
}
|
||||
|
||||
// This macro works with the next macro to declare a non-inlined
|
||||
// version of the above.
|
||||
#define NS_DECL_ZEROING_OPERATOR_NEW \
|
||||
void* operator new(size_t sz); \
|
||||
void operator delete(void* ptr);
|
||||
|
||||
#define NS_IMPL_ZEROING_OPERATOR_NEW(_class) \
|
||||
void* _class::operator new(size_t sz) { \
|
||||
void* rv = ::operator new(sz); \
|
||||
if (rv) { \
|
||||
nsCRT::zero(rv, sz); \
|
||||
} \
|
||||
return rv; \
|
||||
} \
|
||||
void _class::operator delete(void* ptr) { \
|
||||
::operator delete(ptr); \
|
||||
}
|
||||
|
||||
/// This is a wrapper class around all the C runtime functions.
|
||||
|
||||
class NS_COM nsCRT {
|
||||
public:
|
||||
|
||||
/** Copy bytes from aSrc to aDest.
|
||||
@param aDest the destination address
|
||||
@param aSrc the source address
|
||||
@param aCount the number of bytes to copy
|
||||
*/
|
||||
static void memcpy(void* aDest, const void* aSrc, PRUint32 aCount) {
|
||||
::memcpy(aDest, aSrc, (size_t)aCount);
|
||||
}
|
||||
|
||||
static void memmove(void* aDest, const void* aSrc, PRUint32 aCount) {
|
||||
::memmove(aDest, aSrc, (size_t)aCount);
|
||||
}
|
||||
|
||||
static void memset(void* aDest, PRUint8 aByte, PRUint32 aCount) {
|
||||
::memset(aDest, aByte, aCount);
|
||||
}
|
||||
|
||||
static void zero(void* aDest, PRUint32 aCount) {
|
||||
::memset(aDest, 0, (size_t)aCount);
|
||||
}
|
||||
|
||||
/** Compute the string length of s
|
||||
@param s the string in question
|
||||
@return the length of s
|
||||
*/
|
||||
static PRUint32 strlen(const char* s) {
|
||||
return PRUint32(::strlen(s));
|
||||
}
|
||||
|
||||
/// Compare s1 and s2.
|
||||
static PRInt32 strcmp(const char* s1, const char* s2) {
|
||||
return PRUint32(PL_strcmp(s1, s2));
|
||||
}
|
||||
|
||||
static PRInt32 strncmp(const char* s1, const char* s2,
|
||||
PRUint32 aMaxLen) {
|
||||
return PRInt32(PL_strncmp(s1, s2, aMaxLen));
|
||||
}
|
||||
|
||||
/// Case-insensitive string comparison.
|
||||
static PRInt32 strcasecmp(const char* s1, const char* s2) {
|
||||
return PRInt32(PL_strcasecmp(s1, s2));
|
||||
}
|
||||
|
||||
/// Case-insensitive string comparison with length
|
||||
static PRInt32 strncasecmp(const char* s1, const char* s2, PRUint32 aMaxLen) {
|
||||
return PRInt32(PL_strncasecmp(s1, s2, aMaxLen));
|
||||
}
|
||||
|
||||
static PRInt32 strncmp(const char* s1, const char* s2, PRInt32 aMaxLen) {
|
||||
return PRInt32(PL_strncmp(s1,s2,aMaxLen));
|
||||
}
|
||||
|
||||
static char* strdup(const char* str) {
|
||||
return PL_strdup(str);
|
||||
}
|
||||
|
||||
static void free(char* str) {
|
||||
PL_strfree(str);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
How to use this fancy (thread-safe) version of strtok:
|
||||
|
||||
void main( void ) {
|
||||
printf( "%s\n\nTokens:\n", string );
|
||||
// Establish string and get the first token:
|
||||
char* newStr;
|
||||
token = nsCRT::strtok( string, seps, &newStr );
|
||||
while( token != NULL ) {
|
||||
// While there are tokens in "string"
|
||||
printf( " %s\n", token );
|
||||
// Get next token:
|
||||
token = nsCRT::strtok( newStr, seps, &newStr );
|
||||
}
|
||||
}
|
||||
* WARNING - STRTOK WHACKS str THE FIRST TIME IT IS CALLED *
|
||||
* MAKE A COPY OF str IF YOU NEED TO USE IT AFTER strtok() *
|
||||
*/
|
||||
static char* strtok(char* str, const char* delims, char* *newStr);
|
||||
|
||||
/// Like strlen except for ucs2 strings
|
||||
static PRUint32 strlen(const PRUnichar* s);
|
||||
|
||||
/// Like strcmp except for ucs2 strings
|
||||
static PRInt32 strcmp(const PRUnichar* s1, const PRUnichar* s2);
|
||||
/// Like strcmp except for ucs2 strings
|
||||
static PRInt32 strncmp(const PRUnichar* s1, const PRUnichar* s2,
|
||||
PRUint32 aMaxLen);
|
||||
|
||||
/// Like strcasecmp except for ucs2 strings
|
||||
static PRInt32 strcasecmp(const PRUnichar* s1, const PRUnichar* s2);
|
||||
/// Like strncasecmp except for ucs2 strings
|
||||
static PRInt32 strncasecmp(const PRUnichar* s1, const PRUnichar* s2,
|
||||
PRUint32 aMaxLen);
|
||||
|
||||
/// Like strcmp with a char* and a ucs2 string
|
||||
static PRInt32 strcmp(const PRUnichar* s1, const char* s2);
|
||||
/// Like strncmp with a char* and a ucs2 string
|
||||
static PRInt32 strncmp(const PRUnichar* s1, const char* s2,
|
||||
PRUint32 aMaxLen);
|
||||
|
||||
/// Like strcasecmp with a char* and a ucs2 string
|
||||
static PRInt32 strcasecmp(const PRUnichar* s1, const char* s2);
|
||||
/// Like strncasecmp with a char* and a ucs2 string
|
||||
static PRInt32 strncasecmp(const PRUnichar* s1, const char* s2,
|
||||
PRUint32 aMaxLen);
|
||||
|
||||
// Note: uses new[] to allocate memory, so you must use delete[] to
|
||||
// free the memory
|
||||
static PRUnichar* strdup(const PRUnichar* str);
|
||||
|
||||
static void free(PRUnichar* str) {
|
||||
delete[] str;
|
||||
}
|
||||
|
||||
/// Compute a hashcode for a C string
|
||||
static PRUint32 HashValue(const char* s1);
|
||||
|
||||
/// Same as above except that we return the length in s1len
|
||||
static PRUint32 HashValue(const char* s1, PRUint32* s1len);
|
||||
|
||||
/// Compute a hashcode for a ucs2 string
|
||||
static PRUint32 HashValue(const PRUnichar* s1);
|
||||
|
||||
/// Same as above except that we return the length in s1len
|
||||
static PRUint32 HashValue(const PRUnichar* s1, PRUint32* s1len);
|
||||
|
||||
/// String to integer.
|
||||
static PRInt32 atoi( const PRUnichar *string );
|
||||
|
||||
static PRUnichar ToUpper(PRUnichar aChar);
|
||||
|
||||
static PRUnichar ToLower(PRUnichar aChar);
|
||||
|
||||
static PRBool IsUpper(PRUnichar aChar);
|
||||
|
||||
static PRBool IsLower(PRUnichar aChar);
|
||||
};
|
||||
|
||||
#endif /* nsCRT_h___ */
|
||||
392
mozilla/xpcom/ds/nsConjoiningEnumerator.cpp
Normal file
392
mozilla/xpcom/ds/nsConjoiningEnumerator.cpp
Normal file
@@ -0,0 +1,392 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsIEnumerator.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Intersection Enumerators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsConjoiningEnumerator : public nsIBidirectionalEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIEnumerator methods:
|
||||
NS_IMETHOD First(void);
|
||||
NS_IMETHOD Next(void);
|
||||
NS_IMETHOD CurrentItem(nsISupports **aItem);
|
||||
NS_IMETHOD IsDone(void);
|
||||
|
||||
// nsIBidirectionalEnumerator methods:
|
||||
NS_IMETHOD Last(void);
|
||||
NS_IMETHOD Prev(void);
|
||||
|
||||
// nsConjoiningEnumerator methods:
|
||||
nsConjoiningEnumerator(nsIEnumerator* first, nsIEnumerator* second);
|
||||
virtual ~nsConjoiningEnumerator(void);
|
||||
|
||||
protected:
|
||||
nsIEnumerator* mFirst;
|
||||
nsIEnumerator* mSecond;
|
||||
nsIEnumerator* mCurrent;
|
||||
};
|
||||
|
||||
nsConjoiningEnumerator::nsConjoiningEnumerator(nsIEnumerator* first, nsIEnumerator* second)
|
||||
: mFirst(first), mSecond(second), mCurrent(first)
|
||||
{
|
||||
NS_ADDREF(mFirst);
|
||||
NS_ADDREF(mSecond);
|
||||
}
|
||||
|
||||
nsConjoiningEnumerator::~nsConjoiningEnumerator(void)
|
||||
{
|
||||
NS_RELEASE(mFirst);
|
||||
NS_RELEASE(mSecond);
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsConjoiningEnumerator);
|
||||
NS_IMPL_RELEASE(nsConjoiningEnumerator);
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConjoiningEnumerator::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (aIID.Equals(nsIBidirectionalEnumerator::GetIID()) ||
|
||||
aIID.Equals(nsIEnumerator::GetIID()) ||
|
||||
aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID())) {
|
||||
*aInstancePtr = (void*) this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConjoiningEnumerator::First(void)
|
||||
{
|
||||
mCurrent = mFirst;
|
||||
return mCurrent->First();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConjoiningEnumerator::Next(void)
|
||||
{
|
||||
nsresult rv = mCurrent->Next();
|
||||
if (NS_FAILED(rv) && mCurrent == mFirst) {
|
||||
mCurrent = mSecond;
|
||||
rv = mCurrent->First();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConjoiningEnumerator::CurrentItem(nsISupports **aItem)
|
||||
{
|
||||
return mCurrent->CurrentItem(aItem);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConjoiningEnumerator::IsDone(void)
|
||||
{
|
||||
return (mCurrent == mFirst && mCurrent->IsDone() == NS_OK)
|
||||
|| (mCurrent == mSecond && mCurrent->IsDone() == NS_OK)
|
||||
? NS_OK : NS_COMFALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConjoiningEnumerator::Last(void)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIBidirectionalEnumerator* be;
|
||||
rv = mSecond->QueryInterface(nsIBidirectionalEnumerator::GetIID(), (void**)&be);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
mCurrent = mSecond;
|
||||
rv = be->Last();
|
||||
NS_RELEASE(be);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConjoiningEnumerator::Prev(void)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIBidirectionalEnumerator* be;
|
||||
rv = mCurrent->QueryInterface(nsIBidirectionalEnumerator::GetIID(), (void**)&be);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = be->Prev();
|
||||
NS_RELEASE(be);
|
||||
if (NS_FAILED(rv) && mCurrent == mSecond) {
|
||||
rv = mFirst->QueryInterface(nsIBidirectionalEnumerator::GetIID(), (void**)&be);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
mCurrent = mFirst;
|
||||
rv = be->Last();
|
||||
NS_RELEASE(be);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewConjoiningEnumerator(nsIEnumerator* first, nsIEnumerator* second,
|
||||
nsIBidirectionalEnumerator* *aInstancePtrResult)
|
||||
{
|
||||
if (aInstancePtrResult == 0)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
nsConjoiningEnumerator* e = new nsConjoiningEnumerator(first, second);
|
||||
if (e == 0)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(e);
|
||||
*aInstancePtrResult = e;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static nsresult
|
||||
nsEnumeratorContains(nsIEnumerator* e, nsISupports* item)
|
||||
{
|
||||
nsresult rv;
|
||||
for (e->First(); e->IsDone() != NS_OK; e->Next()) {
|
||||
nsISupports* other;
|
||||
rv = e->CurrentItem(&other);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (item == other) {
|
||||
NS_RELEASE(other);
|
||||
return NS_OK; // true -- exists in enumerator
|
||||
}
|
||||
NS_RELEASE(other);
|
||||
}
|
||||
return NS_COMFALSE; // false -- doesn't exist
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Intersection Enumerators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsIntersectionEnumerator : public nsIEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIEnumerator methods:
|
||||
NS_IMETHOD First(void);
|
||||
NS_IMETHOD Next(void);
|
||||
NS_IMETHOD CurrentItem(nsISupports **aItem);
|
||||
NS_IMETHOD IsDone(void);
|
||||
|
||||
// nsIntersectionEnumerator methods:
|
||||
nsIntersectionEnumerator(nsIEnumerator* first, nsIEnumerator* second);
|
||||
virtual ~nsIntersectionEnumerator(void);
|
||||
|
||||
protected:
|
||||
nsIEnumerator* mFirst;
|
||||
nsIEnumerator* mSecond;
|
||||
};
|
||||
|
||||
nsIntersectionEnumerator::nsIntersectionEnumerator(nsIEnumerator* first, nsIEnumerator* second)
|
||||
: mFirst(first), mSecond(second)
|
||||
{
|
||||
NS_ADDREF(mFirst);
|
||||
NS_ADDREF(mSecond);
|
||||
}
|
||||
|
||||
nsIntersectionEnumerator::~nsIntersectionEnumerator(void)
|
||||
{
|
||||
NS_RELEASE(mFirst);
|
||||
NS_RELEASE(mSecond);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsIntersectionEnumerator, nsIEnumerator::GetIID());
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIntersectionEnumerator::First(void)
|
||||
{
|
||||
nsresult rv = mFirst->First();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return Next();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIntersectionEnumerator::Next(void)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// find the first item that exists in both
|
||||
for (; mFirst->IsDone() != NS_OK; mFirst->Next()) {
|
||||
nsISupports* item;
|
||||
rv = mFirst->CurrentItem(&item);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// see if it also exists in mSecond
|
||||
rv = nsEnumeratorContains(mSecond, item);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_RELEASE(item);
|
||||
if (rv == NS_OK) {
|
||||
// found in both, so return leaving it as the current item of mFirst
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIntersectionEnumerator::CurrentItem(nsISupports **aItem)
|
||||
{
|
||||
return mFirst->CurrentItem(aItem);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIntersectionEnumerator::IsDone(void)
|
||||
{
|
||||
return mFirst->IsDone();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewIntersectionEnumerator(nsIEnumerator* first, nsIEnumerator* second,
|
||||
nsIEnumerator* *aInstancePtrResult)
|
||||
{
|
||||
if (aInstancePtrResult == 0)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
nsIntersectionEnumerator* e = new nsIntersectionEnumerator(first, second);
|
||||
if (e == 0)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(e);
|
||||
*aInstancePtrResult = e;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Union Enumerators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsUnionEnumerator : public nsIEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIEnumerator methods:
|
||||
NS_IMETHOD First(void);
|
||||
NS_IMETHOD Next(void);
|
||||
NS_IMETHOD CurrentItem(nsISupports **aItem);
|
||||
NS_IMETHOD IsDone(void);
|
||||
|
||||
// nsUnionEnumerator methods:
|
||||
nsUnionEnumerator(nsIEnumerator* first, nsIEnumerator* second);
|
||||
virtual ~nsUnionEnumerator(void);
|
||||
|
||||
protected:
|
||||
nsIEnumerator* mFirst;
|
||||
nsIEnumerator* mSecond;
|
||||
};
|
||||
|
||||
nsUnionEnumerator::nsUnionEnumerator(nsIEnumerator* first, nsIEnumerator* second)
|
||||
: mFirst(first), mSecond(second)
|
||||
{
|
||||
NS_ADDREF(mFirst);
|
||||
NS_ADDREF(mSecond);
|
||||
}
|
||||
|
||||
nsUnionEnumerator::~nsUnionEnumerator(void)
|
||||
{
|
||||
NS_RELEASE(mFirst);
|
||||
NS_RELEASE(mSecond);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsUnionEnumerator, nsIEnumerator::GetIID());
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUnionEnumerator::First(void)
|
||||
{
|
||||
nsresult rv = mFirst->First();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return Next();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUnionEnumerator::Next(void)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// find the first item that exists in both
|
||||
for (; mFirst->IsDone() != NS_OK; mFirst->Next()) {
|
||||
nsISupports* item;
|
||||
rv = mFirst->CurrentItem(&item);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// see if it also exists in mSecond
|
||||
rv = nsEnumeratorContains(mSecond, item);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_RELEASE(item);
|
||||
if (rv != NS_OK) {
|
||||
// if it didn't exist in mSecond, return, making it the current item
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// each time around, make sure that mSecond gets reset to the beginning
|
||||
// so that when mFirst is done, we'll be ready to enumerate mSecond
|
||||
rv = mSecond->First();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
return mSecond->Next();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUnionEnumerator::CurrentItem(nsISupports **aItem)
|
||||
{
|
||||
if (mFirst->IsDone() != NS_OK)
|
||||
return mFirst->CurrentItem(aItem);
|
||||
else
|
||||
return mSecond->CurrentItem(aItem);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUnionEnumerator::IsDone(void)
|
||||
{
|
||||
return (mFirst->IsDone() == NS_OK && mSecond->IsDone() == NS_OK)
|
||||
? NS_OK : NS_COMFALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewUnionEnumerator(nsIEnumerator* first, nsIEnumerator* second,
|
||||
nsIEnumerator* *aInstancePtrResult)
|
||||
{
|
||||
if (aInstancePtrResult == 0)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
nsUnionEnumerator* e = new nsUnionEnumerator(first, second);
|
||||
if (e == 0)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(e);
|
||||
*aInstancePtrResult = e;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
569
mozilla/xpcom/ds/nsDeque.cpp
Normal file
569
mozilla/xpcom/ds/nsDeque.cpp
Normal file
@@ -0,0 +1,569 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "nsDeque.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
//#define _SELFTEST_DEQUE 1
|
||||
#undef _SELFTEST_DEQUE
|
||||
|
||||
/**
|
||||
* Standard constructor
|
||||
* @update gess4/18/98
|
||||
* @return new deque
|
||||
*/
|
||||
nsDeque::nsDeque(nsDequeFunctor* aDeallocator) {
|
||||
mDeallocator=aDeallocator;
|
||||
mCapacity=eGrowthDelta;
|
||||
mOrigin=mSize=0;
|
||||
mData=new void*[mCapacity];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
* @update gess4/18/98
|
||||
*/
|
||||
nsDeque::~nsDeque() {
|
||||
Erase();
|
||||
delete [] mData;
|
||||
mData=0;
|
||||
if(mDeallocator) {
|
||||
delete mDeallocator;
|
||||
}
|
||||
mDeallocator=0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of elements currently stored in
|
||||
* this deque.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param
|
||||
* @return int contains element count
|
||||
*/
|
||||
PRInt32 nsDeque::GetSize(void) const {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
void nsDeque::SetDeallocator(nsDequeFunctor* aDeallocator){
|
||||
if(mDeallocator) {
|
||||
delete mDeallocator;
|
||||
}
|
||||
mDeallocator=aDeallocator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all items from container without destroying them.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsDeque& nsDeque::Empty() {
|
||||
if((0<mCapacity) && (mData)) {
|
||||
nsCRT::zero(mData,mCapacity*sizeof(mData));
|
||||
}
|
||||
mSize=0;
|
||||
mOrigin=0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove and delete all items from container
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @return this
|
||||
*/
|
||||
nsDeque& nsDeque::Erase() {
|
||||
if(mDeallocator) {
|
||||
ForEach(*mDeallocator);
|
||||
}
|
||||
return Empty();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method adds an item to the end of the deque.
|
||||
* This operation has the potential to cause the
|
||||
* underlying buffer to resize.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param anItem: new item to be added to deque
|
||||
* @return nada
|
||||
*/
|
||||
nsDeque& nsDeque::GrowCapacity(void) {
|
||||
void** temp=new void*[mCapacity+eGrowthDelta];
|
||||
|
||||
//Here's the interesting part: You can't just move the elements
|
||||
//directy (in situ) from the old buffer to the new one.
|
||||
//Since capacity has changed, the old origin doesn't make
|
||||
//sense anymore. It's better to resequence the elements now.
|
||||
|
||||
int tempi=0;
|
||||
int i=0;
|
||||
int j=0;
|
||||
for(i=mOrigin;i<mCapacity;i++) temp[tempi++]=mData[i]; //copy the leading elements...
|
||||
for(j=0;j<mOrigin;j++) temp[tempi++]=mData[j]; //copy the trailing elements...
|
||||
mCapacity+=eGrowthDelta;
|
||||
mOrigin=0; //now realign the origin...
|
||||
delete[]mData;
|
||||
mData=temp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds an item to the end of the deque.
|
||||
* This operation has the potential to cause the
|
||||
* underlying buffer to resize.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param anItem: new item to be added to deque
|
||||
* @return nada
|
||||
*/
|
||||
nsDeque& nsDeque::Push(void* anItem) {
|
||||
if(mSize==mCapacity) {
|
||||
GrowCapacity();
|
||||
}
|
||||
int offset=mOrigin+mSize;
|
||||
if(offset<mCapacity)
|
||||
mData[offset]=anItem;
|
||||
else mData[offset-mCapacity]=anItem;
|
||||
mSize++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds an item to the front of the deque.
|
||||
* This operation has the potential to cause the
|
||||
* underlying buffer to resize.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param anItem: new item to be added to deque
|
||||
* @return nada
|
||||
*/
|
||||
nsDeque& nsDeque::PushFront(void* anItem) {
|
||||
if(mSize==mCapacity) {
|
||||
GrowCapacity();
|
||||
}
|
||||
if(0==mOrigin){ //case1: [xxx..]
|
||||
//mOrigin=mCapacity-1-mSize++;
|
||||
mOrigin=mCapacity-1;
|
||||
mData[mOrigin]=anItem;
|
||||
}
|
||||
else {// if(mCapacity==(mOrigin+mSize-1)){ //case2: [..xxx] and case3: [.xxx.]
|
||||
mData[--mOrigin]=anItem;
|
||||
}
|
||||
mSize++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove and return the last item in the container.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param none
|
||||
* @return ptr to last item in container
|
||||
*/
|
||||
void* nsDeque::Pop(void) {
|
||||
void* result=0;
|
||||
if(mSize>0) {
|
||||
int offset=mOrigin+mSize-1;
|
||||
if(offset>=mCapacity)
|
||||
offset-=mCapacity;
|
||||
result=mData[offset];
|
||||
mData[offset]=0;
|
||||
mSize--;
|
||||
if(0==mSize)
|
||||
mOrigin=0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called you want to remove and return
|
||||
* the first member in the container.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param nada
|
||||
* @return last item in container
|
||||
*/
|
||||
void* nsDeque::PopFront() {
|
||||
void* result=0;
|
||||
if(mSize>0) {
|
||||
result=mData[mOrigin];
|
||||
mData[mOrigin++]=0; //zero it out for debugging purposes.
|
||||
mSize--;
|
||||
if(mCapacity==mOrigin) //you popped off the end, so cycle back around...
|
||||
mOrigin=0;
|
||||
if(0==mSize)
|
||||
mOrigin=0;
|
||||
}
|
||||
NS_ASSERTION(mOrigin<mCapacity,"Error: Bad origin");
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called you want to peek at the topmost
|
||||
* member without removing it.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param nada
|
||||
* @return last item in container
|
||||
*/
|
||||
void* nsDeque::Peek() {
|
||||
void* result=0;
|
||||
if(mSize>0) {
|
||||
result=mData[mOrigin];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to retrieve the ith element from this container.
|
||||
* Keep in mind that accessing the underlying elements is
|
||||
* done in a relative fashion. Object 0 is not necessarily
|
||||
* the first element (the first element is at mOrigin).
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param anIndex : 0 relative offset of item you want
|
||||
* @return void* or null
|
||||
*/
|
||||
void* nsDeque::ObjectAt(PRInt32 anIndex) const {
|
||||
void* result=0;
|
||||
|
||||
if((anIndex>=0) && (anIndex<mSize))
|
||||
{
|
||||
if(anIndex<(mCapacity-mOrigin)) {
|
||||
result=mData[mOrigin+anIndex];
|
||||
}
|
||||
else {
|
||||
result=mData[anIndex-(mCapacity-mOrigin)];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return an iterator pointing to
|
||||
* the beginning of the queue. Note that this
|
||||
* takes the circular buffer semantics into account.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @return new deque iterator, init'ed to 1st item
|
||||
*/
|
||||
nsDequeIterator nsDeque::Begin(void) const{
|
||||
return nsDequeIterator(*this,0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return an iterator pointing to
|
||||
* the last of the queue. Note that this
|
||||
* takes the circular buffer semantics into account.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @return new deque iterator, init'ed to last item
|
||||
*/
|
||||
nsDequeIterator nsDeque::End(void) const{
|
||||
return nsDequeIterator(*this,mSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method when you wanto to iterate all the
|
||||
* members of the container, passing a functor along
|
||||
* to call your code.
|
||||
*
|
||||
* @update gess4/20/98
|
||||
* @param aFunctor object to call for each member
|
||||
* @return *this
|
||||
*/
|
||||
void nsDeque::ForEach(nsDequeFunctor& aFunctor) const{
|
||||
int i=0;
|
||||
for(i=0;i<mSize;i++){
|
||||
void* obj=ObjectAt(i);
|
||||
obj=aFunctor(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method when you wanto to iterate all the
|
||||
* members of the container, passing a functor along
|
||||
* to call your code. Iteration continues until your
|
||||
* functor returns a non-null.
|
||||
*
|
||||
* @update gess4/20/98
|
||||
* @param aFunctor object to call for each member
|
||||
* @return *this
|
||||
*/
|
||||
const void* nsDeque::FirstThat(nsDequeFunctor& aFunctor) const{
|
||||
int i=0;
|
||||
for(i=0;i<mSize;i++){
|
||||
void* obj=ObjectAt(i);
|
||||
obj=aFunctor(obj);
|
||||
if(obj)
|
||||
return obj;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Here comes the nsDequeIterator class...
|
||||
******************************************************/
|
||||
|
||||
/**
|
||||
* DequeIterator is an object that knows how to iterate (forward and backward)
|
||||
* a Deque. Normally, you don't need to do this, but there are some special
|
||||
* cases where it is pretty handy, so here you go.
|
||||
*
|
||||
* This is a standard dequeiterator constructor
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param aQueue is the deque object to be iterated
|
||||
* @param anIndex is the starting position for your iteration
|
||||
*/
|
||||
nsDequeIterator::nsDequeIterator(const nsDeque& aQueue,int anIndex): mIndex(anIndex), mDeque(aQueue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy construct a new iterator beginning with given
|
||||
*
|
||||
* @update gess4/20/98
|
||||
* @param aCopy is another iterator to copy from
|
||||
* @return
|
||||
*/
|
||||
nsDequeIterator::nsDequeIterator(const nsDequeIterator& aCopy) : mIndex(aCopy.mIndex), mDeque(aCopy.mDeque) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves iterator to first element in deque
|
||||
* @update gess4/18/98
|
||||
* @return this
|
||||
*/
|
||||
nsDequeIterator& nsDequeIterator::First(void){
|
||||
mIndex=0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard assignment operator for dequeiterator
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param aCopy is an iterator to be copied from
|
||||
* @return *this
|
||||
*/
|
||||
nsDequeIterator& nsDequeIterator::operator=(const nsDequeIterator& aCopy) {
|
||||
//queue's are already equal.
|
||||
mIndex=aCopy.mIndex;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* preform ! operation against to iterators to test for equivalence
|
||||
* (or lack thereof)!
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param anIter is the object to be compared to
|
||||
* @return TRUE if NOT equal.
|
||||
*/
|
||||
PRBool nsDequeIterator::operator!=(nsDequeIterator& anIter) {
|
||||
return PRBool(!this->operator==(anIter));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare 2 iterators for equivalence.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param anIter is the other iterator to be compared to
|
||||
* @return TRUE if EQUAL
|
||||
*/
|
||||
PRBool nsDequeIterator::operator<(nsDequeIterator& anIter) {
|
||||
return PRBool(((mIndex<anIter.mIndex) && (&mDeque==&anIter.mDeque)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare 2 iterators for equivalence.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param anIter is the other iterator to be compared to
|
||||
* @return TRUE if EQUAL
|
||||
*/
|
||||
PRBool nsDequeIterator::operator==(nsDequeIterator& anIter) {
|
||||
return PRBool(((mIndex==anIter.mIndex) && (&mDeque==&anIter.mDeque)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare 2 iterators for equivalence.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param anIter is the other iterator to be compared to
|
||||
* @return TRUE if EQUAL
|
||||
*/
|
||||
PRBool nsDequeIterator::operator>=(nsDequeIterator& anIter) {
|
||||
return PRBool(((mIndex>=anIter.mIndex) && (&mDeque==&anIter.mDeque)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-increment operator
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @return object at preincremented index
|
||||
*/
|
||||
void* nsDequeIterator::operator++() {
|
||||
return mDeque.ObjectAt(++mIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-increment operator
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param param is ignored
|
||||
* @return object at post-incremented index
|
||||
*/
|
||||
void* nsDequeIterator::operator++(int) {
|
||||
return mDeque.ObjectAt(mIndex++);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-decrement operator
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @return object at pre-decremented index
|
||||
*/
|
||||
void* nsDequeIterator::operator--() {
|
||||
return mDeque.ObjectAt(--mIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-decrement operator
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param param is ignored
|
||||
* @return object at post-decremented index
|
||||
*/
|
||||
void* nsDequeIterator::operator--(int) {
|
||||
return mDeque.ObjectAt(mIndex--);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dereference operator
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @return object at ith index
|
||||
*/
|
||||
void* nsDequeIterator::GetCurrent(void) {
|
||||
return mDeque.ObjectAt(mIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method when you wanto to iterate all the
|
||||
* members of the container, passing a functor along
|
||||
* to call your code.
|
||||
*
|
||||
* @update gess4/20/98
|
||||
* @param aFunctor object to call for each member
|
||||
* @return *this
|
||||
*/
|
||||
void nsDequeIterator::ForEach(nsDequeFunctor& aFunctor) const{
|
||||
mDeque.ForEach(aFunctor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method when you wanto to iterate all the
|
||||
* members of the container, passing a functor along
|
||||
* to call your code.
|
||||
*
|
||||
* @update gess4/20/98
|
||||
* @param aFunctor object to call for each member
|
||||
* @return *this
|
||||
*/
|
||||
const void* nsDequeIterator::FirstThat(nsDequeFunctor& aFunctor) const{
|
||||
return mDeque.FirstThat(aFunctor);
|
||||
}
|
||||
|
||||
#ifdef _SELFTEST_DEQUE
|
||||
/**************************************************************
|
||||
Now define the token deallocator class...
|
||||
**************************************************************/
|
||||
class _SelfTestDeallocator: public nsDequeFunctor{
|
||||
public:
|
||||
_SelfTestDeallocator::_SelfTestDeallocator() {
|
||||
nsDeque::SelfTest();
|
||||
}
|
||||
virtual void* operator()(void* anObject) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
static _SelfTestDeallocator gDeallocator;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* conduct automated self test for this class
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsDeque::SelfTest(void) {
|
||||
#ifdef _SELFTEST_DEQUE
|
||||
|
||||
{
|
||||
nsDeque theDeque(gDeallocator); //construct a simple one...
|
||||
|
||||
int ints[200];
|
||||
int count=sizeof(ints)/sizeof(int);
|
||||
int i=0;
|
||||
|
||||
for(i=0;i<count;i++){ //initialize'em
|
||||
ints[i]=10*(1+i);
|
||||
}
|
||||
|
||||
for(i=0;i<70;i++){
|
||||
theDeque.Push(&ints[i]);
|
||||
}
|
||||
|
||||
for(i=0;i<56;i++){
|
||||
int* temp=(int*)theDeque.Pop();
|
||||
}
|
||||
|
||||
for(i=0;i<55;i++){
|
||||
theDeque.Push(&ints[i]);
|
||||
}
|
||||
|
||||
for(i=0;i<35;i++){
|
||||
int* temp=(int*)theDeque.Pop();
|
||||
}
|
||||
|
||||
for(i=0;i<35;i++){
|
||||
theDeque.Push(&ints[i]);
|
||||
}
|
||||
|
||||
for(i=0;i<38;i++){
|
||||
int* temp=(int*)theDeque.Pop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int x;
|
||||
x=10;
|
||||
#endif
|
||||
}
|
||||
|
||||
411
mozilla/xpcom/ds/nsDeque.h
Normal file
411
mozilla/xpcom/ds/nsDeque.h
Normal file
@@ -0,0 +1,411 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* MODULE NOTES:
|
||||
* @update gess 4/15/98 (tax day)
|
||||
*
|
||||
* The Deque is a very small, very efficient container object
|
||||
* than can hold elements of type void*, offering the following features:
|
||||
* It's interface supports pushing and poping of children.
|
||||
* It can iterate (via an interator class) it's children.
|
||||
* When full, it can efficently resize dynamically.
|
||||
*
|
||||
*
|
||||
* NOTE: The only bit of trickery here is that this deque is
|
||||
* built upon a ring-buffer. Like all ring buffers, the first
|
||||
* element may not be at index[0]. The mOrigin member determines
|
||||
* where the first child is. This point is quietly hidden from
|
||||
* customers of this class.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NSDEQUE
|
||||
#define _NSDEQUE
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
/**
|
||||
* The nsDequefunctor class is used when you want to create
|
||||
* callbacks between the deque and your generic code.
|
||||
* Use these objects in a call to ForEach();
|
||||
*
|
||||
* @update gess4/20/98
|
||||
*/
|
||||
class NS_COM nsDequeFunctor{
|
||||
public:
|
||||
virtual void* operator()(void* anObject)=0;
|
||||
};
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Here comes the nsDeque class itself...
|
||||
******************************************************/
|
||||
|
||||
/**
|
||||
* The deque (double-ended queue) class is a common container type,
|
||||
* whose behavior mimics a line in your favorite checkout stand.
|
||||
* Classic CS describes the common behavior of a queue as FIFO.
|
||||
* A Deque allows items to be added and removed from either end of
|
||||
* the queue.
|
||||
*
|
||||
* @update gess4/20/98
|
||||
*/
|
||||
|
||||
class NS_COM nsDeque {
|
||||
friend class nsDequeIterator;
|
||||
public:
|
||||
nsDeque(nsDequeFunctor* aDeallocator);
|
||||
~nsDeque();
|
||||
|
||||
/**
|
||||
* Returns the number of elements currently stored in
|
||||
* this deque.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param
|
||||
* @return int contains element count
|
||||
*/
|
||||
PRInt32 GetSize() const;
|
||||
|
||||
|
||||
/**
|
||||
* Pushes new member onto the end of the deque
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param ptr to object to store
|
||||
* @return *this
|
||||
*/
|
||||
nsDeque& Push(void* anItem);
|
||||
|
||||
/**
|
||||
* Pushes new member onto the front of the deque
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param ptr to object to store
|
||||
* @return *this
|
||||
*/
|
||||
nsDeque& PushFront(void* anItem);
|
||||
|
||||
/**
|
||||
* Remove and return the first item in the container.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param none
|
||||
* @return ptr to first item in container
|
||||
*/
|
||||
void* Pop(void);
|
||||
|
||||
/**
|
||||
* Remove and return the first item in the container.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param none
|
||||
* @return ptr to first item in container
|
||||
*/
|
||||
void* PopFront(void);
|
||||
|
||||
|
||||
/**
|
||||
* Return topmost item without removing it.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param none
|
||||
* @return ptr to first item in container
|
||||
*/
|
||||
void* Peek(void);
|
||||
|
||||
/**
|
||||
* method used to retrieve ptr to
|
||||
* ith member in container. DOesn't remove
|
||||
* that item.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param index of desired item
|
||||
* @return ptr to ith element in list
|
||||
*/
|
||||
void* ObjectAt(int anIndex) const;
|
||||
|
||||
/**
|
||||
* Remove all items from container without destroying them
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsDeque& Empty();
|
||||
|
||||
/**
|
||||
* Remove and delete all items from container
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsDeque& Erase();
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new iterator, init'ed to start of container
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @return new dequeIterator
|
||||
*/
|
||||
nsDequeIterator Begin() const;
|
||||
|
||||
/**
|
||||
* Creates a new iterator, init'ed to end of container
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @return new dequeIterator
|
||||
*/
|
||||
nsDequeIterator End() const;
|
||||
|
||||
|
||||
/**
|
||||
* Call this method when you wanto to iterate all the
|
||||
* members of the container, passing a functor along
|
||||
* to call your code.
|
||||
*
|
||||
* @update gess4/20/98
|
||||
* @param aFunctor object to call for each member
|
||||
* @return *this
|
||||
*/
|
||||
void ForEach(nsDequeFunctor& aFunctor) const;
|
||||
|
||||
/**
|
||||
* Call this method when you wanto to iterate all the
|
||||
* members of the container, passing a functor along
|
||||
* to call your code. This process will interupt if
|
||||
* your function returns a null to this iterator.
|
||||
*
|
||||
* @update gess4/20/98
|
||||
* @param aFunctor object to call for each member
|
||||
* @return *this
|
||||
*/
|
||||
const void* FirstThat(nsDequeFunctor& aFunctor) const;
|
||||
|
||||
void SetDeallocator(nsDequeFunctor* aDeallocator);
|
||||
|
||||
/**
|
||||
* Perform automated selftest on the deque
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void SelfTest();
|
||||
|
||||
protected:
|
||||
|
||||
PRInt32 mSize;
|
||||
PRInt32 mCapacity;
|
||||
PRInt32 mOrigin;
|
||||
nsDequeFunctor* mDeallocator;
|
||||
void** mData;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
enum {eGrowthDelta=64};
|
||||
|
||||
/**
|
||||
* Simple default constructor (PRIVATE)
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsDeque();
|
||||
|
||||
/**
|
||||
* Copy constructor (PRIVATE)
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsDeque(const nsDeque& other);
|
||||
|
||||
/**
|
||||
* Deque assignment operator (PRIVATE)
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param another deque
|
||||
* @return *this
|
||||
*/
|
||||
nsDeque& operator=(const nsDeque& anOther);
|
||||
|
||||
nsDeque& GrowCapacity(void);
|
||||
|
||||
};
|
||||
|
||||
/******************************************************
|
||||
* Here comes the nsDequeIterator class...
|
||||
******************************************************/
|
||||
|
||||
class NS_COM nsDequeIterator {
|
||||
public:
|
||||
|
||||
/**
|
||||
* DequeIterator is an object that knows how to iterate (forward and backward)
|
||||
* a Deque. Normally, you don't need to do this, but there are some special
|
||||
* cases where it is pretty handy, so here you go.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param aQueue is the deque object to be iterated
|
||||
* @param anIndex is the starting position for your iteration
|
||||
*/
|
||||
nsDequeIterator(const nsDeque& aQueue,int anIndex=0);
|
||||
|
||||
/**
|
||||
* DequeIterator is an object that knows how to iterate (forward and backward)
|
||||
* a Deque. Normally, you don't need to do this, but there are some special
|
||||
* cases where it is pretty handy, so here you go.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param aQueue is the deque object to be iterated
|
||||
* @param anIndex is the starting position for your iteration
|
||||
*/
|
||||
nsDequeIterator(const nsDequeIterator& aCopy);
|
||||
|
||||
/**
|
||||
* Moves iterator to first element in deque
|
||||
* @update gess4/18/98
|
||||
* @return this
|
||||
*/
|
||||
nsDequeIterator& First(void);
|
||||
|
||||
/**
|
||||
* Standard assignment operator for deque
|
||||
* @update gess4/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsDequeIterator& operator=(const nsDequeIterator& aCopy);
|
||||
|
||||
/**
|
||||
* preform ! operation against to iterators to test for equivalence
|
||||
* (or lack thereof)!
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param anIter is the object to be compared to
|
||||
* @return TRUE if NOT equal.
|
||||
*/
|
||||
PRBool operator!=(nsDequeIterator& anIter);
|
||||
|
||||
/**
|
||||
* Compare 2 iterators for equivalence.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param anIter is the other iterator to be compared to
|
||||
* @return TRUE if EQUAL
|
||||
*/
|
||||
PRBool operator<(nsDequeIterator& anIter);
|
||||
|
||||
/**
|
||||
* Compare 2 iterators for equivalence.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param anIter is the other iterator to be compared to
|
||||
* @return TRUE if EQUAL
|
||||
*/
|
||||
PRBool operator==(nsDequeIterator& anIter);
|
||||
|
||||
/**
|
||||
* Compare 2 iterators for equivalence.
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param anIter is the other iterator to be compared to
|
||||
* @return TRUE if EQUAL
|
||||
*/
|
||||
PRBool operator>=(nsDequeIterator& anIter);
|
||||
|
||||
/**
|
||||
* Pre-increment operator
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @return object at preincremented index
|
||||
*/
|
||||
void* operator++();
|
||||
|
||||
/**
|
||||
* Post-increment operator
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param param is ignored
|
||||
* @return object at post-incremented index
|
||||
*/
|
||||
void* operator++(int);
|
||||
|
||||
/**
|
||||
* Pre-decrement operator
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @return object at pre-decremented index
|
||||
*/
|
||||
void* operator--();
|
||||
|
||||
/**
|
||||
* Post-decrement operator
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @param param is ignored
|
||||
* @return object at post-decremented index
|
||||
*/
|
||||
void* operator--(int);
|
||||
|
||||
/**
|
||||
* Retrieve the ptr to the iterators notion of current node
|
||||
*
|
||||
* @update gess4/18/98
|
||||
* @return object at ith index
|
||||
*/
|
||||
void* GetCurrent(void);
|
||||
|
||||
/**
|
||||
* Call this method when you wanto to iterate all the
|
||||
* members of the container, passing a functor along
|
||||
* to call your code.
|
||||
*
|
||||
* @update gess4/20/98
|
||||
* @param aFunctor object to call for each member
|
||||
* @return *this
|
||||
*/
|
||||
void ForEach(nsDequeFunctor& aFunctor) const;
|
||||
|
||||
/**
|
||||
* Call this method when you wanto to iterate all the
|
||||
* members of the container, passing a functor along
|
||||
* to call your code.
|
||||
*
|
||||
* @update gess4/20/98
|
||||
* @param aFunctor object to call for each member
|
||||
* @return *this
|
||||
*/
|
||||
const void* FirstThat(nsDequeFunctor& aFunctor) const;
|
||||
|
||||
protected:
|
||||
|
||||
PRInt32 mIndex;
|
||||
const nsDeque& mDeque;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
77
mozilla/xpcom/ds/nsEmptyEnumerator.cpp
Normal file
77
mozilla/xpcom/ds/nsEmptyEnumerator.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
An empty enumerator.
|
||||
|
||||
*/
|
||||
|
||||
#include "nsIEnumerator.h"
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class EmptyEnumeratorImpl : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
EmptyEnumeratorImpl(void) {};
|
||||
virtual ~EmptyEnumeratorImpl(void) {};
|
||||
|
||||
// nsISupports interface
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
NS_IMETHOD_(nsrefcnt) Release(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
NS_IMETHOD QueryInterface(REFNSIID iid, void** result) {
|
||||
if (! result)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (iid.Equals(nsISimpleEnumerator::GetIID()) ||
|
||||
iid.Equals(kISupportsIID)) {
|
||||
*result = (nsISimpleEnumerator*) this;
|
||||
NS_ADDREF(this);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
// nsISimpleEnumerator
|
||||
NS_IMETHOD HasMoreElements(PRBool* aResult) {
|
||||
*aResult = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetNext(nsISupports** aResult) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewEmptyEnumerator(nsISimpleEnumerator** aResult)
|
||||
{
|
||||
static EmptyEnumeratorImpl gEmptyEnumerator;
|
||||
*aResult = &gEmptyEnumerator;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
228
mozilla/xpcom/ds/nsEnumeratorUtils.cpp
Normal file
228
mozilla/xpcom/ds/nsEnumeratorUtils.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsEnumeratorUtils.h"
|
||||
|
||||
|
||||
nsArrayEnumerator::nsArrayEnumerator(nsISupportsArray* aValueArray)
|
||||
: mValueArray(aValueArray),
|
||||
mIndex(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
NS_IF_ADDREF(mValueArray);
|
||||
}
|
||||
|
||||
nsArrayEnumerator::~nsArrayEnumerator(void)
|
||||
{
|
||||
NS_IF_RELEASE(mValueArray);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsArrayEnumerator, nsISimpleEnumerator::GetIID());
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsArrayEnumerator::HasMoreElements(PRBool* aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult != 0, "null ptr");
|
||||
if (! aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
PRUint32 cnt;
|
||||
nsresult rv = mValueArray->Count(&cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
*aResult = (mIndex < (PRInt32) cnt);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsArrayEnumerator::GetNext(nsISupports** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult != 0, "null ptr");
|
||||
if (! aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
PRUint32 cnt;
|
||||
nsresult rv = mValueArray->Count(&cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (mIndex >= (PRInt32) cnt)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
*aResult = mValueArray->ElementAt(mIndex++);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewArrayEnumerator(nsISimpleEnumerator* *result,
|
||||
nsISupportsArray* array)
|
||||
{
|
||||
nsArrayEnumerator* enumer = new nsArrayEnumerator(array);
|
||||
if (enumer == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(enumer);
|
||||
*result = enumer;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsSingletonEnumerator::nsSingletonEnumerator(nsISupports* aValue)
|
||||
: mValue(aValue)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
NS_IF_ADDREF(mValue);
|
||||
mConsumed = (mValue ? PR_FALSE : PR_TRUE);
|
||||
}
|
||||
|
||||
nsSingletonEnumerator::~nsSingletonEnumerator()
|
||||
{
|
||||
NS_IF_RELEASE(mValue);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsSingletonEnumerator, nsISimpleEnumerator::GetIID());
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSingletonEnumerator::HasMoreElements(PRBool* aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult != 0, "null ptr");
|
||||
if (! aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aResult = !mConsumed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSingletonEnumerator::GetNext(nsISupports** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult != 0, "null ptr");
|
||||
if (! aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (mConsumed)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
mConsumed = PR_TRUE;
|
||||
|
||||
NS_ADDREF(mValue);
|
||||
*aResult = mValue;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewSingletonEnumerator(nsISimpleEnumerator* *result,
|
||||
nsISupports* singleton)
|
||||
{
|
||||
nsSingletonEnumerator* enumer = new nsSingletonEnumerator(singleton);
|
||||
if (enumer == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(enumer);
|
||||
*result = enumer;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
nsAdapterEnumerator::nsAdapterEnumerator(nsIEnumerator* aEnum)
|
||||
: mEnum(aEnum), mCurrent(0), mStarted(PR_FALSE)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
NS_ADDREF(mEnum);
|
||||
}
|
||||
|
||||
|
||||
nsAdapterEnumerator::~nsAdapterEnumerator()
|
||||
{
|
||||
NS_RELEASE(mEnum);
|
||||
NS_IF_RELEASE(mCurrent);
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAdapterEnumerator, nsISimpleEnumerator::GetIID());
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAdapterEnumerator::HasMoreElements(PRBool* aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (mCurrent) {
|
||||
*aResult = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (! mStarted) {
|
||||
mStarted = PR_TRUE;
|
||||
rv = mEnum->First();
|
||||
if (rv == NS_OK) {
|
||||
mEnum->CurrentItem(&mCurrent);
|
||||
*aResult = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
*aResult = PR_FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*aResult = PR_FALSE;
|
||||
|
||||
rv = mEnum->IsDone();
|
||||
if (rv != NS_OK) {
|
||||
// We're not done. Advance to the next one.
|
||||
rv = mEnum->Next();
|
||||
if (rv == NS_OK) {
|
||||
mEnum->CurrentItem(&mCurrent);
|
||||
*aResult = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAdapterEnumerator::GetNext(nsISupports** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
PRBool hasMore;
|
||||
rv = HasMoreElements(&hasMore);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (! hasMore)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
// No need to addref, we "transfer" the ownership to the caller.
|
||||
*aResult = mCurrent;
|
||||
mCurrent = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewAdapterEnumerator(nsISimpleEnumerator* *result,
|
||||
nsIEnumerator* enumerator)
|
||||
{
|
||||
nsAdapterEnumerator* enumer = new nsAdapterEnumerator(enumerator);
|
||||
if (enumer == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(enumer);
|
||||
*result = enumer;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
97
mozilla/xpcom/ds/nsEnumeratorUtils.h
Normal file
97
mozilla/xpcom/ds/nsEnumeratorUtils.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsEnumeratorUtils_h__
|
||||
#define nsEnumeratorUtils_h__
|
||||
|
||||
#include "nsIEnumerator.h"
|
||||
#include "nsISupportsArray.h"
|
||||
|
||||
class NS_COM nsArrayEnumerator : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsISimpleEnumerator interface
|
||||
NS_IMETHOD HasMoreElements(PRBool* aResult);
|
||||
NS_IMETHOD GetNext(nsISupports** aResult);
|
||||
|
||||
// nsRDFArrayEnumerator methods
|
||||
nsArrayEnumerator(nsISupportsArray* aValueArray);
|
||||
virtual ~nsArrayEnumerator(void);
|
||||
|
||||
protected:
|
||||
nsISupportsArray* mValueArray;
|
||||
PRInt32 mIndex;
|
||||
};
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewArrayEnumerator(nsISimpleEnumerator* *result,
|
||||
nsISupportsArray* array);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class NS_COM nsSingletonEnumerator : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsISimpleEnumerator methods
|
||||
NS_IMETHOD HasMoreElements(PRBool* aResult);
|
||||
NS_IMETHOD GetNext(nsISupports** aResult);
|
||||
|
||||
nsSingletonEnumerator(nsISupports* aValue);
|
||||
virtual ~nsSingletonEnumerator();
|
||||
|
||||
protected:
|
||||
nsISupports* mValue;
|
||||
PRBool mConsumed;
|
||||
};
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewSingletonEnumerator(nsISimpleEnumerator* *result,
|
||||
nsISupports* singleton);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class NS_COM nsAdapterEnumerator : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsISimpleEnumerator methods
|
||||
NS_IMETHOD HasMoreElements(PRBool* aResult);
|
||||
NS_IMETHOD GetNext(nsISupports** aResult);
|
||||
|
||||
nsAdapterEnumerator(nsIEnumerator* aEnum);
|
||||
virtual ~nsAdapterEnumerator();
|
||||
|
||||
protected:
|
||||
nsIEnumerator* mEnum;
|
||||
nsISupports* mCurrent;
|
||||
PRBool mStarted;
|
||||
};
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewAdapterEnumerator(nsISimpleEnumerator* *result,
|
||||
nsIEnumerator* enumerator);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif /* nsEnumeratorUtils_h__ */
|
||||
259
mozilla/xpcom/ds/nsHashtable.cpp
Normal file
259
mozilla/xpcom/ds/nsHashtable.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "prmem.h"
|
||||
#include "prlog.h"
|
||||
#include "nsHashtable.h"
|
||||
|
||||
//
|
||||
// Key operations
|
||||
//
|
||||
|
||||
static PR_CALLBACK PLHashNumber _hashValue(const void *key)
|
||||
{
|
||||
return ((const nsHashKey *) key)->HashValue();
|
||||
}
|
||||
|
||||
static PR_CALLBACK PRIntn _hashKeyCompare(const void *key1, const void *key2) {
|
||||
return ((const nsHashKey *) key1)->Equals((const nsHashKey *) key2);
|
||||
}
|
||||
|
||||
static PR_CALLBACK PRIntn _hashValueCompare(const void *value1,
|
||||
const void *value2) {
|
||||
// We're not going to make any assumptions about value equality
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Memory callbacks
|
||||
//
|
||||
|
||||
static PR_CALLBACK void *_hashAllocTable(void *pool, PRSize size) {
|
||||
return PR_MALLOC(size);
|
||||
}
|
||||
|
||||
static PR_CALLBACK void _hashFreeTable(void *pool, void *item) {
|
||||
PR_DELETE(item);
|
||||
}
|
||||
|
||||
static PR_CALLBACK PLHashEntry *_hashAllocEntry(void *pool, const void *key) {
|
||||
return PR_NEW(PLHashEntry);
|
||||
}
|
||||
|
||||
static PR_CALLBACK void _hashFreeEntry(void *pool, PLHashEntry *entry,
|
||||
PRUintn flag) {
|
||||
if (flag == HT_FREE_ENTRY) {
|
||||
delete (nsHashKey *) (entry->key);
|
||||
PR_DELETE(entry);
|
||||
}
|
||||
}
|
||||
|
||||
static PLHashAllocOps _hashAllocOps = {
|
||||
_hashAllocTable, _hashFreeTable,
|
||||
_hashAllocEntry, _hashFreeEntry
|
||||
};
|
||||
|
||||
//
|
||||
// Enumerator callback
|
||||
//
|
||||
|
||||
struct _HashEnumerateArgs {
|
||||
nsHashtableEnumFunc fn;
|
||||
void* arg;
|
||||
};
|
||||
|
||||
static PR_CALLBACK PRIntn _hashEnumerate(PLHashEntry *he, PRIntn i, void *arg)
|
||||
{
|
||||
_HashEnumerateArgs* thunk = (_HashEnumerateArgs*)arg;
|
||||
return thunk->fn((nsHashKey *) he->key, he->value, thunk->arg)
|
||||
? HT_ENUMERATE_NEXT
|
||||
: HT_ENUMERATE_STOP;
|
||||
}
|
||||
|
||||
//
|
||||
// HashKey
|
||||
//
|
||||
nsHashKey::nsHashKey(void)
|
||||
{
|
||||
}
|
||||
|
||||
nsHashKey::~nsHashKey(void)
|
||||
{
|
||||
}
|
||||
|
||||
nsHashtable::nsHashtable(PRUint32 aInitSize, PRBool threadSafe)
|
||||
: mLock(NULL)
|
||||
{
|
||||
hashtable = PL_NewHashTable(aInitSize,
|
||||
_hashValue,
|
||||
_hashKeyCompare,
|
||||
_hashValueCompare,
|
||||
&_hashAllocOps,
|
||||
NULL);
|
||||
if (threadSafe == PR_TRUE)
|
||||
{
|
||||
mLock = PR_NewLock();
|
||||
if (mLock == NULL)
|
||||
{
|
||||
// Cannot create a lock. If running on a multiprocessing system
|
||||
// we are sure to die.
|
||||
PR_ASSERT(mLock != NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsHashtable::~nsHashtable() {
|
||||
PL_HashTableDestroy(hashtable);
|
||||
if (mLock) PR_DestroyLock(mLock);
|
||||
}
|
||||
|
||||
PRBool nsHashtable::Exists(nsHashKey *aKey)
|
||||
{
|
||||
PLHashNumber hash = aKey->HashValue();
|
||||
|
||||
if (mLock) PR_Lock(mLock);
|
||||
|
||||
PLHashEntry **hep = PL_HashTableRawLookup(hashtable, hash, (void *) aKey);
|
||||
|
||||
if (mLock) PR_Unlock(mLock);
|
||||
|
||||
return *hep != NULL;
|
||||
}
|
||||
|
||||
void *nsHashtable::Put(nsHashKey *aKey, void *aData) {
|
||||
void *res = NULL;
|
||||
PLHashNumber hash = aKey->HashValue();
|
||||
PLHashEntry *he;
|
||||
|
||||
if (mLock) PR_Lock(mLock);
|
||||
|
||||
PLHashEntry **hep = PL_HashTableRawLookup(hashtable, hash, (void *) aKey);
|
||||
|
||||
if ((he = *hep) != NULL) {
|
||||
res = he->value;
|
||||
he->value = aData;
|
||||
} else {
|
||||
PL_HashTableRawAdd(hashtable, hep, hash,
|
||||
(void *) aKey->Clone(), aData);
|
||||
}
|
||||
|
||||
if (mLock) PR_Unlock(mLock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void *nsHashtable::Get(nsHashKey *aKey) {
|
||||
|
||||
if (mLock) PR_Lock(mLock);
|
||||
|
||||
void *ret = PL_HashTableLookup(hashtable, (void *) aKey);
|
||||
|
||||
if (mLock) PR_Unlock(mLock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *nsHashtable::Remove(nsHashKey *aKey) {
|
||||
PLHashNumber hash = aKey->HashValue();
|
||||
PLHashEntry *he;
|
||||
|
||||
if (mLock) PR_Lock(mLock);
|
||||
|
||||
PLHashEntry **hep = PL_HashTableRawLookup(hashtable, hash, (void *) aKey);
|
||||
void *res = NULL;
|
||||
|
||||
if ((he = *hep) != NULL) {
|
||||
res = he->value;
|
||||
PL_HashTableRawRemove(hashtable, hep, he);
|
||||
}
|
||||
|
||||
if (mLock) PR_Unlock(mLock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static PR_CALLBACK PRIntn _hashEnumerateCopy(PLHashEntry *he, PRIntn i, void *arg)
|
||||
{
|
||||
nsHashtable *newHashtable = (nsHashtable *)arg;
|
||||
newHashtable->Put((nsHashKey *) he->key, he->value);
|
||||
return HT_ENUMERATE_NEXT;
|
||||
}
|
||||
|
||||
nsHashtable * nsHashtable::Clone() {
|
||||
PRBool threadSafe = PR_FALSE;
|
||||
if (mLock)
|
||||
threadSafe = PR_TRUE;
|
||||
nsHashtable *newHashTable = new nsHashtable(hashtable->nentries, threadSafe);
|
||||
|
||||
PL_HashTableEnumerateEntries(hashtable, _hashEnumerateCopy, newHashTable);
|
||||
return newHashTable;
|
||||
}
|
||||
|
||||
void nsHashtable::Enumerate(nsHashtableEnumFunc aEnumFunc, void* closure) {
|
||||
_HashEnumerateArgs thunk;
|
||||
thunk.fn = aEnumFunc;
|
||||
thunk.arg = closure;
|
||||
PL_HashTableEnumerateEntries(hashtable, _hashEnumerate, &thunk);
|
||||
}
|
||||
|
||||
static PR_CALLBACK PRIntn _hashEnumerateRemove(PLHashEntry *he, PRIntn i, void *arg)
|
||||
{
|
||||
return HT_ENUMERATE_REMOVE;
|
||||
}
|
||||
|
||||
void nsHashtable::Reset() {
|
||||
PL_HashTableEnumerateEntries(hashtable, _hashEnumerateRemove, NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsCStringKey::nsCStringKey(const char* str)
|
||||
: mStr(mBuf)
|
||||
{
|
||||
PRUint32 len = PL_strlen(str);
|
||||
if (len >= sizeof(mBuf)) {
|
||||
mStr = PL_strdup(str);
|
||||
NS_ASSERTION(mStr, "out of memory");
|
||||
}
|
||||
else {
|
||||
PL_strcpy(mStr, str);
|
||||
}
|
||||
}
|
||||
|
||||
nsCStringKey::~nsCStringKey(void)
|
||||
{
|
||||
if (mStr != mBuf)
|
||||
PL_strfree(mStr);
|
||||
}
|
||||
|
||||
PRUint32 nsCStringKey::HashValue(void) const
|
||||
{
|
||||
return (PRUint32) PL_HashString((const void*) mStr);
|
||||
}
|
||||
|
||||
PRBool nsCStringKey::Equals(const nsHashKey* aKey) const
|
||||
{
|
||||
return PL_strcmp( ((nsCStringKey*)aKey)->mStr, mStr ) == 0;
|
||||
}
|
||||
|
||||
nsHashKey* nsCStringKey::Clone() const
|
||||
{
|
||||
return new nsCStringKey(mStr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user