@agoric/xsnap 0.14.3-dev-b047af2.0 → 0.14.3-dev-3eb4230.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/api.js +1 -1
  2. package/package.json +16 -23
  3. package/src/build.js +4 -61
  4. package/moddable/modules/data/base64/base64.js +0 -28
  5. package/moddable/modules/data/base64/manifest.json +0 -11
  6. package/moddable/modules/data/base64/modBase64.c +0 -188
  7. package/moddable/modules/data/binaryMessage/BinaryMessage.js +0 -106
  8. package/moddable/modules/data/crc/crc.c +0 -205
  9. package/moddable/modules/data/crc/crc.js +0 -36
  10. package/moddable/modules/data/crc/manifest.json +0 -8
  11. package/moddable/modules/data/hex/hex.js +0 -28
  12. package/moddable/modules/data/hex/manifest.json +0 -11
  13. package/moddable/modules/data/hex/modHex.c +0 -139
  14. package/moddable/modules/data/logical/logical.js +0 -32
  15. package/moddable/modules/data/logical/modLogical.c +0 -98
  16. package/moddable/modules/data/qrcode/manifest.json +0 -9
  17. package/moddable/modules/data/qrcode/qrcode.c +0 -93
  18. package/moddable/modules/data/qrcode/qrcode.js +0 -23
  19. package/moddable/modules/data/qrcode/qrcodegen.c +0 -1025
  20. package/moddable/modules/data/qrcode/qrcodegen.h +0 -267
  21. package/moddable/modules/data/text/decoder/manifest.json +0 -8
  22. package/moddable/modules/data/text/decoder/textdecoder.c +0 -480
  23. package/moddable/modules/data/text/decoder/textdecoder.js +0 -27
  24. package/moddable/modules/data/text/encoder/manifest.json +0 -8
  25. package/moddable/modules/data/text/encoder/textencoder.c +0 -232
  26. package/moddable/modules/data/text/encoder/textencoder.js +0 -24
  27. package/moddable/modules/data/tinyint/tinyint.c +0 -150
  28. package/moddable/modules/data/tinyint/tinyint.js +0 -53
  29. package/moddable/modules/data/url/manifest.json +0 -17
  30. package/moddable/modules/data/url/url.c +0 -1959
  31. package/moddable/modules/data/url/url.js +0 -210
  32. package/moddable/modules/data/wavreader/manifest.json +0 -8
  33. package/moddable/modules/data/wavreader/wavreader.js +0 -128
  34. package/moddable/modules/data/zlib/deflate.c +0 -161
  35. package/moddable/modules/data/zlib/deflate.js +0 -63
  36. package/moddable/modules/data/zlib/inflate.c +0 -145
  37. package/moddable/modules/data/zlib/inflate.js +0 -66
  38. package/moddable/modules/data/zlib/manifest_deflate.json +0 -9
  39. package/moddable/modules/data/zlib/manifest_inflate.json +0 -9
  40. package/moddable/modules/data/zlib/miniz.c +0 -4924
  41. package/moddable/xs/includes/xs.d.ts +0 -73
  42. package/moddable/xs/includes/xs.h +0 -1533
  43. package/moddable/xs/includes/xsmc.h +0 -206
  44. package/moddable/xs/makefiles/lin/makefile +0 -33
  45. package/moddable/xs/makefiles/lin/xsc.mk +0 -118
  46. package/moddable/xs/makefiles/lin/xsid.mk +0 -90
  47. package/moddable/xs/makefiles/lin/xsl.mk +0 -168
  48. package/moddable/xs/makefiles/lin/xst.mk +0 -201
  49. package/moddable/xs/makefiles/mac/makefile +0 -33
  50. package/moddable/xs/makefiles/mac/xsc.mk +0 -130
  51. package/moddable/xs/makefiles/mac/xsid.mk +0 -102
  52. package/moddable/xs/makefiles/mac/xsl.mk +0 -177
  53. package/moddable/xs/makefiles/mac/xst.mk +0 -203
  54. package/moddable/xs/makefiles/mac/xst_no_asan.txt +0 -52
  55. package/moddable/xs/makefiles/win/build.bat +0 -26
  56. package/moddable/xs/makefiles/win/xsc.mak +0 -142
  57. package/moddable/xs/makefiles/win/xsid.mak +0 -113
  58. package/moddable/xs/makefiles/win/xsl.mak +0 -186
  59. package/moddable/xs/makefiles/win/xst.mak +0 -195
  60. package/moddable/xs/platforms/lin_xs.h +0 -99
  61. package/moddable/xs/platforms/mac_xs.h +0 -97
  62. package/moddable/xs/platforms/wasm_xs.h +0 -79
  63. package/moddable/xs/platforms/win_xs.h +0 -104
  64. package/moddable/xs/platforms/xsHost.h +0 -63
  65. package/moddable/xs/platforms/xsPlatform.h +0 -618
  66. package/moddable/xs/sources/xsAPI.c +0 -2555
  67. package/moddable/xs/sources/xsAll.c +0 -294
  68. package/moddable/xs/sources/xsAll.h +0 -2741
  69. package/moddable/xs/sources/xsArguments.c +0 -222
  70. package/moddable/xs/sources/xsArray.c +0 -2657
  71. package/moddable/xs/sources/xsAtomics.c +0 -844
  72. package/moddable/xs/sources/xsBigInt.c +0 -1859
  73. package/moddable/xs/sources/xsBoolean.c +0 -109
  74. package/moddable/xs/sources/xsCode.c +0 -4493
  75. package/moddable/xs/sources/xsCommon.c +0 -1710
  76. package/moddable/xs/sources/xsCommon.h +0 -1142
  77. package/moddable/xs/sources/xsDataView.c +0 -2890
  78. package/moddable/xs/sources/xsDate.c +0 -1541
  79. package/moddable/xs/sources/xsDebug.c +0 -2710
  80. package/moddable/xs/sources/xsDefaults.c +0 -134
  81. package/moddable/xs/sources/xsError.c +0 -353
  82. package/moddable/xs/sources/xsFunction.c +0 -776
  83. package/moddable/xs/sources/xsGenerator.c +0 -865
  84. package/moddable/xs/sources/xsGlobal.c +0 -839
  85. package/moddable/xs/sources/xsJSON.c +0 -1091
  86. package/moddable/xs/sources/xsLexical.c +0 -1969
  87. package/moddable/xs/sources/xsLockdown.c +0 -933
  88. package/moddable/xs/sources/xsMapSet.c +0 -1649
  89. package/moddable/xs/sources/xsMarshall.c +0 -1020
  90. package/moddable/xs/sources/xsMath.c +0 -624
  91. package/moddable/xs/sources/xsMemory.c +0 -1941
  92. package/moddable/xs/sources/xsModule.c +0 -3101
  93. package/moddable/xs/sources/xsNumber.c +0 -560
  94. package/moddable/xs/sources/xsObject.c +0 -1102
  95. package/moddable/xs/sources/xsPlatforms.c +0 -480
  96. package/moddable/xs/sources/xsProfile.c +0 -577
  97. package/moddable/xs/sources/xsPromise.c +0 -1199
  98. package/moddable/xs/sources/xsProperty.c +0 -636
  99. package/moddable/xs/sources/xsProxy.c +0 -1014
  100. package/moddable/xs/sources/xsRegExp.c +0 -1168
  101. package/moddable/xs/sources/xsRun.c +0 -4889
  102. package/moddable/xs/sources/xsScope.c +0 -1293
  103. package/moddable/xs/sources/xsScript.c +0 -288
  104. package/moddable/xs/sources/xsScript.h +0 -1186
  105. package/moddable/xs/sources/xsSnapshot.c +0 -2161
  106. package/moddable/xs/sources/xsSnapshot.h +0 -51
  107. package/moddable/xs/sources/xsSourceMap.c +0 -218
  108. package/moddable/xs/sources/xsString.c +0 -3332
  109. package/moddable/xs/sources/xsSymbol.c +0 -503
  110. package/moddable/xs/sources/xsSyntaxical.c +0 -4193
  111. package/moddable/xs/sources/xsTree.c +0 -1893
  112. package/moddable/xs/sources/xsType.c +0 -1488
  113. package/moddable/xs/sources/xsdtoa.c +0 -6672
  114. package/moddable/xs/sources/xsmc.c +0 -340
  115. package/moddable/xs/sources/xsre.c +0 -7578
  116. package/xsnap-native/xsnap/makefiles/lin/makefile +0 -10
  117. package/xsnap-native/xsnap/makefiles/lin/xsnap-worker.mk +0 -153
  118. package/xsnap-native/xsnap/makefiles/lin/xsnap.mk +0 -144
  119. package/xsnap-native/xsnap/makefiles/mac/makefile +0 -10
  120. package/xsnap-native/xsnap/makefiles/mac/xsnap-worker.mk +0 -162
  121. package/xsnap-native/xsnap/makefiles/mac/xsnap.mk +0 -153
  122. package/xsnap-native/xsnap/sources/xsnap-worker.c +0 -996
  123. package/xsnap-native/xsnap/sources/xsnap.c +0 -716
  124. package/xsnap-native/xsnap/sources/xsnap.h +0 -142
  125. package/xsnap-native/xsnap/sources/xsnapPlatform.c +0 -1496
  126. package/xsnap-native/xsnap/sources/xsnapPlatform.h +0 -105
