@agoric/xsnap 0.14.3-dev-b047af2.0 → 0.14.3-dev-2a16ddd.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 (125) hide show
  1. package/package.json +8 -15
  2. package/src/build.js +4 -61
  3. package/moddable/modules/data/base64/base64.js +0 -28
  4. package/moddable/modules/data/base64/manifest.json +0 -11
  5. package/moddable/modules/data/base64/modBase64.c +0 -188
  6. package/moddable/modules/data/binaryMessage/BinaryMessage.js +0 -106
  7. package/moddable/modules/data/crc/crc.c +0 -205
  8. package/moddable/modules/data/crc/crc.js +0 -36
  9. package/moddable/modules/data/crc/manifest.json +0 -8
  10. package/moddable/modules/data/hex/hex.js +0 -28
  11. package/moddable/modules/data/hex/manifest.json +0 -11
  12. package/moddable/modules/data/hex/modHex.c +0 -139
  13. package/moddable/modules/data/logical/logical.js +0 -32
  14. package/moddable/modules/data/logical/modLogical.c +0 -98
  15. package/moddable/modules/data/qrcode/manifest.json +0 -9
  16. package/moddable/modules/data/qrcode/qrcode.c +0 -93
  17. package/moddable/modules/data/qrcode/qrcode.js +0 -23
  18. package/moddable/modules/data/qrcode/qrcodegen.c +0 -1025
  19. package/moddable/modules/data/qrcode/qrcodegen.h +0 -267
  20. package/moddable/modules/data/text/decoder/manifest.json +0 -8
  21. package/moddable/modules/data/text/decoder/textdecoder.c +0 -480
  22. package/moddable/modules/data/text/decoder/textdecoder.js +0 -27
  23. package/moddable/modules/data/text/encoder/manifest.json +0 -8
  24. package/moddable/modules/data/text/encoder/textencoder.c +0 -232
  25. package/moddable/modules/data/text/encoder/textencoder.js +0 -24
  26. package/moddable/modules/data/tinyint/tinyint.c +0 -150
  27. package/moddable/modules/data/tinyint/tinyint.js +0 -53
  28. package/moddable/modules/data/url/manifest.json +0 -17
  29. package/moddable/modules/data/url/url.c +0 -1959
  30. package/moddable/modules/data/url/url.js +0 -210
  31. package/moddable/modules/data/wavreader/manifest.json +0 -8
  32. package/moddable/modules/data/wavreader/wavreader.js +0 -128
  33. package/moddable/modules/data/zlib/deflate.c +0 -161
  34. package/moddable/modules/data/zlib/deflate.js +0 -63
  35. package/moddable/modules/data/zlib/inflate.c +0 -145
  36. package/moddable/modules/data/zlib/inflate.js +0 -66
  37. package/moddable/modules/data/zlib/manifest_deflate.json +0 -9
  38. package/moddable/modules/data/zlib/manifest_inflate.json +0 -9
  39. package/moddable/modules/data/zlib/miniz.c +0 -4924
  40. package/moddable/xs/includes/xs.d.ts +0 -73
  41. package/moddable/xs/includes/xs.h +0 -1533
  42. package/moddable/xs/includes/xsmc.h +0 -206
  43. package/moddable/xs/makefiles/lin/makefile +0 -33
  44. package/moddable/xs/makefiles/lin/xsc.mk +0 -118
  45. package/moddable/xs/makefiles/lin/xsid.mk +0 -90
  46. package/moddable/xs/makefiles/lin/xsl.mk +0 -168
  47. package/moddable/xs/makefiles/lin/xst.mk +0 -201
  48. package/moddable/xs/makefiles/mac/makefile +0 -33
  49. package/moddable/xs/makefiles/mac/xsc.mk +0 -130
  50. package/moddable/xs/makefiles/mac/xsid.mk +0 -102
  51. package/moddable/xs/makefiles/mac/xsl.mk +0 -177
  52. package/moddable/xs/makefiles/mac/xst.mk +0 -203
  53. package/moddable/xs/makefiles/mac/xst_no_asan.txt +0 -52
  54. package/moddable/xs/makefiles/win/build.bat +0 -26
  55. package/moddable/xs/makefiles/win/xsc.mak +0 -142
  56. package/moddable/xs/makefiles/win/xsid.mak +0 -113
  57. package/moddable/xs/makefiles/win/xsl.mak +0 -186
  58. package/moddable/xs/makefiles/win/xst.mak +0 -195
  59. package/moddable/xs/platforms/lin_xs.h +0 -99
  60. package/moddable/xs/platforms/mac_xs.h +0 -97
  61. package/moddable/xs/platforms/wasm_xs.h +0 -79
  62. package/moddable/xs/platforms/win_xs.h +0 -104
  63. package/moddable/xs/platforms/xsHost.h +0 -63
  64. package/moddable/xs/platforms/xsPlatform.h +0 -618
  65. package/moddable/xs/sources/xsAPI.c +0 -2555
  66. package/moddable/xs/sources/xsAll.c +0 -294
  67. package/moddable/xs/sources/xsAll.h +0 -2741
  68. package/moddable/xs/sources/xsArguments.c +0 -222
  69. package/moddable/xs/sources/xsArray.c +0 -2657
  70. package/moddable/xs/sources/xsAtomics.c +0 -844
  71. package/moddable/xs/sources/xsBigInt.c +0 -1859
  72. package/moddable/xs/sources/xsBoolean.c +0 -109
  73. package/moddable/xs/sources/xsCode.c +0 -4493
  74. package/moddable/xs/sources/xsCommon.c +0 -1710
  75. package/moddable/xs/sources/xsCommon.h +0 -1142
  76. package/moddable/xs/sources/xsDataView.c +0 -2890
  77. package/moddable/xs/sources/xsDate.c +0 -1541
  78. package/moddable/xs/sources/xsDebug.c +0 -2710
  79. package/moddable/xs/sources/xsDefaults.c +0 -134
  80. package/moddable/xs/sources/xsError.c +0 -353
  81. package/moddable/xs/sources/xsFunction.c +0 -776
  82. package/moddable/xs/sources/xsGenerator.c +0 -865
  83. package/moddable/xs/sources/xsGlobal.c +0 -839
  84. package/moddable/xs/sources/xsJSON.c +0 -1091
  85. package/moddable/xs/sources/xsLexical.c +0 -1969
  86. package/moddable/xs/sources/xsLockdown.c +0 -933
  87. package/moddable/xs/sources/xsMapSet.c +0 -1649
  88. package/moddable/xs/sources/xsMarshall.c +0 -1020
  89. package/moddable/xs/sources/xsMath.c +0 -624
  90. package/moddable/xs/sources/xsMemory.c +0 -1941
  91. package/moddable/xs/sources/xsModule.c +0 -3101
  92. package/moddable/xs/sources/xsNumber.c +0 -560
  93. package/moddable/xs/sources/xsObject.c +0 -1102
  94. package/moddable/xs/sources/xsPlatforms.c +0 -480
  95. package/moddable/xs/sources/xsProfile.c +0 -577
  96. package/moddable/xs/sources/xsPromise.c +0 -1199
  97. package/moddable/xs/sources/xsProperty.c +0 -636
  98. package/moddable/xs/sources/xsProxy.c +0 -1014
  99. package/moddable/xs/sources/xsRegExp.c +0 -1168
  100. package/moddable/xs/sources/xsRun.c +0 -4889
  101. package/moddable/xs/sources/xsScope.c +0 -1293
  102. package/moddable/xs/sources/xsScript.c +0 -288
  103. package/moddable/xs/sources/xsScript.h +0 -1186
  104. package/moddable/xs/sources/xsSnapshot.c +0 -2161
  105. package/moddable/xs/sources/xsSnapshot.h +0 -51
  106. package/moddable/xs/sources/xsSourceMap.c +0 -218
  107. package/moddable/xs/sources/xsString.c +0 -3332
  108. package/moddable/xs/sources/xsSymbol.c +0 -503
  109. package/moddable/xs/sources/xsSyntaxical.c +0 -4193
  110. package/moddable/xs/sources/xsTree.c +0 -1893
  111. package/moddable/xs/sources/xsType.c +0 -1488
  112. package/moddable/xs/sources/xsdtoa.c +0 -6672
  113. package/moddable/xs/sources/xsmc.c +0 -340
  114. package/moddable/xs/sources/xsre.c +0 -7578
  115. package/xsnap-native/xsnap/makefiles/lin/makefile +0 -10
  116. package/xsnap-native/xsnap/makefiles/lin/xsnap-worker.mk +0 -153
  117. package/xsnap-native/xsnap/makefiles/lin/xsnap.mk +0 -144
  118. package/xsnap-native/xsnap/makefiles/mac/makefile +0 -10
  119. package/xsnap-native/xsnap/makefiles/mac/xsnap-worker.mk +0 -162
  120. package/xsnap-native/xsnap/makefiles/mac/xsnap.mk +0 -153
  121. package/xsnap-native/xsnap/sources/xsnap-worker.c +0 -996
  122. package/xsnap-native/xsnap/sources/xsnap.c +0 -716
  123. package/xsnap-native/xsnap/sources/xsnap.h +0 -142
  124. package/xsnap-native/xsnap/sources/xsnapPlatform.c +0 -1496
  125. 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
-