@@ -1,1959 +0,0 @@
1
- /*
2
- * Copyright (c) 2021-2022 Moddable Tech, Inc.
3
- *
4
- * This file is part of the Moddable SDK Runtime.
5
- *
6
- * The Moddable SDK Runtime is free software: you can redistribute it and/or modify
7
- * it under the terms of the GNU Lesser General Public License as published by
8
- * the Free Software Foundation, either version 3 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * The Moddable SDK Runtime is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU Lesser General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU Lesser General Public License
17
- * along with the Moddable SDK Runtime. If not, see <http://www.gnu.org/licenses/>.
18
- *
19
- */
20
-
21
- #include "xsAll.h"
22
- #ifdef kPocoRotation
23
- #include "mc.xs.h"
24
- #define MODDABLE_MODULE 1
25
- #else
26
- #define xsID_scheme fxID(the, "scheme")
27
- #define xsID_username fxID(the, "username")
28
- #define xsID_password fxID(the, "password")
29
- #define xsID_host fxID(the, "host")
30
- #define xsID_port fxID(the, "port")
31
- #define xsID_path fxID(the, "path")
32
- #define xsID_query fxID(the, "query")
33
- #define xsID_fragment fxID(the, "fragment")
34
- extern void fx_parseURL(txMachine* the);
35
- extern void fx_serializeURL(txMachine* the);
36
- extern void fx_parseQuery(txMachine* the);
37
- extern void fx_serializeQuery(txMachine* the);
38
- #endif
39
-
40
-
41
- static void fx_parseURLCopyPart(txMachine* the, txSlot* src, txSlot* dst, txID id);
42
- static void fx_parseURLCopyPath(txMachine* the, txSlot* src, txSlot* dst);
43
- static txInteger fx_parseURLDecode(txMachine* the, txStringStream* stream);
44
- static void fx_parseURLEncode(txMachine* the, txInteger c, txStringStream* dst);
45
- static void fx_parseURLEmptyPart(txMachine* the, txSlot* target, txID id);
46
- static txBoolean fx_parseURLHasOpaquePath(txMachine* the, txSlot* parts);
47
- static txBoolean fx_parseURLHost(txMachine* the, txStringStream* src, txInteger from, txInteger to, txStringStream* dst, txBoolean special);
48
- static txBoolean fx_parseURLHostIPv4(txMachine* the, txStringStream* src, txInteger from, txInteger to, txStringStream* dst);
49
- static txBoolean fx_parseURLHostIPv6(txMachine* the, txStringStream* src, txInteger from, txInteger to, txStringStream* dst);
50
- static txBoolean fx_parseURLHostNotSpecial(txMachine* the, txStringStream* src, txInteger from, txInteger to, txStringStream* dst);
51
- static txBoolean fx_parseURLHostSpecial(txMachine* the, txStringStream* src, txInteger from, txInteger to, txStringStream* dst);
52
- static void fx_parseURLNullPart(txMachine* the, txSlot* target, txID id);
53
- static txBoolean fx_parseURLIsPartEmpty(txMachine* the, txSlot* parts, txID id);
54
- static txBoolean fx_parseURLIsWindowsDriveLetter(txMachine* the, txString string, txBoolean startsWith);
55
- static void fx_parseURLPercentEncode(txMachine* the, txInteger c, txStringStream* dst, const char* set);
56
- static void fx_parseURLPushPath(txMachine* the, txSlot* path, txStringStream* dst, txBoolean flag);
57
- static void fx_parseURLSetPart(txMachine* the, txSlot* target, txID id, txIndex index, txStringStream* dst);
58
- static void fx_parseURLShortenPath(txMachine* the, txSlot* path);
59
- static txInteger fx_parseURLSpecialScheme(txMachine* the, txString scheme);
60
- static void fx_parseQueryPlus(txMachine* the, txSlot* string, txInteger from, txInteger to);
61
- static void fx_serializeQueryPlus(txMachine* the, txString theSet);
62
-
63
- static const char ICACHE_RODATA_ATTR gxControlSet[128] = {
64
- /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
65
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0x */
66
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1x */
67
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2x !"#$%&'()*+,-./ */
68
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */
69
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4x @ABCDEFGHIJKLMNO */
70
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5X PQRSTUVWXYZ[\]^_ */
71
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6x `abcdefghijklmno */
72
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 /* 7X pqrstuvwxyz{|}~ */
73
- };
74
-
75
- static const char ICACHE_RODATA_ATTR gxUserInfoSet[128] = {
76
- /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
77
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0x */
78
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1x */
79
- 1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1, /* 2x !"#$%&'()*+,-./ */
80
- 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1, /* 3x 0123456789:;<=>? */
81
- 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4x @ABCDEFGHIJKLMNO */
82
- 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0, /* 5X PQRSTUVWXYZ[\]^_ */
83
- 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6x `abcdefghijklmno */
84
- 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1 /* 7X pqrstuvwxyz{|}~ */
85
- };
86
-
87
- static const char ICACHE_RODATA_ATTR gxNotSpecialHostSet[128] = {
88
- /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
89
- 1,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0, /* 0x */
90
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1x */
91
- 1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1, /* 2x !"#$%&'()*+,-./ */
92
- 0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,1, /* 3x 0123456789:;<=>? */
93
- 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4x @ABCDEFGHIJKLMNO */
94
- 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0, /* 5X PQRSTUVWXYZ[\]^_ */
95
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6x `abcdefghijklmno */
96
- 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0 /* 7X pqrstuvwxyz{|}~ */
97
- };
98
-
99
- static const char ICACHE_RODATA_ATTR gxSpecialHostSet[128] = {
100
- /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
101
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0x */
102
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1x */
103
- 1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1, /* 2x !"#$%&'()*+,-./ */
104
- 0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,1, /* 3x 0123456789:;<=>? */
105
- 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4x @ABCDEFGHIJKLMNO */
106
- 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0, /* 5X PQRSTUVWXYZ[\]^_ */
107
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6x `abcdefghijklmno */
108
- 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1 /* 7X pqrstuvwxyz{|}~ */
109
- };
110
-
111
- static const char ICACHE_RODATA_ATTR gxPathSet[128] = {
112
- /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
113
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0x */
114
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1x */
115
- 1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 2x !"#$%&'()*+,-./ */
116
- 0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1, /* 3x 0123456789:;<=>? */
117
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4x @ABCDEFGHIJKLMNO */
118
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5X PQRSTUVWXYZ[\]^_ */
119
- 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6x `abcdefghijklmno */
120
- 0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1 /* 7X pqrstuvwxyz{|}~ */
121
- };
122
-
123
- static const char ICACHE_RODATA_ATTR gxQuerySet[128] = {
124
- /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
125
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0x */
126
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1x */
127
- 1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 2x !"#$%&'()*+,-./ */
128
- 0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, /* 3x 0123456789:;<=>? */
129
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4x @ABCDEFGHIJKLMNO */
130
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5X PQRSTUVWXYZ[\]^_ */
131
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6x `abcdefghijklmno */
132
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 /* 7X pqrstuvwxyz{|}~ */
133
- };
134
- static const char ICACHE_RODATA_ATTR gxSpecialQuerySet[128] = {
135
- /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
136
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0x */
137
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1x */
138
- 1,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0, /* 2x !"#$%&'()*+,-./ */
139
- 0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, /* 3x 0123456789:;<=>? */
140
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4x @ABCDEFGHIJKLMNO */
141
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5X PQRSTUVWXYZ[\]^_ */
142
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6x `abcdefghijklmno */
143
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 /* 7X pqrstuvwxyz{|}~ */
144
- };
145
-
146
- static const char ICACHE_RODATA_ATTR gxFragmentSet[128] = {
147
- /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
148
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0x */
149
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1x */
150
- 1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2x !"#$%&'()*+,-./ */
151
- 0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, /* 3x 0123456789:;<=>? */
152
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4x @ABCDEFGHIJKLMNO */
153
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5X PQRSTUVWXYZ[\]^_ */
154
- 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6x `abcdefghijklmno */
155
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 /* 7X pqrstuvwxyz{|}~ */
156
- };
157
-
158
- static const char ICACHE_RODATA_ATTR gxFormSet[128] = {
159
- /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
160
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x */
161
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1x */
162
- 0,0,1,0,0,0,0,0,0,0,1,0,0,1,1,0, /* 2x !"#$%&'()*+,-./ */
163
- 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */
164
- 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4x @ABCDEFGHIJKLMNO */
165
- 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, /* 5X PQRSTUVWXYZ[\]^_ */
166
- 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6x `abcdefghijklmno */
167
- 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, /* 7X pqrstuvwxyz{|}~ */
168
- };
169
-
170
- static const char gxHexLower[] ICACHE_FLASH_ATTR = "0123456789abcdef";
171
-
172
- #define mx_parseURLBufferSize 64
173
- #define mx_parseURLSpecialSchemeCount 6
174
- static const txString gx_parseURLSpecialSchemeNames[mx_parseURLSpecialSchemeCount] = {
175
- "file",
176
- "ftp",
177
- "http",
178
- "https",
179
- "ws",
180
- "wss",
181
- };
182
- static const txInteger gx_parseURLSpecialSchemePorts[mx_parseURLSpecialSchemeCount] = {
183
- 0,
184
- 21,
185
- 80,
186
- 443,
187
- 80,
188
- 443,
189
- };
190
-
191
- enum {
192
- SCHEME_STATE = 1,
193
- USERNAME_STATE,
194
- PASSWORD_STATE,
195
- HOST_PORT_STATE,
196
- HOST_STATE,
197
- PORT_STATE,
198
- PATH_STATE,
199
- QUERY_STATE,
200
- FRAGMENT_STATE,
201
- ORIGIN_STATE,
202
- };
203
-
204
- void fx_parseURL(txMachine* the)
205
- {
206
- txStringStream _src;
207
- txStringStream* src = &_src;
208
- txStringStream _dst;
209
- txStringStream* dst = &_dst;
210
-
211
- txInteger override = 0;
212
- txInteger overrideSchemeIndex = -1;
213
- txBoolean overrideSpecial = 0;
214
-
215
- txSlot* base = C_NULL;
216
- txInteger baseSchemeIndex = -1;
217
- txBoolean baseSpecial = 0;
218
-
219
- txSlot* result = C_NULL;
220
- txInteger schemeIndex = -1;
221
- txBoolean special = 0;
222
-
223
- txInteger atOffset = -1;
224
- txInteger colonOffset = -1;
225
- txInteger hostOffset = -1;
226
- txSize tmp;
227
- txBoolean insideBracket = 0;
228
-
229
- txIndex length;
230
- txInteger c;
231
- txNumber port;
232
-
233
- fxVars(the, 3);
234
- src->slot = mxArgv(0);
235
- src->offset = 0;
236
- src->size = mxStringLength(fxToString(the, mxArgv(0)));
237
- mxVarv(0)->value.string = fxNewChunk(the, mx_parseURLBufferSize);
238
- mxVarv(0)->kind = XS_STRING_KIND;
239
- dst->slot = mxVarv(0);
240
- dst->slot->value.string[0] = 0;
241
- dst->offset = 0;
242
- dst->size = mx_parseURLBufferSize;
243
-
244
- if (mxArgc > 2) {
245
- *mxResult = *mxArgv(1);
246
- result = mxResult;
247
-
248
- override = fxToInteger(the, mxArgv(2));
249
- mxPushSlot(result);
250
- mxGetID(xsID_scheme);
251
- overrideSchemeIndex = fx_parseURLSpecialScheme(the, the->stack->value.string);
252
- mxPop();
253
- overrideSpecial = overrideSchemeIndex >= 0;
254
-
255
- if (override == SCHEME_STATE) {
256
- goto XS_URL_SCHEME_START;
257
- }
258
- schemeIndex = overrideSchemeIndex;
259
- special = overrideSpecial;
260
- if (override == USERNAME_STATE) {
261
- if ((schemeIndex == 0) || fx_parseURLIsPartEmpty(the, result, xsID_host))
262
- goto XS_URL_END;
263
- goto XS_URL_USERNAME;
264
- }
265
- if (override == PASSWORD_STATE) {
266
- if ((schemeIndex == 0) || fx_parseURLIsPartEmpty(the, result, xsID_host))
267
- goto XS_URL_END;
268
- goto XS_URL_PASSWORD;
269
- }
270
- if (override == HOST_PORT_STATE) {
271
- if (fx_parseURLHasOpaquePath(the, result))
272
- goto XS_URL_END;
273
- hostOffset = 0;
274
- if (schemeIndex == 0)
275
- goto XS_URL_FILE_HOST;
276
- goto XS_URL_HOST;
277
- }
278
- if (override == HOST_STATE) {
279
- if (fx_parseURLHasOpaquePath(the, result))
280
- goto XS_URL_END;
281
- hostOffset = 0;
282
- if (schemeIndex == 0)
283
- goto XS_URL_FILE_HOST;
284
- goto XS_URL_HOST;
285
- }
286
- if (override == PORT_STATE) {
287
- if ((schemeIndex == 0) || fx_parseURLIsPartEmpty(the, result, xsID_host))
288
- goto XS_URL_END;
289
- goto XS_URL_PORT;
290
- }
291
- if (override == PATH_STATE) {
292
- if (fx_parseURLHasOpaquePath(the, result))
293
- goto XS_URL_END;
294
- mxPushInteger(0);
295
- mxPushSlot(result);
296
- mxSetID(mxID(_length));
297
- mxPop();
298
- c = fx_parseURLDecode(the, src);
299
- if ((c != '/') && (!special || (c != '\\')))
300
- src->offset = 0;
301
- goto XS_URL_PATH;
302
- }
303
- if (override == QUERY_STATE) {
304
- if (src->size == 0) {
305
- fx_parseURLNullPart(the, result, xsID_query);
306
- goto XS_URL_END;
307
- }
308
- fx_parseURLEmptyPart(the, result, xsID_query);
309
- c = fx_parseURLDecode(the, src);
310
- if (c != '?')
311
- src->offset = 0;
312
- goto XS_URL_QUERY;
313
- }
314
- if (override == FRAGMENT_STATE) {
315
- if (src->size == 0) {
316
- fx_parseURLNullPart(the, result, xsID_fragment);
317
- goto XS_URL_END;
318
- }
319
- fx_parseURLEmptyPart(the, result, xsID_fragment);
320
- c = fx_parseURLDecode(the, src);
321
- if (c != '#')
322
- src->offset = 0;
323
- goto XS_URL_FRAGMENT;
324
- }
325
- goto XS_URL_ERROR;
326
- }
327
- else {
328
- fxNewArray(the, 0);
329
- mxPullSlot(mxResult);
330
- result = mxResult;
331
-
332
- fx_parseURLEmptyPart(the, result, xsID_username);
333
- fx_parseURLEmptyPart(the, result, xsID_password);
334
- fx_parseURLNullPart(the, result, xsID_host);
335
- fx_parseURLEmptyPart(the, result, xsID_port);
336
- fx_parseURLNullPart(the, result, xsID_query);
337
- fx_parseURLNullPart(the, result, xsID_fragment);
338
-
339
- if ((mxArgc > 1) && mxIsReference(mxArgv(1))) {
340
- base = mxArgv(1);
341
- mxPushSlot(base);
342
- mxGetID(xsID_scheme);
343
- baseSchemeIndex = fx_parseURLSpecialScheme(the, the->stack->value.string);
344
- mxPop();
345
- baseSpecial = baseSchemeIndex >= 0;
346
- }
347
- }
348
-
349
- for (;;) {
350
- c = fx_parseURLDecode(the, src);
351
- if (c == C_EOF)
352
- break;
353
- if ((c > 0x20) && (c != 0x7F)) {
354
- fx_parseURLEncode(the, c, dst);
355
- break;
356
- }
357
- }
358
- if (c != C_EOF) {
359
- tmp = -1;
360
- for (;;) {
361
- c = fx_parseURLDecode(the, src);
362
- if (c == C_EOF)
363
- break;
364
- if ((c > 0x20) && (c != 0x7F))
365
- tmp = -1;
366
- else if (tmp < 0)
367
- tmp = dst->offset;
368
- if ((c != 9) && (c != 10) && (c != 13))
369
- fx_parseURLEncode(the, c, dst);
370
- }
371
- if (tmp >= 0) {
372
- dst->offset = tmp;
373
- dst->slot->value.string[tmp] = 0;
374
- }
375
- }
376
- src->slot = dst->slot;
377
- src->offset = 0;
378
- src->size = dst->size;
379
- mxArgv(0)->value.string = fxNewChunk(the, mx_parseURLBufferSize);
380
- mxArgv(0)->kind = XS_STRING_KIND;
381
- dst->slot = mxArgv(0);
382
- dst->slot->value.string[0] = 0;
383
- dst->offset = 0;
384
- dst->size = mx_parseURLBufferSize;
385
-
386
-
387
- XS_URL_SCHEME_START:
388
- c = fx_parseURLDecode(the, src);
389
- if (('A' <= c) && (c <= 'Z')) {
390
- fx_parseURLEncode(the, c - ('A' - 'a'), dst);
391
- goto XS_URL_SCHEME;
392
- }
393
- if (('a' <= c) && (c <= 'z')) {
394
- fx_parseURLEncode(the, c, dst);
395
- goto XS_URL_SCHEME;
396
- }
397
- if (override)
398
- goto XS_URL_ERROR;
399
- src->offset = 0;
400
- dst->offset = 0;
401
- goto XS_URL_NO_SCHEME;
402
-
403
- XS_URL_SCHEME:
404
- c = fx_parseURLDecode(the, src);
405
- if (('A' <= c) && (c <= 'Z')) {
406
- fx_parseURLEncode(the, c - ('A' - 'a'), dst);
407
- goto XS_URL_SCHEME;
408
- }
409
- if ((('a' <= c) && (c <= 'z')) || (('0' <= c) && (c <= '9')) || (c == '+') || (c == '-') || (c == '.')) {
410
- fx_parseURLEncode(the, c, dst);
411
- goto XS_URL_SCHEME;
412
- }
413
- if ((c == ':') || (override && (c == C_EOF))) {
414
- schemeIndex = fx_parseURLSpecialScheme(the, dst->slot->value.string);
415
- special = schemeIndex >= 0;
416
- if (override) {
417
- if (overrideSpecial != special)
418
- goto XS_URL_END;
419
- if (schemeIndex == 0) {
420
- if (!fx_parseURLIsPartEmpty(the, result, xsID_username))
421
- goto XS_URL_END;
422
- if (!fx_parseURLIsPartEmpty(the, result, xsID_password))
423
- goto XS_URL_END;
424
- if (!fx_parseURLIsPartEmpty(the, result, xsID_port))
425
- goto XS_URL_END;
426
- }
427
- if ((overrideSchemeIndex == 0) && (schemeIndex != 0)) {
428
- if (fx_parseURLIsPartEmpty(the, result, xsID_host))
429
- goto XS_URL_END;
430
- }
431
- }
432
- fx_parseURLSetPart(the, result, xsID_scheme, 0, dst);
433
- if (override) {
434
- if (special) {
435
- mxPushSlot(result);
436
- mxGetID(xsID_port);
437
- port = (the->stack->value.string[0]) ? fxToInteger(the, the->stack) : 0;
438
- mxPop();
439
- if (port == gx_parseURLSpecialSchemePorts[schemeIndex])
440
- fx_parseURLEmptyPart(the, result, xsID_port);
441
- }
442
- goto XS_URL_END;
443
- }
444
- if (schemeIndex == 0)
445
- goto XS_URL_FILE_START;
446
- if (special) {
447
- if (base && (baseSchemeIndex == schemeIndex))
448
- goto XS_URL_RELATIVE;
449
- goto XS_URL_AUTHORITY_START;
450
- }
451
-
452
- tmp = src->offset;
453
- c = fx_parseURLDecode(the, src);
454
- if (c == '/') {
455
- tmp = src->offset;
456
- c = fx_parseURLDecode(the, src);
457
- if (c == '/')
458
- goto XS_URL_AUTHORITY_START;
459
- src->offset = tmp;
460
- c = '/';
461
- goto XS_URL_PATH;
462
- }
463
- src->offset = tmp;
464
- goto XS_URL_OPAQUE_PATH;
465
- }
466
- if (override)
467
- goto XS_URL_ERROR;
468
- src->offset = 0;
469
- dst->offset = 0;
470
-
471
- XS_URL_NO_SCHEME:
472
- if (!base)
473
- goto XS_URL_ERROR;
474
- fx_parseURLCopyPart(the, base, result, xsID_scheme);
475
- schemeIndex = baseSchemeIndex;
476
- special = baseSpecial;
477
- if (schemeIndex == 0)
478
- goto XS_URL_FILE_START;
479
-
480
- if (fx_parseURLHasOpaquePath(the, base)) {
481
- c = fx_parseURLDecode(the, src);
482
- if (c == '#') {
483
- fx_parseURLCopyPart(the, base, result, xsID_path);
484
- fx_parseURLCopyPart(the, base, result, xsID_query);
485
- goto XS_URL_FRAGMENT;
486
- }
487
- goto XS_URL_ERROR;
488
- }
489
- goto XS_URL_RELATIVE;
490
-
491
- XS_URL_RELATIVE:
492
- tmp = src->offset;
493
- c = fx_parseURLDecode(the, src);
494
- if ((c == '/') || (special && (c == '\\'))) {
495
- c = fx_parseURLDecode(the, src);
496
- if ((c == '/') || (special && (c == '\\'))) {
497
- goto XS_URL_AUTHORITY_START;
498
- }
499
- }
500
- src->offset = tmp;
501
-
502
- fx_parseURLCopyPart(the, base, result, xsID_username);
503
- fx_parseURLCopyPart(the, base, result, xsID_password);
504
- fx_parseURLCopyPart(the, base, result, xsID_host);
505
- fx_parseURLCopyPart(the, base, result, xsID_port);
506
-
507
- c = fx_parseURLDecode(the, src);
508
- if ((c == '/') || (special && (c == '\\')))
509
- goto XS_URL_PATH;
510
- fx_parseURLCopyPath(the, base, result);
511
- if (c == '?')
512
- goto XS_URL_QUERY;
513
- fx_parseURLCopyPart(the, base, result, xsID_query);
514
- if (c == '#')
515
- goto XS_URL_FRAGMENT;
516
- if (c != C_EOF) {
517
- fx_parseURLShortenPath(the, result);
518
- src->offset = tmp;
519
- goto XS_URL_PATH;
520
- }
521
- goto XS_URL_END;
522
-
523
- XS_URL_AUTHORITY_START:
524
- tmp = src->offset;
525
- c = fx_parseURLDecode(the, src);
526
- if (special && ((c == '/') || (c == '\\')))
527
- goto XS_URL_AUTHORITY_START;
528
- src->offset = tmp;
529
-
530
- XS_URL_AUTHORITY:
531
- c = fx_parseURLDecode(the, src);
532
- if (c == '@') {
533
- atOffset = src->offset - 1;
534
- }
535
- else if (c == ':') {
536
- if (colonOffset < 0)
537
- colonOffset = src->offset - 1;
538
- }
539
- if ((c == C_EOF) || (c == '/') || (special && (c == '\\')) || (c == '?') || (c == '#')) {
540
- txInteger endOffset = src->offset - 1;
541
- src->offset = tmp;
542
- if (atOffset >= 0) {
543
- if (colonOffset > atOffset)
544
- colonOffset = -1;
545
- if (colonOffset >= 0) {
546
- while (src->offset < colonOffset) {
547
- c = fx_parseURLDecode(the, src);
548
- fx_parseURLPercentEncode(the, c, dst, gxUserInfoSet);
549
- }
550
- fx_parseURLSetPart(the, result, xsID_username, 0, dst);
551
- src->offset++;
552
- while (src->offset < atOffset) {
553
- c = fx_parseURLDecode(the, src);
554
- fx_parseURLPercentEncode(the, c, dst, gxUserInfoSet);
555
- }
556
- fx_parseURLSetPart(the, result, xsID_password, 0, dst);
557
- src->offset++;
558
- }
559
- else {
560
- while (src->offset < atOffset) {
561
- c = fx_parseURLDecode(the, src);
562
- fx_parseURLPercentEncode(the, c, dst, gxUserInfoSet);
563
- }
564
- fx_parseURLSetPart(the, result, xsID_username, 0, dst);
565
- src->offset++;
566
- }
567
- if (src->offset == endOffset)
568
- goto XS_URL_ERROR;
569
- }
570
- hostOffset = src->offset;
571
- goto XS_URL_HOST;
572
- }
573
- goto XS_URL_AUTHORITY;
574
-
575
- XS_URL_USERNAME:
576
- c = fx_parseURLDecode(the, src);
577
- if (c == C_EOF) {
578
- fx_parseURLSetPart(the, result, xsID_username, 0, dst);
579
- goto XS_URL_END;
580
- }
581
- fx_parseURLPercentEncode(the, c, dst, gxUserInfoSet);
582
- goto XS_URL_USERNAME;
583
-
584
- XS_URL_PASSWORD:
585
- c = fx_parseURLDecode(the, src);
586
- if (c == C_EOF) {
587
- fx_parseURLSetPart(the, result, xsID_password, 0, dst);
588
- goto XS_URL_END;
589
- }
590
- fx_parseURLPercentEncode(the, c, dst, gxUserInfoSet);
591
- goto XS_URL_PASSWORD;
592
-
593
- XS_URL_HOST:
594
- c = fx_parseURLDecode(the, src);
595
- if ((c == ':') && !insideBracket) {
596
- if (src->offset - 1 == hostOffset)
597
- goto XS_URL_ERROR;
598
- if (override == HOST_STATE)
599
- goto XS_URL_END;
600
- if (fx_parseURLHost(the, src, hostOffset, src->offset - 1, dst, special)) {
601
- fx_parseURLSetPart(the, result, xsID_host, 0, dst);
602
- goto XS_URL_PORT;
603
- }
604
- if (override)
605
- goto XS_URL_END;
606
- goto XS_URL_ERROR;
607
- }
608
- if ((c == C_EOF) || (c == '/') || (special && (c == '\\')) || (c == '?') || (c == '#')) {
609
- if (special && (src->offset - 1 == hostOffset))
610
- goto XS_URL_ERROR;
611
- //@@
612
- if (fx_parseURLHost(the, src, hostOffset, src->offset - 1, dst, special)) {
613
- fx_parseURLSetPart(the, result, xsID_host, 0, dst);
614
- if (c == C_EOF)
615
- goto XS_URL_END;
616
- if (c == '?')
617
- goto XS_URL_QUERY;
618
- if (c == '#')
619
- goto XS_URL_FRAGMENT;
620
- goto XS_URL_PATH;
621
- }
622
- if (override)
623
- goto XS_URL_END;
624
- goto XS_URL_ERROR;
625
- }
626
- if (c == '[')
627
- insideBracket = 1;
628
- if (c == ']')
629
- insideBracket = 0;
630
- goto XS_URL_HOST;
631
-
632
- XS_URL_PORT:
633
- c = fx_parseURLDecode(the, src);
634
- if (('0' <= c) && (c <= '9')) {
635
- fx_parseURLEncode(the, c, dst);
636
- goto XS_URL_PORT;
637
- }
638
- if (override || (c == C_EOF) || (c == '/') || (special && (c == '\\')) || (c == '?') || (c == '#')) {
639
- if (dst->offset != 0) {
640
- mxPushSlot(dst->slot);
641
- port = fxToNumber(the, the->stack);
642
- mxPop();
643
- if (port > 65535)
644
- goto XS_URL_ERROR;
645
- if (special && ((txInteger)port == gx_parseURLSpecialSchemePorts[schemeIndex])) {
646
- fx_parseURLEmptyPart(the, result, xsID_port);
647
- dst->offset = 0;
648
- dst->slot->value.string[0] = 0;
649
- }
650
- else {
651
- fxIntegerToString(the, (txInteger)port, dst->slot->value.string, dst->size);
652
- fx_parseURLSetPart(the, result, xsID_port, 0, dst);
653
- }
654
- }
655
- if (override || (c == C_EOF))
656
- goto XS_URL_END;
657
- if (c == '?')
658
- goto XS_URL_QUERY;
659
- if (c == '#')
660
- goto XS_URL_FRAGMENT;
661
- goto XS_URL_PATH;
662
- }
663
- goto XS_URL_ERROR;
664
-
665
- XS_URL_FILE_START:
666
- tmp = src->offset;
667
- c = fx_parseURLDecode(the, src);
668
- if ((c == '/') || (c == '\\'))
669
- goto XS_URL_FILE_SLASH;
670
- if (base && (baseSchemeIndex == 0)) {
671
- fx_parseURLCopyPart(the, base, result, xsID_host);
672
- if (fx_parseURLIsWindowsDriveLetter(the, src->slot->value.string + tmp, 1)) {
673
- src->offset = tmp;
674
- goto XS_URL_PATH;
675
- }
676
- fx_parseURLCopyPath(the, base, result);
677
- if (c == '?')
678
- goto XS_URL_QUERY;
679
- fx_parseURLCopyPart(the, base, result, xsID_query);
680
- if (c == '#')
681
- goto XS_URL_FRAGMENT;
682
- if (c != C_EOF) {
683
- fx_parseURLShortenPath(the, result);
684
- src->offset = tmp;
685
- goto XS_URL_PATH;
686
- }
687
- goto XS_URL_END;
688
- }
689
- fx_parseURLEmptyPart(the, result, xsID_host);
690
- if (c == '?')
691
- goto XS_URL_QUERY;
692
- if (c == '#')
693
- goto XS_URL_FRAGMENT;
694
- if (c != C_EOF) {
695
- src->offset = tmp;
696
- goto XS_URL_PATH;
697
- }
698
- goto XS_URL_END;
699
-
700
- XS_URL_FILE_SLASH:
701
- tmp = src->offset;
702
- c = fx_parseURLDecode(the, src);
703
- if ((c == '/') || (c == '\\')) {
704
- hostOffset = src->offset;
705
- goto XS_URL_FILE_HOST;
706
- }
707
- if (base && (baseSchemeIndex == 0)) {
708
- fx_parseURLCopyPart(the, base, result, xsID_host);
709
- if (fx_parseURLIsWindowsDriveLetter(the, src->slot->value.string + tmp, 1)) {
710
- src->offset = tmp;
711
- goto XS_URL_PATH;
712
- }
713
- mxPushSlot(base);
714
- mxGetID(mxID(_length));
715
- length = (txIndex)fxToLength(the, the->stack);
716
- mxPop();
717
- if (length > 0) {
718
- mxPushSlot(base);
719
- mxGetIndex(0);
720
- if (fx_parseURLIsWindowsDriveLetter(the, the->stack->value.string, 0)) {
721
- mxPushSlot(result);
722
- mxSetIndex(0);
723
- mxPop();
724
- }
725
- }
726
- }
727
- else
728
- fx_parseURLEmptyPart(the, result, xsID_host);
729
- src->offset = tmp;
730
- goto XS_URL_PATH;
731
-
732
- XS_URL_FILE_HOST:
733
- c = fx_parseURLDecode(the, src);
734
- if ((c == C_EOF) || (c == '/') || (c == '\\') || (c == '?') || (c == '#')) {
735
- if (!override && fx_parseURLIsWindowsDriveLetter(the, src->slot->value.string + hostOffset, 1)) {
736
- txInteger endOffset = src->offset - 1;
737
- fx_parseURLEmptyPart(the, result, xsID_host);
738
- src->offset = hostOffset;
739
- while (src->offset < endOffset) {
740
- txInteger d = fx_parseURLDecode(the, src);
741
- fx_parseURLPercentEncode(the, d, dst, gxPathSet);
742
- }
743
- src->offset++;
744
- fx_parseURLPushPath(the, result, dst, 0);
745
- goto XS_URL_PATH_START;
746
- }
747
- if (fx_parseURLHost(the, src, hostOffset, src->offset - 1, dst, special)) {
748
- if (!c_strcmp(dst->slot->value.string, "localhost")) {
749
- dst->slot->value.string[0] = 0;
750
- dst->offset = 0;
751
- }
752
- fx_parseURLSetPart(the, result, xsID_host, 0, dst);
753
- goto XS_URL_PATH_START;
754
- }
755
- if (override)
756
- goto XS_URL_END;
757
- goto XS_URL_ERROR;
758
- }
759
- goto XS_URL_FILE_HOST;
760
-
761
- XS_URL_PATH_START:
762
- if (c == C_EOF)
763
- goto XS_URL_END;
764
- if (!override && (c == '?'))
765
- goto XS_URL_QUERY;
766
- if (!override && (c == '#'))
767
- goto XS_URL_FRAGMENT;
768
-
769
- XS_URL_PATH:
770
- c = fx_parseURLDecode(the, src);
771
- if (c == C_EOF) {
772
- fx_parseURLPushPath(the, result, dst, 1);
773
- goto XS_URL_END;
774
- }
775
- if ((c == '/') || (special && (c == '\\'))) {
776
- fx_parseURLPushPath(the, result, dst, 0);
777
- goto XS_URL_PATH;
778
- }
779
- if (!override && (c == '?')) {
780
- fx_parseURLPushPath(the, result, dst, 1);
781
- goto XS_URL_QUERY;
782
- }
783
- if (!override && (c == '#')) {
784
- fx_parseURLPushPath(the, result, dst, 1);
785
- goto XS_URL_FRAGMENT;
786
- }
787
- fx_parseURLPercentEncode(the, c, dst, gxPathSet);
788
- goto XS_URL_PATH;
789
-
790
- XS_URL_OPAQUE_PATH:
791
- c = fx_parseURLDecode(the, src);
792
- if (c == C_EOF) {
793
- fx_parseURLSetPart(the, result, xsID_path, 0, dst);
794
- goto XS_URL_END;
795
- }
796
- if (!override && (c == '?')) {
797
- fx_parseURLSetPart(the, result, xsID_path, 0, dst);
798
- goto XS_URL_QUERY;
799
- }
800
- if (!override && (c == '#')) {
801
- fx_parseURLSetPart(the, result, xsID_path, 0, dst);
802
- goto XS_URL_FRAGMENT;
803
- }
804
- fx_parseURLPercentEncode(the, c, dst, gxControlSet);
805
- goto XS_URL_OPAQUE_PATH;
806
-
807
- XS_URL_QUERY:
808
- c = fx_parseURLDecode(the, src);
809
- if (c == C_EOF) {
810
- fx_parseURLSetPart(the, result, xsID_query, 0, dst);
811
- goto XS_URL_END;
812
- }
813
- if (!override && (c == '#')) {
814
- fx_parseURLSetPart(the, result, xsID_query, 0, dst);
815
- goto XS_URL_FRAGMENT;
816
- }
817
- fx_parseURLPercentEncode(the, c, dst, (special) ? gxSpecialQuerySet : gxQuerySet);
818
- goto XS_URL_QUERY;
819
-
820
- XS_URL_FRAGMENT:
821
- c = fx_parseURLDecode(the, src);
822
- if (c == C_EOF) {
823
- fx_parseURLSetPart(the, result, xsID_fragment, 0, dst);
824
- goto XS_URL_END;
825
- }
826
- fx_parseURLPercentEncode(the, c, dst, gxFragmentSet);
827
- goto XS_URL_FRAGMENT;
828
-
829
- XS_URL_ERROR:
830
- mxTypeError("invalid URL");
831
-
832
- XS_URL_END:
833
- return;
834
- }
835
-
836
- void fx_parseURLCopyPart(txMachine* the, txSlot* src, txSlot* dst, txID id)
837
- {
838
- mxPushSlot(src);
839
- mxGetID(id);
840
- mxPushSlot(dst);
841
- mxSetID(id);
842
- mxPop();
843
- }
844
-
845
- void fx_parseURLCopyPath(txMachine* the, txSlot* src, txSlot* dst)
846
- {
847
- txIndex length, i;
848
-
849
- mxPushSlot(src);
850
- mxGetID(mxID(_length));
851
- length = (txIndex)fxToLength(the, the->stack);
852
- mxPop();
853
- i = 0;
854
- while (i < length) {
855
- mxPushSlot(src);
856
- mxGetIndex(i);
857
- mxPushSlot(dst);
858
- mxSetIndex(i);
859
- mxPop();
860
- i++;
861
- }
862
- }
863
-
864
- txInteger fx_parseURLDecode(txMachine* the, txStringStream* stream)
865
- {
866
- txInteger result;
867
- txString string = stream->slot->value.string + stream->offset;
868
- string = mxStringByteDecode(string, &result);
869
- if ((0xD000 <= result) && (result <= 0xDFFF))
870
- result = 0xFFFD;
871
- stream->offset = string - stream->slot->value.string;
872
- return result;
873
- }
874
-
875
- void fx_parseURLEncode(txMachine* the, txInteger c, txStringStream* dst)
876
- {
877
- txSize length = mxStringByteLength(c);
878
- txString string;
879
- if (dst->offset + length >= dst->size) {
880
- txSize size = fxAddChunkSizes(the, dst->offset, length + 1);
881
- txString string = fxRenewChunk(the, dst->slot->value.string, size);
882
- if (!string) {
883
- string = (txString)fxNewChunk(the, size);
884
- c_memcpy(string, dst->slot->value.string, dst->offset);
885
- }
886
- dst->slot->value.string = string;
887
- dst->size = size;
888
- }
889
- string = dst->slot->value.string + dst->offset;
890
- string = mxStringByteEncode(string, c);
891
- dst->offset += length;
892
- *string = 0;
893
- }
894
-
895
- void fx_parseURLEmptyPart(txMachine* the, txSlot* target, txID id)
896
- {
897
- mxPush(mxEmptyString);
898
- mxPushSlot(target);
899
- mxSetID(id);
900
- mxPop();
901
- }
902
-
903
- txBoolean fx_parseURLHasOpaquePath(txMachine* the, txSlot* parts)
904
- {
905
- mxPushSlot(parts);
906
- return mxHasID(xsID_path);
907
- }
908
-
909
- txBoolean fx_parseURLHost(txMachine* the, txStringStream* src, txInteger from, txInteger to, txStringStream* dst, txBoolean special)
910
- {
911
- txString p = src->slot->value.string;
912
- if ((to - from > 1) && (p[from] == '[') && (p[to - 1] == ']')) {
913
- return fx_parseURLHostIPv6( the, src, from + 1, to - 1, dst);
914
- }
915
- if (special) {
916
- if (fx_parseURLHostSpecial(the, src, from, to, dst))
917
- return fx_parseURLHostIPv4(the, src, from, to, dst);
918
- return 0;
919
- }
920
- return fx_parseURLHostNotSpecial(the, src, from, to, dst);
921
- }
922
-
923
- txBoolean fx_parseURLHostIPv4(txMachine* the, txStringStream* src, txInteger from, txInteger to, txStringStream* dst)
924
- {
925
- txS8 pieces[4];
926
- txS8 value;
927
- txS8 sum;
928
- txInteger pieceCount = 0;
929
- txInteger pieceIndex;
930
- txString p = dst->slot->value.string;
931
- txString q = dst->slot->value.string + dst->offset;
932
- while (p < q) {
933
- value = -1;
934
- if (*p == '0') {
935
- value = 0;
936
- p++;
937
- if ((p < q) && ((*p == 'x') || (*p == 'X'))) {
938
- p++;
939
- while (p < q) {
940
- if (('0' <= *p) && (*p <= '9'))
941
- value = (value * 16) + (*p - '0');
942
- else if (('a' <= *p) && (*p <= 'f'))
943
- value = (value * 16) + (10 + *p - 'a');
944
- else if (('A' <= *p) && (*p <= 'F'))
945
- value = (value * 16) + (10 + *p - 'A');
946
- else
947
- break;
948
- p++;
949
-
950
- }
951
- }
952
- else {
953
- while (p < q) {
954
- if (('0' <= *p) && (*p <= '7'))
955
- value = (value * 8) + (*p - '0');
956
- else if (('8' <= *p) && (*p <= '9'))
957
- value += 0x0000000100000000;
958
- else
959
- break;
960
- p++;
961
- }
962
- }
963
- }
964
- else if (('1' <= *p) && (*p <= '9')) {
965
- value = *p - '0';
966
- p++;
967
- while (p < q) {
968
- if (('0' <= *p) && (*p <= '9'))
969
- value = (value * 10) + (*p - '0');
970
- else
971
- break;
972
- p++;
973
- }
974
- }
975
- if ((p < q) && (*p != '.')) {
976
- value = -1;
977
- while ((p < q) && (*p != '.'))
978
- p++;
979
- }
980
- if (pieceCount < 4)
981
- pieces[pieceCount] = value;
982
- else
983
- pieces[3] = value;
984
- pieceCount++;
985
- if (*p == '.')
986
- p++;
987
- }
988
- if (pieceCount == 0)
989
- return 1;
990
- pieceIndex = pieceCount - 1;
991
- if (pieceIndex > 3)
992
- pieceIndex = 3;
993
- if (pieces[pieceIndex] == -1)
994
- return 1;
995
- if (pieceCount > 4)
996
- return 0;
997
- sum = pieces[pieceIndex];
998
- value = 256;
999
- pieceCount = 4 - pieceCount;
1000
- while (pieceCount > 0) {
1001
- value <<= 8;
1002
- pieceCount--;
1003
- }
1004
- if (sum >= value)
1005
- return 0;
1006
- pieceIndex--;
1007
- while (pieceIndex >= 0) {
1008
- value = pieces[pieceIndex];
1009
- if ((value < 0) || (255 < value))
1010
- return 0;
1011
- pieceCount = 3 - pieceIndex;
1012
- while (pieceCount > 0) {
1013
- value <<= 8;
1014
- pieceCount--;
1015
- }
1016
- sum += value;
1017
- pieceIndex--;
1018
- }
1019
- if (sum > 0x00000000FFFFFFFF)
1020
- return 0;
1021
- pieces[0] = (sum & 0x00000000FF000000) >> 24;
1022
- pieces[1] = (sum & 0x0000000000FF0000) >> 16;
1023
- pieces[2] = (sum & 0x000000000000FF00) >> 8;
1024
- pieces[3] = (sum & 0x00000000000000FF);
1025
- dst->offset = 0;
1026
- dst->slot->value.string[0] = 0;
1027
- for (pieceIndex = 0; pieceIndex < 4; pieceIndex++) {
1028
- value = pieces[pieceIndex];
1029
- if (value >= 100) {
1030
- fx_parseURLEncode(the, '0' + ((txInteger)value / 100), dst);
1031
- value %= 100;
1032
- fx_parseURLEncode(the, '0' + ((txInteger)value / 10), dst);
1033
- value %= 10;
1034
- }
1035
- else if (value >= 10) {
1036
- fx_parseURLEncode(the, '0' + ((txInteger)value / 10), dst);
1037
- value %= 10;
1038
- }
1039
- fx_parseURLEncode(the, '0' + (txInteger)value, dst);
1040
- if (pieceIndex < 3)
1041
- fx_parseURLEncode(the, '.', dst);
1042
- }
1043
- return 1;
1044
- }
1045
-
1046
- txBoolean fx_parseURLHostIPv6(txMachine* the, txStringStream* src, txInteger from, txInteger to, txStringStream* dst)
1047
- {
1048
- txU2 pieces[8];
1049
- txInteger pieceIndex = 0;
1050
- txInteger compress = -1;
1051
- txU2 value;
1052
- txInteger length;
1053
- txInteger numbersSeen;
1054
- txString p = src->slot->value.string + from;
1055
- txString q = src->slot->value.string + to;
1056
- c_memset(pieces, 0, sizeof(pieces));
1057
- if (p[0] == ':') {
1058
- if (p[1] != ':')
1059
- return 0;
1060
- p += 2;
1061
- pieceIndex++;
1062
- compress = pieceIndex;
1063
- }
1064
- while (p < q) {
1065
- if (pieceIndex == 8)
1066
- return 0;
1067
- if (*p == ':') {
1068
- if (compress != -1)
1069
- return 0;
1070
- p++;
1071
- pieceIndex++;
1072
- compress = pieceIndex;
1073
- continue;
1074
- }
1075
- value = 0;
1076
- length = 0;
1077
- while ((p < q) && (length < 4)) {
1078
- if (('0' <= *p) && (*p <= '9'))
1079
- value = (value * 16) + (*p - '0');
1080
- else if (('a' <= *p) && (*p <= 'f'))
1081
- value = (value * 16) + (10 + *p - 'a');
1082
- else if (('A' <= *p) && (*p <= 'F'))
1083
- value = (value * 16) + (10 + *p - 'A');
1084
- else
1085
- break;
1086
- length++;
1087
- p++;
1088
- }
1089
- if (*p == '.') {
1090
- if (length == 0)
1091
- return 0;
1092
- p -= length;
1093
- if (pieceIndex > 6)
1094
- return 0;
1095
- numbersSeen = 0;
1096
- while (p < q) {
1097
- txInteger ipv4Piece = -1;
1098
- if (numbersSeen > 0) {
1099
- if ((*p == '.') && (numbersSeen < 4))
1100
- p++;
1101
- else
1102
- return 0;
1103
- }
1104
- if ((p < q) && ('0' <= *p) && (*p <= '9')) {
1105
- while ((p < q) && ('0' <= *p) && (*p <= '9')) {
1106
- if (ipv4Piece == 0)
1107
- return 0;
1108
- if (ipv4Piece < 0)
1109
- ipv4Piece = *p - '0';
1110
- else
1111
- ipv4Piece = (ipv4Piece * 10) + (*p - '0');
1112
- if (ipv4Piece > 255)
1113
- return 0;
1114
- p++;
1115
- }
1116
- pieces[pieceIndex] = (pieces[pieceIndex] * 256) + ipv4Piece;
1117
- numbersSeen++;
1118
- if ((numbersSeen == 2) || (numbersSeen == 4))
1119
- pieceIndex++;
1120
- }
1121
- else
1122
- return 0;
1123
- }
1124
- if (numbersSeen != 4)
1125
- return 0;
1126
- break;
1127
- }
1128
- else if (*p == ':') {
1129
- p++;
1130
- if (p == q)
1131
- return 0;
1132
- }
1133
- else if (p < q)
1134
- return 0;
1135
- pieces[pieceIndex] = value;
1136
- pieceIndex++;
1137
- }
1138
- if (compress != -1) {
1139
- txInteger swaps = pieceIndex - compress;
1140
- pieceIndex = 7;
1141
- while ((pieceIndex != 0) && (swaps > 0)) {
1142
- txU2 piece = pieces[compress + swaps - 1];
1143
- pieces[compress + swaps - 1] = pieces[pieceIndex];
1144
- pieces[pieceIndex] = piece;
1145
- pieceIndex--;
1146
- swaps--;
1147
- }
1148
- }
1149
- else if (pieceIndex != 8)
1150
- return 0;
1151
-
1152
- compress = -1;
1153
- length = 0;
1154
- pieceIndex = 0;
1155
- while (pieceIndex < 8) {
1156
- if (pieces[pieceIndex] == 0) {
1157
- txInteger zeroCompress = pieceIndex;
1158
- txInteger zeroLength = 1;
1159
- pieceIndex++;
1160
- while (pieceIndex < 8) {
1161
- if (pieces[pieceIndex] != 0)
1162
- break;
1163
- pieceIndex++;
1164
- zeroLength++;
1165
- }
1166
- if (zeroLength > length) {
1167
- compress = zeroCompress;
1168
- length = zeroLength;
1169
- }
1170
-
1171
- }
1172
- pieceIndex++;
1173
- }
1174
- if (length < 2)
1175
- compress = -1;
1176
-
1177
- txBoolean ignore0 = 0;
1178
- fx_parseURLEncode(the, '[', dst);
1179
- for (pieceIndex = 0; pieceIndex < 8; pieceIndex++) {
1180
- value = pieces[pieceIndex];
1181
- if (ignore0 && (value == 0))
1182
- continue;
1183
- else
1184
- ignore0 = 0;
1185
- if (compress == pieceIndex) {
1186
- if (pieceIndex == 0)
1187
- fx_parseURLEncode(the, ':', dst);
1188
- fx_parseURLEncode(the, ':', dst);
1189
- ignore0 = 1;
1190
- continue;
1191
- }
1192
- txInteger flag = 0;
1193
- txInteger shift = 12;
1194
- while (shift > 0) {
1195
- txInteger digit = (value >> shift) & 0x000F;
1196
- flag |= digit;
1197
- if (flag)
1198
- fx_parseURLEncode(the, gxHexLower[digit], dst);
1199
- shift -= 4;
1200
- }
1201
- fx_parseURLEncode(the, gxHexLower[value & 0x000F], dst);
1202
- if (pieceIndex != 7)
1203
- fx_parseURLEncode(the, ':', dst);
1204
- }
1205
- fx_parseURLEncode(the, ']', dst);
1206
- return 1;
1207
- }
1208
-
1209
- txBoolean fx_parseURLHostNotSpecial(txMachine* the, txStringStream* src, txInteger from, txInteger to, txStringStream* dst)
1210
- {
1211
- txBoolean result = 1;
1212
- txInteger offset = src->offset;
1213
- src->offset = from;
1214
- while (src->offset < to) {
1215
- txInteger c = fx_parseURLDecode(the, src);
1216
- if ((c < 0x80) && c_read8(gxNotSpecialHostSet + c)) {
1217
- result = 0;
1218
- break;
1219
- }
1220
- fx_parseURLPercentEncode(the, c, dst, gxControlSet);
1221
- }
1222
- src->offset = offset;
1223
- return result;
1224
- }
1225
-
1226
- txBoolean fx_parseURLHostSpecial(txMachine* the, txStringStream* src, txInteger from, txInteger to, txStringStream* dst)
1227
- {
1228
- txBoolean result = 1;
1229
- txInteger offset = src->offset;
1230
- txInteger flag = 0;
1231
- src->offset = from;
1232
- while (src->offset < to) {
1233
- txInteger c = fx_parseURLDecode(the, src);
1234
- if (c < 0x80) {
1235
- if (('A' <= c) && (c <= 'Z'))
1236
- c -= ('A' - 'a');
1237
- else if (c == '%')
1238
- flag |= 1;
1239
- else if (c_read8(gxSpecialHostSet + c)) {
1240
- result = 0;
1241
- break;
1242
- }
1243
- }
1244
- else {
1245
-
1246
- flag |= 2;
1247
- }
1248
- fx_parseURLEncode(the, c, dst);
1249
- }
1250
- if (result && (flag & 1)) {
1251
- txStringStream _tmp;
1252
- txStringStream* tmp = &_tmp;
1253
- mxTry(the) {
1254
- mxPush(mxGlobal);
1255
- mxDub();
1256
- mxGetID(mxID(_decodeURIComponent));
1257
- mxCall();
1258
- mxPushSlot(dst->slot);
1259
- mxRunCount(1);
1260
- tmp->slot = the->stack;
1261
- tmp->offset = 0;
1262
- tmp->size = 0;
1263
- dst->offset = 0;
1264
- dst->slot->value.string[0] = 0;
1265
- for (;;) {
1266
- txInteger c = fx_parseURLDecode(the, tmp);
1267
- if (c == C_EOF)
1268
- break;
1269
- if (c < 0x80) {
1270
- if (c_read8(gxSpecialHostSet + c)) {
1271
- result = 0;
1272
- break;
1273
- }
1274
- if (('A' <= c) && (c <= 'Z'))
1275
- c -= ('A' - 'a');
1276
- }
1277
- else
1278
- flag |= 2;
1279
- fx_parseURLEncode(the, c, dst);
1280
- }
1281
- mxPop();
1282
- }
1283
- mxCatch(the) {
1284
- result = 0;
1285
- }
1286
- }
1287
- if (result && (flag & 2)) {
1288
- // punycode
1289
- mxSyntaxError("no punycode yet");
1290
- result = 0;
1291
- }
1292
- src->offset = offset;
1293
- return result;
1294
- }
1295
-
1296
- txBoolean fx_parseURLIsPartEmpty(txMachine* the, txSlot* parts, txID id)
1297
- {
1298
- txBoolean result;
1299
- mxPushSlot(parts);
1300
- mxGetID(id);
1301
- result = the->stack->value.string[0] == 0;
1302
- mxPop();
1303
- return result;
1304
- }
1305
-
1306
- txBoolean fx_parseURLIsWindowsDriveLetter(txMachine* the, txString string, txBoolean startsWith)
1307
- {
1308
- char c = *string++;
1309
- if ((('A' <= c) && (c <= 'Z')) || (('a' <= c) && (c <= 'z'))) {
1310
- c = *string++;
1311
- if ((c == ':') || (c == '|')) {
1312
- c = *string++;
1313
- if (c == 0)
1314
- return 1;
1315
- if (startsWith && ((c == '/') || (c == '\\') || (c == '?') || (c == '#')))
1316
- return 1;
1317
- }
1318
- }
1319
- return 0;
1320
- }
1321
-
1322
- void fx_parseURLNullPart(txMachine* the, txSlot* target, txID id)
1323
- {
1324
- mxPushNull();
1325
- mxPushSlot(target);
1326
- mxSetID(id);
1327
- mxPop();
1328
- }
1329
-
1330
- void fx_parseURLPercentEncode(txMachine* the, txInteger c, txStringStream* dst, const char* set)
1331
- {
1332
- txSize length;
1333
- txString string;
1334
- if (c < 0x80) {
1335
- if (c_read8(set + c))
1336
- length = 3;
1337
- else
1338
- length = 1;
1339
- }
1340
- else if (c < 0x800) {
1341
- length = 6;
1342
- }
1343
- else if (c < 0x10000) {
1344
- length = 9;
1345
- }
1346
- else {
1347
- length = 12;
1348
- }
1349
- if (dst->offset + length >= dst->size) {
1350
- txSize size = fxAddChunkSizes(the, dst->offset, length + 1);
1351
- txString string = fxRenewChunk(the, dst->slot->value.string, size);
1352
- if (!string) {
1353
- string = (txString)fxNewChunk(the, size);
1354
- c_memcpy(string, dst->slot->value.string, dst->offset);
1355
- }
1356
- dst->slot->value.string = string;
1357
- dst->size = size;
1358
- }
1359
- string = dst->slot->value.string + dst->offset;
1360
- if (length == 1)
1361
- *string++ = (char)c;
1362
- else if (length == 3) {
1363
- *string++ = '%';
1364
- string = fxStringifyHexEscape(string, c);
1365
- }
1366
- else if (length == 6) {
1367
- *string++ = '%';
1368
- string = fxStringifyHexEscape(string, 0xC0 | (c >> 6));
1369
- *string++ = '%';
1370
- string = fxStringifyHexEscape(string, 0x80 | (c & 0x3F));
1371
- }
1372
- else if (length == 9) {
1373
- *string++ = '%';
1374
- string = fxStringifyHexEscape(string, 0xE0 | (c >> 12));
1375
- *string++ = '%';
1376
- string = fxStringifyHexEscape(string, 0x80 | ((c >> 6) & 0x3F));
1377
- *string++ = '%';
1378
- string = fxStringifyHexEscape(string, 0x80 | (c & 0x3F));
1379
- }
1380
- else {
1381
- *string++ = '%';
1382
- string = fxStringifyHexEscape(string, 0xF0 | (c >> 18));
1383
- *string++ = '%';
1384
- string = fxStringifyHexEscape(string, 0x80 | ((c >> 12) & 0x3F));
1385
- *string++ = '%';
1386
- string = fxStringifyHexEscape(string, 0x80 | ((c >> 6) & 0x3F));
1387
- *string++ = '%';
1388
- string = fxStringifyHexEscape(string, 0x80 | (c & 0x3F));
1389
- }
1390
- dst->offset += length;
1391
- *string = 0;
1392
- }
1393
-
1394
- void fx_parseURLPushPath(txMachine* the, txSlot* path, txStringStream* dst, txBoolean flag)
1395
- {
1396
- txSize size;
1397
- txString string;
1398
- if ((c_strcmp(dst->slot->value.string, "..") == 0)
1399
- || (c_strcmp(dst->slot->value.string, ".%2E") == 0)
1400
- || (c_strcmp(dst->slot->value.string, "%2E.") == 0)
1401
- || (c_strcmp(dst->slot->value.string, "%2E%2E") == 0)
1402
- || (c_strcmp(dst->slot->value.string, ".%2e") == 0)
1403
- || (c_strcmp(dst->slot->value.string, "%2e.") == 0)
1404
- || (c_strcmp(dst->slot->value.string, "%2e%2e") == 0)) {
1405
- fx_parseURLShortenPath(the, path);
1406
- if (flag) {
1407
- dst->slot->value.string[0] = 0;
1408
- dst->offset = 0;
1409
- }
1410
- }
1411
- else if ((c_strcmp(dst->slot->value.string, ".") == 0)
1412
- || (c_strcmp(dst->slot->value.string, "%2E") == 0)
1413
- || (c_strcmp(dst->slot->value.string, "%2e") == 0)) {
1414
- if (flag) {
1415
- dst->slot->value.string[0] = 0;
1416
- dst->offset = 0;
1417
- }
1418
- }
1419
- else {
1420
- txIndex length;
1421
- mxPushSlot(path);
1422
- mxGetID(mxID(_length));
1423
- length = (txIndex)fxToLength(the, the->stack);
1424
- mxPop();
1425
- if ((length == 0) && fx_parseURLIsWindowsDriveLetter(the, dst->slot->value.string, 0))
1426
- dst->slot->value.string[1] = ':';
1427
- flag = 1;
1428
- }
1429
- if (flag) {
1430
- mxPushSlot(path);
1431
- mxDub();
1432
- mxGetID(mxID(_push));
1433
- mxCall();
1434
- size = dst->offset + 1;
1435
- string = fxRenewChunk(the, dst->slot->value.string, size);
1436
- if (!string) {
1437
- string = (txString)fxNewChunk(the, size);
1438
- c_memcpy(string, dst->slot->value.string, size);
1439
- }
1440
- mxPushString(string);
1441
- mxRunCount(1);
1442
- mxPop();
1443
- }
1444
- dst->slot->value.string = fxNewChunk(the, mx_parseURLBufferSize);
1445
- dst->size = mx_parseURLBufferSize;
1446
- dst->offset = 0;
1447
- dst->slot->value.string[0] = 0;
1448
- }
1449
-
1450
- txInteger fx_parseURLSpecialScheme(txMachine* the, txString scheme)
1451
- {
1452
- txInteger i;
1453
- for (i = 0; i < mx_parseURLSpecialSchemeCount; i++) {
1454
- if (!c_strcmp(scheme, gx_parseURLSpecialSchemeNames[i]))
1455
- return i;
1456
- }
1457
- return -1;
1458
- }
1459
-
1460
- void fx_parseURLSetPart(txMachine* the, txSlot* target, txID id, txIndex index, txStringStream* dst)
1461
- {
1462
- txSize size = dst->offset + 1;
1463
- txString string = fxRenewChunk(the, dst->slot->value.string, size);
1464
- if (!string) {
1465
- string = (txString)fxNewChunk(the, size);
1466
- c_memcpy(string, dst->slot->value.string, size);
1467
- }
1468
- mxPushString(string);
1469
- mxPushSlot(target);
1470
- mxSetAll(id, index);
1471
- mxPop();
1472
- dst->slot->value.string = fxNewChunk(the, mx_parseURLBufferSize);
1473
- dst->size = mx_parseURLBufferSize;
1474
- dst->offset = 0;
1475
- dst->slot->value.string[0] = 0;
1476
- }
1477
-
1478
- void fx_parseURLShortenPath(txMachine* the, txSlot* path)
1479
- {
1480
- txIndex length;
1481
- txBoolean flag;
1482
- mxPushSlot(path);
1483
- mxGetID(mxID(_length));
1484
- length = (txIndex)fxToLength(the, the->stack);
1485
- mxPop();
1486
- if (length == 1) {
1487
- mxPushSlot(path);
1488
- mxGetIndex(0);
1489
- flag = fx_parseURLIsWindowsDriveLetter(the, the->stack->value.string, 0);
1490
- mxPop();
1491
- if (flag)
1492
- return;
1493
- }
1494
- if (length > 0) {
1495
- length--;
1496
- mxPushInteger(length);
1497
- mxPushSlot(path);
1498
- mxSetID(mxID(_length));
1499
- mxPop();
1500
- }
1501
- }
1502
-
1503
- void fx_serializeURL(txMachine* the)
1504
- {
1505
- txSlot* parts;
1506
- txInteger schemeIndex;
1507
- txIndex length;
1508
- txInteger override = 0;
1509
- txSlot* result;
1510
-
1511
- fxVars(the, 3);
1512
- result = mxResult;
1513
- fxCopyStringC(the, result, "");
1514
-
1515
- parts = mxArgv(0);
1516
-
1517
- mxPushSlot(parts);
1518
- mxGetID(xsID_scheme);
1519
- schemeIndex = fx_parseURLSpecialScheme(the, the->stack->value.string);
1520
- mxPop();
1521
-
1522
- mxPushSlot(parts);
1523
- mxGetID(mxID(_length));
1524
- length = (txIndex)fxToLength(the, the->stack);
1525
- mxPop();
1526
-
1527
- if (mxArgc > 1) {
1528
- override = fxToInteger(the, mxArgv(1));
1529
- if (override == SCHEME_STATE) {
1530
- goto XS_URL_SCHEME;
1531
- }
1532
- if (override == USERNAME_STATE) {
1533
- goto XS_URL_USERNAME;
1534
- }
1535
- if (override == PASSWORD_STATE) {
1536
- goto XS_URL_PASSWORD;
1537
- }
1538
- if (override == HOST_PORT_STATE) {
1539
- goto XS_URL_HOST;
1540
- }
1541
- if (override == HOST_STATE) {
1542
- goto XS_URL_HOST;
1543
- }
1544
- if (override == PORT_STATE) {
1545
- goto XS_URL_PORT;
1546
- }
1547
- if (override == PATH_STATE) {
1548
- goto XS_URL_PATH;
1549
- }
1550
- if (override == QUERY_STATE) {
1551
- goto XS_URL_QUERY;
1552
- }
1553
- if (override == FRAGMENT_STATE) {
1554
- goto XS_URL_FRAGMENT;
1555
- }
1556
- if (override == ORIGIN_STATE) {
1557
- goto XS_URL_ORIGIN;
1558
- }
1559
- goto XS_URL_END;
1560
- }
1561
-
1562
- XS_URL_SCHEME:
1563
- mxPushSlot(parts);
1564
- mxGetID(xsID_scheme);
1565
- fxConcatString(the, result, the->stack);
1566
- mxPop();
1567
- fxConcatStringC(the, result, ":");
1568
- if (override == SCHEME_STATE)
1569
- goto XS_URL_END;
1570
-
1571
- mxPushSlot(parts);
1572
- mxGetID(xsID_host);
1573
- mxPullSlot(mxVarv(0));
1574
- if (mxIsNull(mxVarv(0))) {
1575
- if (length > 1) {
1576
- mxPushSlot(parts);
1577
- mxGetIndex(0);
1578
- if (the->stack->value.string[0] == 0)
1579
- fxConcatStringC(the, result, "/.");
1580
- mxPop();
1581
- }
1582
- goto XS_URL_PATH;
1583
- }
1584
-
1585
- fxConcatStringC(the, result, "//");
1586
-
1587
- mxPushSlot(parts);
1588
- mxGetID(xsID_username);
1589
- mxPullSlot(mxVarv(1));
1590
- mxPushSlot(parts);
1591
- mxGetID(xsID_password);
1592
- mxPullSlot(mxVarv(2));
1593
- if (mxVarv(1)->value.string[0] || mxVarv(2)->value.string[0]) {
1594
- fxConcatString(the, result, mxVarv(1));
1595
- if (mxVarv(2)->value.string[0]) {
1596
- fxConcatStringC(the, result, ":");
1597
- fxConcatString(the, result, mxVarv(2));
1598
- }
1599
- fxConcatStringC(the, result, "@");
1600
- }
1601
- fxConcatString(the, result, mxVarv(0));
1602
- goto XS_URL_PORT;
1603
-
1604
- XS_URL_USERNAME:
1605
- mxPushSlot(parts);
1606
- mxGetID(xsID_username);
1607
- fxConcatString(the, result, the->stack);
1608
- mxPop();
1609
- goto XS_URL_END;
1610
-
1611
- XS_URL_PASSWORD:
1612
- mxPushSlot(parts);
1613
- mxGetID(xsID_password);
1614
- fxConcatString(the, result, the->stack);
1615
- mxPop();
1616
- goto XS_URL_END;
1617
-
1618
- XS_URL_ORIGIN:
1619
- if (schemeIndex < 0) {
1620
- fxConcatStringC(the, result, "null");
1621
- goto XS_URL_END;
1622
- }
1623
- mxPushSlot(parts);
1624
- mxGetID(xsID_host);
1625
- mxPullSlot(mxVarv(0));
1626
- if (!mxVarv(0)->value.string[0]) {
1627
- fxConcatStringC(the, result, "null");
1628
- goto XS_URL_END;
1629
- }
1630
- mxPushSlot(parts);
1631
- mxGetID(xsID_scheme);
1632
- fxConcatString(the, result, the->stack);
1633
- mxPop();
1634
- fxConcatStringC(the, result, "://");
1635
- fxConcatString(the, result, mxVarv(0));
1636
- goto XS_URL_PORT;
1637
-
1638
- XS_URL_HOST:
1639
- mxPushSlot(parts);
1640
- mxGetID(xsID_host);
1641
- mxPullSlot(mxVarv(0));
1642
- fxConcatString(the, result, mxVarv(0));
1643
- if (override == HOST_STATE)
1644
- goto XS_URL_END;
1645
-
1646
- XS_URL_PORT:
1647
- mxPushSlot(parts);
1648
- mxGetID(xsID_port);
1649
- mxPullSlot(mxVarv(0));
1650
- if (mxVarv(0)->value.string[0]) {
1651
- if (override != PORT_STATE)
1652
- fxConcatStringC(the, result, ":");
1653
- fxConcatString(the, result, mxVarv(0));
1654
- }
1655
- if ((override == HOST_PORT_STATE) || (override == PORT_STATE) || (override == ORIGIN_STATE))
1656
- goto XS_URL_END;
1657
-
1658
- XS_URL_PATH:
1659
- mxPushSlot(parts);
1660
- if (mxHasID(xsID_path)) {
1661
- mxPushSlot(parts);
1662
- mxGetID(xsID_path);
1663
- fxConcatString(the, result, the->stack);
1664
- mxPop();
1665
- }
1666
- else {
1667
- if (length == 0) {
1668
- if (schemeIndex >= 0)
1669
- fxConcatStringC(the, result, "/");
1670
- }
1671
- else {
1672
- txIndex index = 0;
1673
- while (index < length) {
1674
- fxConcatStringC(the, result, "/");
1675
- mxPushSlot(parts);
1676
- mxGetIndex(index);
1677
- fxConcatString(the, result, the->stack);
1678
- mxPop();
1679
- index++;
1680
- }
1681
- }
1682
- }
1683
- if (override == PATH_STATE)
1684
- goto XS_URL_END;
1685
-
1686
- XS_URL_QUERY:
1687
- mxPushSlot(parts);
1688
- mxGetID(xsID_query);
1689
- if (!mxIsNull(the->stack)) {
1690
- if (!override || the->stack->value.string[0])
1691
- fxConcatStringC(the, result, "?");
1692
- fxConcatString(the, result, the->stack);
1693
- }
1694
- mxPop();
1695
- if (override)
1696
- goto XS_URL_END;
1697
-
1698
- XS_URL_FRAGMENT:
1699
- mxPushSlot(parts);
1700
- mxGetID(xsID_fragment);
1701
- if (!mxIsNull(the->stack)) {
1702
- if (!override || the->stack->value.string[0])
1703
- fxConcatStringC(the, result, "#");
1704
- fxConcatString(the, result, the->stack);
1705
- }
1706
- mxPop();
1707
-
1708
- XS_URL_END:
1709
- return;
1710
- }
1711
-
1712
- void fx_parseQuery(txMachine* the)
1713
- {
1714
- txSlot* result;
1715
- txSlot* string;
1716
- txSlot* pair;
1717
- txSlot* push;
1718
- txInteger offset, ampersand, equal;
1719
- fxVars(the, 2);
1720
- result = mxResult;
1721
- string = mxArgv(0);
1722
- pair = mxVarv(0);
1723
- push = mxVarv(1);
1724
-
1725
- fxNewArray(the, 0);
1726
- mxPullSlot(result);
1727
-
1728
- fxToString(the, string);
1729
-
1730
- mxPushSlot(result);
1731
- mxGetID(mxID(_push));
1732
- mxPullSlot(push);
1733
-
1734
- offset = 0;
1735
- ampersand = 0;
1736
- equal = 0;
1737
- if (string->value.string[0] == '?') {
1738
- offset++;
1739
- ampersand++;
1740
- equal++;
1741
- }
1742
- for (;;) {
1743
- char c = string->value.string[offset];
1744
- if ((c == 0) || (c == '&')) {
1745
- if (offset > ampersand) {
1746
- mxPushSlot(result);
1747
- mxPushSlot(push);
1748
- mxCall();
1749
-
1750
- fxNewInstance(the);
1751
- mxPullSlot(pair);
1752
-
1753
- if (equal == ampersand)
1754
- equal = offset;
1755
- fx_parseQueryPlus(the, string, ampersand, equal);
1756
- mxPushSlot(pair);
1757
- mxSetID(mxID(_name));
1758
- mxPop();
1759
-
1760
- equal++;
1761
-
1762
- if (equal < offset)
1763
- fx_parseQueryPlus(the, string, equal, offset);
1764
- else
1765
- mxPush(mxEmptyString);
1766
- mxPushSlot(pair);
1767
- mxSetID(mxID(_value));
1768
- mxPop();
1769
-
1770
- mxPushSlot(pair);
1771
- mxRunCount(1);
1772
- mxPop();
1773
- }
1774
- if (c == 0)
1775
- break;
1776
- ampersand = offset + 1;
1777
- equal = offset + 1;
1778
- }
1779
- else if (c == '=') {
1780
- equal = offset;
1781
- }
1782
- offset++;
1783
- }
1784
- }
1785
-
1786
- void fx_parseQueryPlus(txMachine* the, txSlot* string, txInteger from, txInteger to)
1787
- {
1788
- txString src;
1789
- txString limit;
1790
- txInteger length;
1791
- txInteger c, d;
1792
- txString dst;
1793
- src = string->value.string + from;
1794
- limit = string->value.string + to;
1795
- length = 0;
1796
- while (src < limit) {
1797
- c = c_read8(src++);
1798
- if (c == '%')
1799
- fxParseHexEscape(&src, &d);
1800
- length++;
1801
- }
1802
- length += 1;
1803
- mxPushUndefined();
1804
- the->stack->value.string = fxNewChunk(the, length);
1805
- the->stack->kind = XS_STRING_KIND;
1806
- src = string->value.string + from;
1807
- limit = string->value.string + to;
1808
- dst = the->stack->value.string;
1809
- while ((src < limit)) {
1810
- c = c_read8(src++);
1811
- if (c == '%') {
1812
- if (fxParseHexEscape(&src, &d))
1813
- *dst++ = (char)d;
1814
- else
1815
- *dst++ = '%';
1816
- }
1817
- else if (c == '+')
1818
- *dst++ = ' ';
1819
- else
1820
- *dst++ = (char)c;
1821
- }
1822
- *dst = 0;
1823
- }
1824
-
1825
- void fx_serializeQuery(txMachine* the)
1826
- {
1827
- txSlot* pairs;
1828
- txSlot* pair;
1829
- txSlot* result;
1830
-
1831
- txInteger length, index;
1832
- fxVars(the, 3);
1833
- pairs = mxVarv(0);
1834
- pair = mxVarv(1);
1835
- result = mxVarv(2);
1836
-
1837
- mxPushSlot(mxArgv(0));
1838
- mxPullSlot(pairs);
1839
-
1840
- mxPush(mxEmptyString);
1841
- mxPullSlot(result);
1842
-
1843
- mxPushSlot(pairs);
1844
- mxGetID(mxID(_length));
1845
- length = (txIndex)fxToLength(the, the->stack);
1846
- mxPop();
1847
-
1848
- index = 0;
1849
- while (index < length) {
1850
- if (index > 0)
1851
- fxConcatStringC(the, result, "&");
1852
- mxPushSlot(pairs);
1853
- mxGetIndex(index);
1854
- mxPullSlot(pair);
1855
-
1856
- mxPushSlot(pair);
1857
- mxGetID(mxID(_name));
1858
- mxPullSlot(mxArgv(0));
1859
- fx_serializeQueryPlus(the, (txString)gxFormSet);
1860
- fxConcatString(the, result, mxResult);
1861
-
1862
- fxConcatStringC(the, result, "=");
1863
-
1864
- mxPushSlot(pair);
1865
- mxGetID(mxID(_value));
1866
- mxPullSlot(mxArgv(0));
1867
- fx_serializeQueryPlus(the, (txString)gxFormSet);
1868
- fxConcatString(the, result, mxResult);
1869
- index++;
1870
- }
1871
-
1872
- *mxResult = *result;
1873
- }
1874
-
1875
- void fx_serializeQueryPlus(txMachine* the, txString theSet)
1876
- {
1877
- txString src;
1878
- txInteger length;
1879
- txBoolean same = 1;
1880
- txInteger c;
1881
- txString dst;
1882
-
1883
- src = fxToString(the, mxArgv(0));
1884
- length = 0;
1885
- while (((src = mxStringByteDecode(src, &c))) && (c != C_EOF)) {
1886
- if (c < 0x80) {
1887
- if (c == ' ') {
1888
- length += 1;
1889
- same = 0;
1890
- }
1891
- else if (c_read8(theSet + c))
1892
- length += 1;
1893
- else {
1894
- length += 3;
1895
- same = 0;
1896
- }
1897
- }
1898
- else {
1899
- if (c < 0x800)
1900
- length += 6;
1901
- else if ((0xD800 <= c) && (c <= 0xDFFF))
1902
- mxURIError("invalid string");
1903
- else if (c < 0x10000)
1904
- length += 9;
1905
- else
1906
- length += 12;
1907
- same = 0;
1908
- }
1909
- }
1910
- length += 1;
1911
- if (same) {
1912
- mxResult->value.string = mxArgv(0)->value.string;
1913
- mxResult->kind = mxArgv(0)->kind;
1914
- return;
1915
- }
1916
- mxResult->value.string = fxNewChunk(the, length);
1917
- mxResult->kind = XS_STRING_KIND;
1918
- src = mxArgv(0)->value.string;
1919
- dst = mxResult->value.string;
1920
- while (((src = mxStringByteDecode(src, &c))) && (c != C_EOF)) {
1921
- if (c < 0x80) {
1922
- if (c == ' ')
1923
- *dst++ = '+';
1924
- else if (c_read8(theSet + c))
1925
- *dst++ = (char)c;
1926
- else {
1927
- *dst++ = '%';
1928
- dst = fxStringifyHexEscape(dst, c);
1929
- }
1930
- }
1931
- else if (c < 0x800) {
1932
- *dst++ = '%';
1933
- dst = fxStringifyHexEscape(dst, 0xC0 | (c >> 6));
1934
- *dst++ = '%';
1935
- dst = fxStringifyHexEscape(dst, 0x80 | (c & 0x3F));
1936
- }
1937
- else if (c < 0x10000) {
1938
- *dst++ = '%';
1939
- dst = fxStringifyHexEscape(dst, 0xE0 | (c >> 12));
1940
- *dst++ = '%';
1941
- dst = fxStringifyHexEscape(dst, 0x80 | ((c >> 6) & 0x3F));
1942
- *dst++ = '%';
1943
- dst = fxStringifyHexEscape(dst, 0x80 | (c & 0x3F));
1944
- }
1945
- else {
1946
- *dst++ = '%';
1947
- dst = fxStringifyHexEscape(dst, 0xF0 | (c >> 18));
1948
- *dst++ = '%';
1949
- dst = fxStringifyHexEscape(dst, 0x80 | ((c >> 12) & 0x3F));
1950
- *dst++ = '%';
1951
- dst = fxStringifyHexEscape(dst, 0x80 | ((c >> 6) & 0x3F));
1952
- *dst++ = '%';
1953
- dst = fxStringifyHexEscape(dst, 0x80 | (c & 0x3F));
1954
- }
1955
- }
1956
- *dst = 0;
1957
- }
1958
-
1959
-