@magic-xpa/utils 4.1200.0-dev4120.21 → 4.1200.0-dev4120.212
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.
- package/fesm2022/magic-xpa-utils.mjs +1222 -72
- package/fesm2022/magic-xpa-utils.mjs.map +1 -1
- package/index.d.ts +3 -0
- package/package.json +2 -4
- package/src/MsgInterface.d.ts +5 -0
- package/src/StrUtil.d.ts +1 -0
- package/src/XMLConstants.d.ts +2 -0
- package/esm2022/index.mjs +0 -27
- package/esm2022/magic-xpa-utils.mjs +0 -2
- package/esm2022/src/Base64.mjs +0 -164
- package/esm2022/src/ChoiceUtils.mjs +0 -79
- package/esm2022/src/Constants.mjs +0 -74
- package/esm2022/src/DateTimeUtils.mjs +0 -54
- package/esm2022/src/DateUtil.mjs +0 -58
- package/esm2022/src/InternalInterface.mjs +0 -341
- package/esm2022/src/JSON_Utils.mjs +0 -7
- package/esm2022/src/Logger.mjs +0 -216
- package/esm2022/src/MagicConstants.mjs +0 -12
- package/esm2022/src/Misc.mjs +0 -98
- package/esm2022/src/MsgInterface.mjs +0 -192
- package/esm2022/src/PICInterface.mjs +0 -60
- package/esm2022/src/PlatformUtils.mjs +0 -11
- package/esm2022/src/Queue.mjs +0 -28
- package/esm2022/src/Randomizer.mjs +0 -34
- package/esm2022/src/RequestInfo.mjs +0 -28
- package/esm2022/src/Rtf.mjs +0 -614
- package/esm2022/src/StorageAttribute.mjs +0 -84
- package/esm2022/src/StrUtil.mjs +0 -453
- package/esm2022/src/SyncExecutionHelper.mjs +0 -21
- package/esm2022/src/UtilDateJpn.mjs +0 -232
- package/esm2022/src/UtilImeJpn.mjs +0 -13
- package/esm2022/src/UtilStrByteMode.mjs +0 -300
- package/esm2022/src/XMLConstants.mjs +0 -169
- package/esm2022/src/Xml/XmlParser.mjs +0 -247
- package/esm2022/src/enums.mjs +0 -1763
|
@@ -1,33 +1,90 @@
|
|
|
1
1
|
import { Encoding, StringBuilder, Hashtable, Stack, NChar, NNumber, NString, RefParam, isNullOrUndefined, DateTime, ISO_8859_1_Encoding, ApplicationException, Int32, Exception, List, Thread, Debug } from '@magic-xpa/mscorelib';
|
|
2
2
|
import { parseString } from 'xml2js';
|
|
3
3
|
|
|
4
|
+
/// <summary>JPN: DBCS support
|
|
5
|
+
/// Utility Class for String
|
|
6
|
+
/// In this class, considering DBCS, strings are counted by the number
|
|
7
|
+
/// of bytes, not the number of characters.
|
|
8
|
+
/// </summary>
|
|
9
|
+
/// <author> Toshiro Nakayoshi (MSJ) </author>
|
|
4
10
|
class UtilStrByteMode {
|
|
5
11
|
static Encoding = Encoding.UTF8;
|
|
12
|
+
// TODO : need to check what to do with CultureInfo
|
|
6
13
|
static strNavigatorLang = window.navigator.language;
|
|
7
14
|
static _bLocaleDefLangJPN = UtilStrByteMode.strNavigatorLang.startsWith('ja');
|
|
8
15
|
static _bLocaleDefLangCHN = UtilStrByteMode.strNavigatorLang.startsWith('zh');
|
|
9
16
|
static _bLocaleDefLangKOR = UtilStrByteMode.strNavigatorLang.startsWith('ko');
|
|
17
|
+
/// <summary> Checks the environment whether it is running on DBCS environment
|
|
18
|
+
/// Returns true if the language code for the current default Locale is
|
|
19
|
+
/// DBCS language (in non-Unicode encoding).
|
|
20
|
+
///
|
|
21
|
+
/// </summary>
|
|
22
|
+
/// <returns> true if DBCS, or false if SBCS
|
|
23
|
+
/// </returns>
|
|
10
24
|
static isLocaleDefLangDBCS() {
|
|
11
25
|
return UtilStrByteMode._bLocaleDefLangJPN || UtilStrByteMode._bLocaleDefLangCHN || UtilStrByteMode._bLocaleDefLangKOR;
|
|
12
26
|
}
|
|
27
|
+
/// <summary> Checks whether the language code for the current default Locale
|
|
28
|
+
/// is JAPANESE.
|
|
29
|
+
///
|
|
30
|
+
/// </summary>
|
|
31
|
+
/// <returns> true if JAPANESE, or false if not
|
|
32
|
+
/// </returns>
|
|
13
33
|
static isLocaleDefLangJPN() {
|
|
14
34
|
return UtilStrByteMode._bLocaleDefLangJPN;
|
|
15
35
|
}
|
|
36
|
+
/// <summary> Checks whether the language code for the current default Locale
|
|
37
|
+
/// is KOREAN.
|
|
38
|
+
///
|
|
39
|
+
/// </summary>
|
|
40
|
+
/// <returns> true if KOREAN, or false if not
|
|
41
|
+
/// </returns>
|
|
16
42
|
static isLocaleDefLangKOR() {
|
|
17
43
|
return UtilStrByteMode._bLocaleDefLangKOR;
|
|
18
44
|
}
|
|
19
45
|
static isKoreanCharacter(c) {
|
|
20
|
-
return (44032 <= c && c <= 55203) || (4352 <= c && c <= 4607) || (12592 <= c && c <= 12687) || (43360 <= c && c <= 43391) || (55216 <= c && c <= 55295);
|
|
21
|
-
}
|
|
46
|
+
return (44032 <= /*'가'*/ c && c <= 55203 /*'힣'*/) || (4352 <= /*'ᄀ'*/ c && c <= 4607 /*'ᇿ'*/) || (12592 <= /*''*/ c && c <= 12687 /*''*/) || (43360 <= /*'ꥠ'*/ c && c <= 43391 /*''*/) || (55216 <= /*'ힰ'*/ c && c <= 55295 /*''*/);
|
|
47
|
+
}
|
|
48
|
+
/// <summary> Length of String
|
|
49
|
+
/// Returns the number of bytes (in default encoding).
|
|
50
|
+
///
|
|
51
|
+
/// </summary>
|
|
52
|
+
/// <param name="strVal:">string (in Unicode)
|
|
53
|
+
/// </param>
|
|
54
|
+
/// <returns> the number of bytes (in default encoding)
|
|
55
|
+
///
|
|
56
|
+
/// Example: lenB("abXYc")
|
|
57
|
+
/// Where 'a', 'b' and 'c' are SBCS, and 'X' and 'Y' are DBCS, it returns
|
|
58
|
+
/// 7.
|
|
59
|
+
/// </returns>
|
|
22
60
|
static lenB(strVal) {
|
|
61
|
+
// convert to byte[] by default-encoding
|
|
23
62
|
return UtilStrByteMode.Encoding.GetByteCount(strVal);
|
|
24
63
|
}
|
|
64
|
+
/// <summary> Substring of String
|
|
65
|
+
/// Extracts a specified number of characters (a substring) from a string.
|
|
66
|
+
/// If a DBCS character is divided in two, it will be replace to a space.
|
|
67
|
+
///
|
|
68
|
+
/// </summary>
|
|
69
|
+
/// <param name="strVal:">string (in Unicode)
|
|
70
|
+
/// </param>
|
|
71
|
+
/// <param name="ofs:">starting position (byte) of the substring
|
|
72
|
+
/// </param>
|
|
73
|
+
/// <param name="len:">number of bytes to be extracted (i.e. bytes of substring)
|
|
74
|
+
/// </param>
|
|
75
|
+
/// <returns> substring
|
|
76
|
+
///
|
|
77
|
+
/// Example: midB("abXYc", 2, 4)
|
|
78
|
+
/// Where 'a', 'b' and 'c' are SBCS, and 'X' and 'Y' are DBCS, it returns
|
|
79
|
+
/// "bX ".
|
|
80
|
+
/// </returns>
|
|
25
81
|
static midB(strVal, ofs, len) {
|
|
26
|
-
let intValidMaxIndex = -1;
|
|
27
|
-
let intValidMinIndex = -1;
|
|
28
|
-
let bHeadSpace = false;
|
|
29
|
-
let bEndSpace = false;
|
|
82
|
+
let intValidMaxIndex = -1; // param #1 of substring
|
|
83
|
+
let intValidMinIndex = -1; // param #2 of substring
|
|
84
|
+
let bHeadSpace = false; // flag: need to add space
|
|
85
|
+
let bEndSpace = false; // flag: need to add space
|
|
30
86
|
let strRet;
|
|
87
|
+
// check and modify ofs & len
|
|
31
88
|
if (len <= 0)
|
|
32
89
|
return "";
|
|
33
90
|
if (ofs <= 0) {
|
|
@@ -41,6 +98,7 @@ class UtilStrByteMode {
|
|
|
41
98
|
let LenMax = intByteLength - ofs;
|
|
42
99
|
if (LenMax < len)
|
|
43
100
|
len = LenMax;
|
|
101
|
+
// set MinIndex and MaxIndex for substring
|
|
44
102
|
intByteLength = 0;
|
|
45
103
|
for (let intIndex = 0; intIndex < strVal.length; intIndex = intIndex + 1) {
|
|
46
104
|
let s = strVal.substr(intIndex, 1);
|
|
@@ -68,7 +126,9 @@ class UtilStrByteMode {
|
|
|
68
126
|
}
|
|
69
127
|
}
|
|
70
128
|
}
|
|
129
|
+
// prepare for substring
|
|
71
130
|
let strbufAddingBuf = new StringBuilder(len);
|
|
131
|
+
// execute Mid
|
|
72
132
|
if (bHeadSpace) {
|
|
73
133
|
strbufAddingBuf.Append(' ');
|
|
74
134
|
}
|
|
@@ -82,9 +142,39 @@ class UtilStrByteMode {
|
|
|
82
142
|
strbufAddingBuf = null;
|
|
83
143
|
return strRet;
|
|
84
144
|
}
|
|
145
|
+
/// <summary> Get Characters from Left of String
|
|
146
|
+
/// Returns a specified number of bytes from the left side of a string.
|
|
147
|
+
/// If a DBCS character is divided in two, it will be replace to a space.
|
|
148
|
+
///
|
|
149
|
+
/// </summary>
|
|
150
|
+
/// <param name="strVal:">string (in Unicode)
|
|
151
|
+
/// </param>
|
|
152
|
+
/// <param name="len:">number of bytes to be retured
|
|
153
|
+
/// </param>
|
|
154
|
+
/// <returns> output string
|
|
155
|
+
///
|
|
156
|
+
/// Example: leftB("abXYc", 4)
|
|
157
|
+
/// Where 'a', 'b' and 'c' are SBCS, and 'X' and 'Y' are DBCS, it returns
|
|
158
|
+
/// "abX".
|
|
159
|
+
/// </returns>
|
|
85
160
|
static leftB(strVal, len) {
|
|
86
161
|
return UtilStrByteMode.midB(strVal, 0, len);
|
|
87
162
|
}
|
|
163
|
+
/// <summary> Get Characters from Right of String
|
|
164
|
+
/// Returns a specified number of bytes from the right side of a string.
|
|
165
|
+
/// If a DBCS character is divided in two, it will be replace to a space.
|
|
166
|
+
///
|
|
167
|
+
/// </summary>
|
|
168
|
+
/// <param name="strVal:">string (in Unicode)
|
|
169
|
+
/// </param>
|
|
170
|
+
/// <param name="len:">number of bytes to be retured
|
|
171
|
+
/// </param>
|
|
172
|
+
/// <returns> output string
|
|
173
|
+
///
|
|
174
|
+
/// Example: rightB("abXYc", 4)
|
|
175
|
+
/// Where 'a', 'b' and 'c' are SBCS, and 'X' and 'Y' are DBCS, it returns
|
|
176
|
+
/// " Yc".
|
|
177
|
+
/// </returns>
|
|
88
178
|
static rightB(strVal, len) {
|
|
89
179
|
let byteFldsValLen = UtilStrByteMode.lenB(strVal);
|
|
90
180
|
if (len < 0) {
|
|
@@ -96,6 +186,27 @@ class UtilStrByteMode {
|
|
|
96
186
|
}
|
|
97
187
|
return UtilStrByteMode.midB(strVal, ofs, len);
|
|
98
188
|
}
|
|
189
|
+
/// <summary> Insert String
|
|
190
|
+
/// Inserts one string into another.
|
|
191
|
+
/// If a DBCS character is divided in two, it will be replace to a space.
|
|
192
|
+
///
|
|
193
|
+
/// </summary>
|
|
194
|
+
/// <param name="strTarget:">A string that represents the target string.
|
|
195
|
+
/// </param>
|
|
196
|
+
/// <param name="strSource:">A string that represents the source string.
|
|
197
|
+
/// </param>
|
|
198
|
+
/// <param name="ofs:">A number that represents the starting position (byte) in
|
|
199
|
+
/// the target.
|
|
200
|
+
/// </param>
|
|
201
|
+
/// <param name="len:">A number that represents the number of bytes from the
|
|
202
|
+
/// source that will be inserted into the target.
|
|
203
|
+
/// </param>
|
|
204
|
+
/// <returns> output string
|
|
205
|
+
///
|
|
206
|
+
/// Example: insB("abXYc", "de", 4, 1)
|
|
207
|
+
/// Where 'a', 'b', 'c', 'd' and 'e' are SBCS, and 'X' and 'Y' are DBCS,
|
|
208
|
+
/// it returns "ab d Yc".
|
|
209
|
+
/// </returns>
|
|
99
210
|
static insB(strTarget, strSource, ofs, len) {
|
|
100
211
|
if (ofs < 0) {
|
|
101
212
|
ofs = 0;
|
|
@@ -122,6 +233,24 @@ class UtilStrByteMode {
|
|
|
122
233
|
strbufRetVal.Append(UtilStrByteMode.rightB(strTarget, intTargetLenB - ofs));
|
|
123
234
|
return strbufRetVal.ToString();
|
|
124
235
|
}
|
|
236
|
+
/// <summary> Delete Characters
|
|
237
|
+
/// Delete characters from a string.
|
|
238
|
+
/// If a DBCS character is divided in two, it will be replace to a space.
|
|
239
|
+
///
|
|
240
|
+
/// </summary>
|
|
241
|
+
/// <param name="strVal:">string (in Unicode)
|
|
242
|
+
/// </param>
|
|
243
|
+
/// <param name="ofs:">The position (byte) of the first character to be deleted.
|
|
244
|
+
/// </param>
|
|
245
|
+
/// <param name="len:">The number of characters to be deleted, beginning with
|
|
246
|
+
/// position start and proceeding rightward.
|
|
247
|
+
/// </param>
|
|
248
|
+
/// <returns> output string
|
|
249
|
+
///
|
|
250
|
+
/// Example: delB("abXYc", 2, 4)
|
|
251
|
+
/// Where 'a', 'b' and 'c' are SBCS, and 'X' and 'Y' are DBCS, it returns
|
|
252
|
+
/// "a c".
|
|
253
|
+
/// </returns>
|
|
125
254
|
static delB(strVal, ofs, len) {
|
|
126
255
|
if (ofs < 0) {
|
|
127
256
|
ofs = 0;
|
|
@@ -153,16 +282,55 @@ class UtilStrByteMode {
|
|
|
153
282
|
}
|
|
154
283
|
return strRet;
|
|
155
284
|
}
|
|
285
|
+
/// <summary> In-String Search
|
|
286
|
+
/// Returns a number that represents the first position (byte) of a
|
|
287
|
+
/// substring within a string.
|
|
288
|
+
///
|
|
289
|
+
/// </summary>
|
|
290
|
+
/// <param name="strTarget:">string (in Unicode)
|
|
291
|
+
/// </param>
|
|
292
|
+
/// <param name="strSearch:">string which will be the search argument in string
|
|
293
|
+
/// </param>
|
|
294
|
+
/// <returns> number, 0 if not found
|
|
295
|
+
///
|
|
296
|
+
/// Example: instrB("abXYc", "Y")
|
|
297
|
+
/// Where 'a', 'b' and 'c' are SBCS, and 'X' and 'Y' are DBCS, it returns
|
|
298
|
+
/// 5.
|
|
299
|
+
/// </returns>
|
|
156
300
|
static instrB(strTarget, strSearch) {
|
|
157
301
|
if (strSearch.length === 0) {
|
|
302
|
+
// nothing to look for
|
|
158
303
|
return 0;
|
|
159
304
|
}
|
|
160
305
|
let ofs = strTarget.indexOf(strSearch);
|
|
161
306
|
if (ofs < 0) {
|
|
307
|
+
// not found
|
|
162
308
|
return 0;
|
|
163
309
|
}
|
|
164
310
|
return UtilStrByteMode.lenB(strTarget.substr(0, ofs)) + 1;
|
|
165
311
|
}
|
|
312
|
+
/// <summary> Replace Substring Within a String (Byte Mode)
|
|
313
|
+
/// Replaces a substring within a string with another substring.
|
|
314
|
+
/// If a DBCS character is divided in two, it will be replace to a space.
|
|
315
|
+
///
|
|
316
|
+
/// </summary>
|
|
317
|
+
/// <param name="strTarget:">target string where the replacement will take place.
|
|
318
|
+
/// </param>
|
|
319
|
+
/// <param name="strOrigin:">string that provides the substring to be copied to
|
|
320
|
+
/// target.
|
|
321
|
+
/// </param>
|
|
322
|
+
/// <param name="ofs:">the first position (byte) in the target string that will
|
|
323
|
+
/// receive the substring from origin.
|
|
324
|
+
/// </param>
|
|
325
|
+
/// <param name="len:">the number of bytes that will be moved from origin to
|
|
326
|
+
/// target, starting from the leftmost character of origin.
|
|
327
|
+
/// </param>
|
|
328
|
+
/// <returns> string containing modified target string
|
|
329
|
+
///
|
|
330
|
+
/// Example: repB("abXYc", "de", 4, 2)
|
|
331
|
+
/// Where 'a', 'b', 'c', 'd' and 'e' are SBCS, and 'X' and 'Y' are DBCS,
|
|
332
|
+
/// it returns "ab de c".
|
|
333
|
+
/// </returns>
|
|
166
334
|
static repB(strTarget, strOrigin, ofs, len) {
|
|
167
335
|
let strbufAddingBuf = new StringBuilder();
|
|
168
336
|
if (ofs < 0) {
|
|
@@ -185,12 +353,33 @@ class UtilStrByteMode {
|
|
|
185
353
|
if (intRightLen > 0) {
|
|
186
354
|
strbufAddingBuf.Append(UtilStrByteMode.rightB(strTarget, intRightLen));
|
|
187
355
|
}
|
|
356
|
+
// add blanks to the end
|
|
188
357
|
intAddSpaceLen = len - UtilStrByteMode.lenB(strOrigin);
|
|
189
358
|
for (; intAddSpaceLen > 0; intAddSpaceLen--) {
|
|
190
359
|
strbufAddingBuf.Append(' ');
|
|
191
360
|
}
|
|
192
361
|
return strbufAddingBuf.ToString();
|
|
193
362
|
}
|
|
363
|
+
/// <summary> Replace Substring Within a String (Character Mode)
|
|
364
|
+
/// Replaces a substring within a string with another substring.
|
|
365
|
+
///
|
|
366
|
+
/// </summary>
|
|
367
|
+
/// <param name="strTarget:">target string where the replacement will take place.
|
|
368
|
+
/// </param>
|
|
369
|
+
/// <param name="strOrigin:">string that provides the substring to be copied to
|
|
370
|
+
/// target.
|
|
371
|
+
/// </param>
|
|
372
|
+
/// <param name="ofs:">the first position (character) in the target string that
|
|
373
|
+
/// will receive the substring from origin.
|
|
374
|
+
/// </param>
|
|
375
|
+
/// <param name="len:">the number of characters that will be moved from origin
|
|
376
|
+
/// to target, starting from the leftmost character of origin.
|
|
377
|
+
/// </param>
|
|
378
|
+
/// <returns> string containing modified target string
|
|
379
|
+
///
|
|
380
|
+
/// Example: repB("abXYc", "de", 4, 2)
|
|
381
|
+
/// Whether each character is SBCS or DBCS, it returns "abXde".
|
|
382
|
+
/// </returns>
|
|
194
383
|
static repC(strTarget, strOrigin, ofs, len) {
|
|
195
384
|
let strbufAddingBuf = new StringBuilder();
|
|
196
385
|
if (ofs < 0) {
|
|
@@ -205,6 +394,7 @@ class UtilStrByteMode {
|
|
|
205
394
|
len = 0;
|
|
206
395
|
}
|
|
207
396
|
strbufAddingBuf.Append(strTarget.substr(0, ofs));
|
|
397
|
+
// add blanks between strTarget and strOrigin
|
|
208
398
|
let intAddSpaceLen = ofs - strTarget.length;
|
|
209
399
|
for (; intAddSpaceLen > 0; intAddSpaceLen--)
|
|
210
400
|
strbufAddingBuf.Append(' ');
|
|
@@ -218,9 +408,18 @@ class UtilStrByteMode {
|
|
|
218
408
|
}
|
|
219
409
|
return strbufAddingBuf.ToString();
|
|
220
410
|
}
|
|
411
|
+
/// <summary> Checks whether a character is 1 byte (halfwidth) or not (fullwidth)
|
|
412
|
+
/// Returns true if the character is represented by 1 byte in non-Unicode
|
|
413
|
+
/// encoding.
|
|
414
|
+
/// </summary>
|
|
415
|
+
/// <param name="letter:">a character to be checked.
|
|
416
|
+
/// </param>
|
|
417
|
+
/// <returns> true if the character is halfwidth (SBCS), or false if it is
|
|
418
|
+
/// fullwidth (DBCS).
|
|
419
|
+
/// </returns>
|
|
221
420
|
static isHalfWidth(str) {
|
|
222
421
|
let letter = str.charCodeAt(0);
|
|
223
|
-
if (32 <= letter && letter <= 126) {
|
|
422
|
+
if (32 <= /*' '*/ letter && letter <= 126 /*'~'*/) {
|
|
224
423
|
return true;
|
|
225
424
|
}
|
|
226
425
|
else {
|
|
@@ -230,18 +429,33 @@ class UtilStrByteMode {
|
|
|
230
429
|
}
|
|
231
430
|
return false;
|
|
232
431
|
}
|
|
432
|
+
/// <summary> Checks whether a character is halfwidth digit letter
|
|
433
|
+
/// Do not use "Character.isDigit" which cannot distinguish between
|
|
434
|
+
/// halfwidth digit letter(SBCS) and fullwidth difit letter(DBCS).
|
|
435
|
+
/// </summary>
|
|
436
|
+
/// <param name="letter:">a character to be checked.
|
|
437
|
+
/// </param>
|
|
438
|
+
/// <returns> true if the character is halfwidth digit letter, or
|
|
439
|
+
/// false if it is DBCS or not digit letter.
|
|
440
|
+
/// </returns>
|
|
233
441
|
static isDigit(letter) {
|
|
234
|
-
return 48 <= letter.charCodeAt(0) && letter.charCodeAt(0) <= 57
|
|
235
|
-
}
|
|
442
|
+
return 48 <= /*'0'*/ letter.charCodeAt(0) && letter.charCodeAt(0) <= 57 /*'9'*/;
|
|
443
|
+
}
|
|
444
|
+
/// <summary>Checks whether a character is one of those supported for # Alpha Mask</summary>
|
|
445
|
+
/// <param name="letter:">a character to be checked.
|
|
446
|
+
/// </param>
|
|
447
|
+
/// <returns> true if the character is halfwidth digit letter, or
|
|
448
|
+
/// false if it is DBCS or not digit letter.
|
|
449
|
+
/// </returns>
|
|
236
450
|
static asNumeric(letter) {
|
|
237
451
|
let result;
|
|
238
452
|
switch (letter.charCodeAt(0)) {
|
|
239
|
-
case 42:
|
|
240
|
-
case 43:
|
|
241
|
-
case 44:
|
|
242
|
-
case 45:
|
|
243
|
-
case 46:
|
|
244
|
-
case 47:
|
|
453
|
+
case 42: /*'*'*/
|
|
454
|
+
case 43: /*'+'*/
|
|
455
|
+
case 44: /*','*/
|
|
456
|
+
case 45: /*'-'*/
|
|
457
|
+
case 46: /*'.'*/
|
|
458
|
+
case 47: /*'/'*/
|
|
245
459
|
result = true;
|
|
246
460
|
break;
|
|
247
461
|
default:
|
|
@@ -250,12 +464,47 @@ class UtilStrByteMode {
|
|
|
250
464
|
}
|
|
251
465
|
return result;
|
|
252
466
|
}
|
|
467
|
+
/// <summary> Converts a position for the 1st string (Source) to a position for
|
|
468
|
+
/// the 2nd string (Dest).
|
|
469
|
+
/// If a double byte character exists in the strings, the position for the
|
|
470
|
+
/// Source could be different from the position for the Dest.
|
|
471
|
+
/// (DBCS Support)
|
|
472
|
+
///
|
|
473
|
+
/// </summary>
|
|
474
|
+
/// <param name="strSource:">Source string
|
|
475
|
+
/// </param>
|
|
476
|
+
/// <param name="strDest:">Dest string
|
|
477
|
+
/// </param>
|
|
478
|
+
/// <param name="pos:">position in the Source string
|
|
479
|
+
/// </param>
|
|
480
|
+
/// <param name="isAdvance:">advance or retreat the ret pos if a DBCS char is split
|
|
481
|
+
/// </param>
|
|
482
|
+
/// <returns> position in the Dest string
|
|
483
|
+
///
|
|
484
|
+
/// Example: convPos("abcYZ", "YZabc", 4)
|
|
485
|
+
/// It returns 4, if the all characters in the strings are SBCS.
|
|
486
|
+
///
|
|
487
|
+
/// If 'a', 'b' and 'c' are SBCS, and 'Y' and 'Z' are DBCS, it
|
|
488
|
+
/// returns 3.
|
|
489
|
+
/// pos
|
|
490
|
+
/// Unicode index 0 1 2 3 [4]
|
|
491
|
+
/// +-------------+
|
|
492
|
+
/// Source string |a|b|c| Y | Z |
|
|
493
|
+
/// +-------------+
|
|
494
|
+
/// ANSI index 0 1 2 3 4[5]6
|
|
495
|
+
/// +-------------+
|
|
496
|
+
/// Dest string | Y | Z |a|b|c|
|
|
497
|
+
/// +-------------+
|
|
498
|
+
/// Unicode index 0 1 2[3]4
|
|
499
|
+
/// ret
|
|
500
|
+
/// </returns>
|
|
253
501
|
static convPos(strSource, strDest, pos, isAdvance) {
|
|
254
502
|
let retPos;
|
|
255
503
|
if (pos < 0)
|
|
256
504
|
return 0;
|
|
257
505
|
if (pos > strSource.length)
|
|
258
506
|
pos = strSource.length;
|
|
507
|
+
// add blanks to the Dest string if it is shorter than the Src string
|
|
259
508
|
let diffLen = UtilStrByteMode.lenB(strSource) - UtilStrByteMode.lenB(strDest);
|
|
260
509
|
if (diffLen > 0) {
|
|
261
510
|
let stringBuilder = new StringBuilder(strDest);
|
|
@@ -266,11 +515,23 @@ class UtilStrByteMode {
|
|
|
266
515
|
let byteSource = UtilStrByteMode.Encoding.GetBytes(strSource.substr(0, pos));
|
|
267
516
|
let strLeftB = UtilStrByteMode.leftB(strDest, byteSource.length);
|
|
268
517
|
retPos = strLeftB.length;
|
|
269
|
-
if (!isAdvance && retPos > 0 && strLeftB.charCodeAt(retPos - 1) === 32 && strDest.charCodeAt(retPos - 1) !== 32) {
|
|
518
|
+
if (!isAdvance && retPos > 0 && strLeftB.charCodeAt(retPos - 1) === 32 /*' '*/ && strDest.charCodeAt(retPos - 1) !== 32 /*' '*/) {
|
|
270
519
|
retPos = retPos - 1;
|
|
271
520
|
}
|
|
272
521
|
return retPos;
|
|
273
522
|
}
|
|
523
|
+
/// <summary> return the number of characters of picture which corresponds to
|
|
524
|
+
/// given string.
|
|
525
|
+
/// </summary>
|
|
526
|
+
/// <param name="str:">given string
|
|
527
|
+
/// </param>
|
|
528
|
+
/// <param name="picture:">picture
|
|
529
|
+
/// </param>
|
|
530
|
+
/// <returns> minimal length of picture
|
|
531
|
+
/// Example: getMinLenPicture("ZZ20/11/", "JJJJYY/MM/DD") [ZZ is DBCS]
|
|
532
|
+
/// It returns 10.
|
|
533
|
+
/// </returns>
|
|
534
|
+
/// (DBCS Support)
|
|
274
535
|
static getMinLenPicture(str, picture) {
|
|
275
536
|
let len = 0;
|
|
276
537
|
if (UtilStrByteMode.lenB(picture) - UtilStrByteMode.lenB(str) > 0) {
|
|
@@ -280,6 +541,18 @@ class UtilStrByteMode {
|
|
|
280
541
|
len = picture.length;
|
|
281
542
|
return len;
|
|
282
543
|
}
|
|
544
|
+
/// <summary>
|
|
545
|
+
/// </summary> Compares two specified strings in the DBCS sort order and returns an integer
|
|
546
|
+
/// that indicates their relative position.
|
|
547
|
+
/// <param name="str1:">The first string to compare.
|
|
548
|
+
/// </param>
|
|
549
|
+
/// <param name="str2:">The second string to compare.
|
|
550
|
+
/// </param>
|
|
551
|
+
/// <returns>an integer that indicates the lexical relationship between the two strings.
|
|
552
|
+
/// -1: str1 is less than str2.
|
|
553
|
+
/// 0: str1 equals str2.
|
|
554
|
+
/// 1: str1 is greater than str2.
|
|
555
|
+
/// </returns>
|
|
283
556
|
static strcmp(str1, str2) {
|
|
284
557
|
let array1 = UtilStrByteMode.Encoding.GetBytes(str1);
|
|
285
558
|
let array2 = UtilStrByteMode.Encoding.GetBytes(str2);
|
|
@@ -300,19 +573,28 @@ class UtilStrByteMode {
|
|
|
300
573
|
}
|
|
301
574
|
}
|
|
302
575
|
|
|
576
|
+
//@dynamic
|
|
303
577
|
class Rtf_SYMBOL {
|
|
304
578
|
szKeyword = null;
|
|
579
|
+
/* RTF keyword */
|
|
305
580
|
kwd = null;
|
|
581
|
+
/* base action to take */
|
|
306
582
|
idxInRgprop = null;
|
|
583
|
+
/* index into property table if kwd == kwdProp */
|
|
584
|
+
/* index into destination table if kwd == kwdDest */
|
|
585
|
+
/* character to print if kwd == kwdChar */
|
|
307
586
|
constructor(keyWord, kwd, idxInRgprop) {
|
|
308
587
|
this.szKeyword = keyWord;
|
|
309
588
|
this.kwd = kwd;
|
|
310
589
|
this.idxInRgprop = idxInRgprop;
|
|
311
590
|
}
|
|
312
591
|
}
|
|
592
|
+
// @dynamic
|
|
313
593
|
class Rtf_PROP {
|
|
314
594
|
actn = null;
|
|
595
|
+
/* size of value */
|
|
315
596
|
prop = null;
|
|
597
|
+
/* structure containing value */
|
|
316
598
|
constructor(actn, prop) {
|
|
317
599
|
this.actn = actn;
|
|
318
600
|
this.prop = prop;
|
|
@@ -359,6 +641,7 @@ var Rtf_IDEST;
|
|
|
359
641
|
Rtf_IDEST[Rtf_IDEST["COLOR"] = 1] = "COLOR";
|
|
360
642
|
Rtf_IDEST[Rtf_IDEST["SKIP"] = 2] = "SKIP";
|
|
361
643
|
})(Rtf_IDEST || (Rtf_IDEST = {}));
|
|
644
|
+
/* types of properties */
|
|
362
645
|
var Rtf_IPROP;
|
|
363
646
|
(function (Rtf_IPROP) {
|
|
364
647
|
Rtf_IPROP[Rtf_IPROP["BOLD"] = 0] = "BOLD";
|
|
@@ -395,6 +678,7 @@ var Rtf_IPROP;
|
|
|
395
678
|
Rtf_IPROP[Rtf_IPROP["XA_BULLET"] = 31] = "XA_BULLET";
|
|
396
679
|
Rtf_IPROP[Rtf_IPROP["MAX"] = 32] = "MAX";
|
|
397
680
|
})(Rtf_IPROP || (Rtf_IPROP = {}));
|
|
681
|
+
/* Rtf Destination State */
|
|
398
682
|
var Rtf_RDS;
|
|
399
683
|
(function (Rtf_RDS) {
|
|
400
684
|
Rtf_RDS[Rtf_RDS["NORM"] = 0] = "NORM";
|
|
@@ -414,6 +698,15 @@ var Rtf_ErrorRtf;
|
|
|
414
698
|
Rtf_ErrorRtf[Rtf_ErrorRtf["END_OF_FILE"] = 7] = "END_OF_FILE";
|
|
415
699
|
Rtf_ErrorRtf[Rtf_ErrorRtf["BUFFER_TOO_SMALL"] = 8] = "BUFFER_TOO_SMALL";
|
|
416
700
|
})(Rtf_ErrorRtf || (Rtf_ErrorRtf = {}));
|
|
701
|
+
// TODO :
|
|
702
|
+
// Rtf_RtfChar should actually be enum.
|
|
703
|
+
// But computed string values are not allowed to be defined in enum.
|
|
704
|
+
// So, we cannot have String.fromCharCode(XXX).
|
|
705
|
+
// We have 2 options:
|
|
706
|
+
// 1. Convert this enum into a class with all static readonly items.
|
|
707
|
+
// 2. Keep it as enum with numeric values (char codes).
|
|
708
|
+
// Going with #1 now, since @2 makes the code ugly.
|
|
709
|
+
// Will evalaute later if required.
|
|
417
710
|
class Rtf_RtfChar {
|
|
418
711
|
static CR = String.fromCharCode(0x0d);
|
|
419
712
|
static LF = String.fromCharCode(0x0A);
|
|
@@ -451,6 +744,7 @@ class Rtf {
|
|
|
451
744
|
_codePageTable = new Hashtable();
|
|
452
745
|
static RTF_PREFIX = "{\\rtf";
|
|
453
746
|
static CHAR_PAR = "par";
|
|
747
|
+
/* Property descriptions */
|
|
454
748
|
static rgprop = [
|
|
455
749
|
new Rtf_PROP(Rtf_ACTN.BYTE, Rtf_PROPTYPE.CHP), new Rtf_PROP(Rtf_ACTN.BYTE, Rtf_PROPTYPE.CHP),
|
|
456
750
|
new Rtf_PROP(Rtf_ACTN.BYTE, Rtf_PROPTYPE.CHP), new Rtf_PROP(Rtf_ACTN.BYTE, Rtf_PROPTYPE.CHP),
|
|
@@ -468,6 +762,7 @@ class Rtf {
|
|
|
468
762
|
new Rtf_PROP(Rtf_ACTN.BYTE, Rtf_PROPTYPE.PAP), new Rtf_PROP(Rtf_ACTN.SPEC, Rtf_PROPTYPE.PAP),
|
|
469
763
|
new Rtf_PROP(Rtf_ACTN.SPEC, Rtf_PROPTYPE.CHP), new Rtf_PROP(Rtf_ACTN.SPEC, Rtf_PROPTYPE.SEP)
|
|
470
764
|
];
|
|
765
|
+
/* Keyword descriptions */
|
|
471
766
|
static rgsymRtf = [
|
|
472
767
|
new Rtf_SYMBOL("b", Rtf_KWD.PROP, Rtf_IPROP.BOLD), new Rtf_SYMBOL("ul", Rtf_KWD.PROP, Rtf_IPROP.UNDERLINE),
|
|
473
768
|
new Rtf_SYMBOL("i", Rtf_KWD.PROP, Rtf_IPROP.ITALIC), new Rtf_SYMBOL("li", Rtf_KWD.PROP, Rtf_IPROP.LEFT_IND),
|
|
@@ -514,6 +809,8 @@ class Rtf {
|
|
|
514
809
|
new Rtf_SYMBOL("title", Rtf_KWD.DEST, Rtf_IDEST.SKIP), new Rtf_SYMBOL("txe", Rtf_KWD.DEST, Rtf_IDEST.SKIP),
|
|
515
810
|
new Rtf_SYMBOL("xe", Rtf_KWD.DEST, Rtf_IDEST.SKIP)
|
|
516
811
|
];
|
|
812
|
+
/// <summary> Constructor
|
|
813
|
+
/// </summary>
|
|
517
814
|
constructor() {
|
|
518
815
|
this._stack = new Stack();
|
|
519
816
|
this._group = 0;
|
|
@@ -529,6 +826,13 @@ class Rtf {
|
|
|
529
826
|
this.setCodePageTable();
|
|
530
827
|
}
|
|
531
828
|
}
|
|
829
|
+
/// <summary> Checks if the blob has a Rtf data or not
|
|
830
|
+
///
|
|
831
|
+
/// </summary>
|
|
832
|
+
/// <param name="str">
|
|
833
|
+
/// </param>
|
|
834
|
+
/// <returns>
|
|
835
|
+
/// </returns>
|
|
532
836
|
static isRtf(str) {
|
|
533
837
|
let isRtf = false;
|
|
534
838
|
if (str !== null && str.startsWith(this.RTF_PREFIX)) {
|
|
@@ -536,6 +840,17 @@ class Rtf {
|
|
|
536
840
|
}
|
|
537
841
|
return isRtf;
|
|
538
842
|
}
|
|
843
|
+
/// <summary> Converts Rtf Text to Plain Text
|
|
844
|
+
/// Step 1: Isolate RTF keywords and send them to ParseKeyword; Push and pop state at the start and end of
|
|
845
|
+
/// RTF groups Send text to ParseChar for further processing.
|
|
846
|
+
///
|
|
847
|
+
/// </summary>
|
|
848
|
+
/// <param name="rtfTxt">
|
|
849
|
+
/// </param>
|
|
850
|
+
/// <param name="outputTxt">
|
|
851
|
+
/// </param>
|
|
852
|
+
/// <returns>
|
|
853
|
+
/// </returns>
|
|
539
854
|
toTxt(rtfTxt, outputTxt) {
|
|
540
855
|
let cNibble = 2;
|
|
541
856
|
let b = 0;
|
|
@@ -561,6 +876,7 @@ class Rtf {
|
|
|
561
876
|
this._index++;
|
|
562
877
|
if (this._group < 0)
|
|
563
878
|
return Rtf_ErrorRtf.STACK_UNDERFLOW;
|
|
879
|
+
/* if we're parsing binary data, handle it directly */
|
|
564
880
|
if (this._internalState === Rtf_RIS.BIN) {
|
|
565
881
|
if ((ec = this.ParseChar(blobChar, outputTxt)) !== Rtf_ErrorRtf.OK)
|
|
566
882
|
return ec;
|
|
@@ -583,16 +899,22 @@ class Rtf {
|
|
|
583
899
|
return ec;
|
|
584
900
|
break;
|
|
585
901
|
case Rtf_RtfChar.LF:
|
|
586
|
-
case Rtf_RtfChar.CR:
|
|
902
|
+
case Rtf_RtfChar.CR: /* cr and lf are noise characters... */
|
|
587
903
|
if (this._processCrlfSpecial) {
|
|
904
|
+
/* Once we reach the 0x0a while ProcessCRLFSpecial_, reset the ProcessCRLFSpecial_ */
|
|
588
905
|
if (blobChar === Rtf_RtfChar.LF) {
|
|
589
906
|
this._processCrlfSpecial = false;
|
|
590
907
|
}
|
|
591
908
|
}
|
|
592
909
|
else {
|
|
910
|
+
/*---------------------------------------------------------------*/
|
|
911
|
+
/* skip new lines coming only from the RTF header 1/1/98 - #2390 */
|
|
912
|
+
/*---------------------------------------------------------------*/
|
|
913
|
+
/* Skip the LF (0x0a) if we are not in the ProcessCRLFSpecial_ */
|
|
593
914
|
if (blobChar === Rtf_RtfChar.LF || (blobChar === Rtf_RtfChar.CR && skipNewline && !this._outputOnce))
|
|
594
915
|
break;
|
|
595
916
|
}
|
|
917
|
+
/* falls through */
|
|
596
918
|
default:
|
|
597
919
|
if (blobChar !== Rtf_RtfChar.CR)
|
|
598
920
|
skipNewline = false;
|
|
@@ -606,6 +928,7 @@ class Rtf {
|
|
|
606
928
|
this._internalState = Rtf_RIS.NORM;
|
|
607
929
|
}
|
|
608
930
|
else {
|
|
931
|
+
/* parsing hex data */
|
|
609
932
|
if (this._internalState !== Rtf_RIS.HEX)
|
|
610
933
|
return Rtf_ErrorRtf.ASSERTION;
|
|
611
934
|
b = b << 4;
|
|
@@ -627,18 +950,22 @@ class Rtf {
|
|
|
627
950
|
if (cNibble === 0) {
|
|
628
951
|
if (UtilStrByteMode.isLocaleDefLangDBCS()) {
|
|
629
952
|
charset = this.getCharset(this._fontNum);
|
|
953
|
+
// leading byte of a double-byte character
|
|
630
954
|
if (!skipParseChar && Rtf.is1stByte(b, charset)) {
|
|
631
955
|
dbcsBytes[0] = b;
|
|
632
956
|
dbcsBytes[1] = 0;
|
|
633
957
|
skipParseChar = true;
|
|
634
958
|
}
|
|
635
959
|
else {
|
|
960
|
+
// trailing byte of a double-byte character
|
|
636
961
|
if (skipParseChar && Rtf.is2ndByte(b, charset))
|
|
637
962
|
dbcsBytes[1] = b;
|
|
963
|
+
// single-byte character
|
|
638
964
|
else {
|
|
639
965
|
dbcsBytes[0] = b;
|
|
640
966
|
dbcsBytes[1] = 0;
|
|
641
967
|
}
|
|
968
|
+
// convert DBCS to Unicode
|
|
642
969
|
codePage = this.getCodePage(charset);
|
|
643
970
|
let workStr = Encoding.GetEncoding(codePage).GetString(dbcsBytes, 0, 2);
|
|
644
971
|
b = workStr.charCodeAt(0);
|
|
@@ -654,19 +981,36 @@ class Rtf {
|
|
|
654
981
|
this._internalState = Rtf_RIS.NORM;
|
|
655
982
|
}
|
|
656
983
|
}
|
|
984
|
+
/* end else (ris != risNorm) */
|
|
657
985
|
break;
|
|
658
986
|
}
|
|
987
|
+
/* switch */
|
|
659
988
|
}
|
|
989
|
+
/* else (ris != risBin) */
|
|
660
990
|
}
|
|
991
|
+
/* while */
|
|
661
992
|
if (this._group < 0)
|
|
662
993
|
return Rtf_ErrorRtf.STACK_UNDERFLOW;
|
|
663
994
|
if (this._group > 0)
|
|
664
995
|
return Rtf_ErrorRtf.UNMATCHED_BRACE;
|
|
996
|
+
/*-------------------------------------------------------------------*/
|
|
997
|
+
/* Eliminate suffix of carrige return + line feed */
|
|
998
|
+
/* (Check last characters - just in case format is not the expected) */
|
|
999
|
+
/*-------------------------------------------------------------------*/
|
|
665
1000
|
currPos = outputTxt.Length;
|
|
666
1001
|
if (currPos >= 3 && (outputTxt.get_Item(currPos - 3) === Rtf_RtfChar.CR && outputTxt.get_Item(currPos - 2) === Rtf_RtfChar.LF && outputTxt.get_Item(currPos - 1) === Rtf_RtfChar.CR || outputTxt.get_Item(currPos - 3) === Rtf_RtfChar.LF && outputTxt.get_Item(currPos - 2) === Rtf_RtfChar.CR && outputTxt.get_Item(currPos - 1) === Rtf_RtfChar.CR))
|
|
667
1002
|
outputTxt.Remove(currPos - 3, 3);
|
|
668
1003
|
return Rtf_ErrorRtf.OK;
|
|
669
1004
|
}
|
|
1005
|
+
/// <summary> Route the character to the appropriate destination stream.
|
|
1006
|
+
///
|
|
1007
|
+
/// </summary>
|
|
1008
|
+
/// <param name="ch">
|
|
1009
|
+
/// </param>
|
|
1010
|
+
/// <param name="outputTxt">
|
|
1011
|
+
/// </param>
|
|
1012
|
+
/// <returns>
|
|
1013
|
+
/// </returns>
|
|
670
1014
|
ParseChar(ch, outputTxt) {
|
|
671
1015
|
let ret = Rtf_ErrorRtf.OK;
|
|
672
1016
|
if (this._internalState === Rtf_RIS.BIN && --this._cbBin <= 0) {
|
|
@@ -674,14 +1018,28 @@ class Rtf {
|
|
|
674
1018
|
}
|
|
675
1019
|
if (this._destState === Rtf_RDS.SKIP) {
|
|
676
1020
|
}
|
|
1021
|
+
/* Toss this character. */
|
|
677
1022
|
else if (this._destState === Rtf_RDS.NORM) {
|
|
1023
|
+
/* Output a character. Properties are valid at this point. */
|
|
678
1024
|
ret = this.PrintChar(ch, outputTxt);
|
|
679
1025
|
}
|
|
680
1026
|
else {
|
|
1027
|
+
/* handle other destinations.... */
|
|
681
1028
|
}
|
|
682
1029
|
return ret;
|
|
683
1030
|
}
|
|
1031
|
+
/// <summary> Send a character to the output file.
|
|
1032
|
+
///
|
|
1033
|
+
/// </summary>
|
|
1034
|
+
/// <param name="ch">
|
|
1035
|
+
/// </param>
|
|
1036
|
+
/// <param name="outputTxt">
|
|
1037
|
+
/// </param>
|
|
1038
|
+
/// <returns>
|
|
1039
|
+
/// </returns>
|
|
684
1040
|
PrintChar(ch, outputTxt) {
|
|
1041
|
+
/* Allow carrige return + line feed in text, but remove bullet sign */
|
|
1042
|
+
/*------------------------------------------------------------------*/
|
|
685
1043
|
if ((ch >= ' ' || ch === Rtf_RtfChar.CR || ch === Rtf_RtfChar.LF) && ch !== String.fromCharCode(183)) {
|
|
686
1044
|
outputTxt.Append(ch);
|
|
687
1045
|
}
|
|
@@ -690,6 +1048,11 @@ class Rtf {
|
|
|
690
1048
|
}
|
|
691
1049
|
return Rtf_ErrorRtf.OK;
|
|
692
1050
|
}
|
|
1051
|
+
/// <summary> Save relevant info on a linked list of SAVE structures.
|
|
1052
|
+
///
|
|
1053
|
+
/// </summary>
|
|
1054
|
+
/// <returns>
|
|
1055
|
+
/// </returns>
|
|
693
1056
|
PushState() {
|
|
694
1057
|
let stackSave = new Rtf_StackSave();
|
|
695
1058
|
if (stackSave === null) {
|
|
@@ -702,6 +1065,11 @@ class Rtf {
|
|
|
702
1065
|
this._group++;
|
|
703
1066
|
return Rtf_ErrorRtf.OK;
|
|
704
1067
|
}
|
|
1068
|
+
/// <summary> Always restore relevant info from the top of the SAVE list.
|
|
1069
|
+
///
|
|
1070
|
+
/// </summary>
|
|
1071
|
+
/// <returns>
|
|
1072
|
+
/// </returns>
|
|
705
1073
|
PopState() {
|
|
706
1074
|
let savedPop = this._stack.pop();
|
|
707
1075
|
if (savedPop === null) {
|
|
@@ -712,6 +1080,15 @@ class Rtf {
|
|
|
712
1080
|
this._group--;
|
|
713
1081
|
return Rtf_ErrorRtf.OK;
|
|
714
1082
|
}
|
|
1083
|
+
/// <summary> Step 2: get a control word (and its associated value) and call TranslateKeyword to dispatch the control.
|
|
1084
|
+
///
|
|
1085
|
+
/// </summary>
|
|
1086
|
+
/// <param name="rtfTxt">
|
|
1087
|
+
/// </param>
|
|
1088
|
+
/// <param name="outputTxt">
|
|
1089
|
+
/// </param>
|
|
1090
|
+
/// <returns>
|
|
1091
|
+
/// </returns>
|
|
715
1092
|
ParseKeyword(rtfTxt, outputTxt) {
|
|
716
1093
|
let ch;
|
|
717
1094
|
let fNeg = false;
|
|
@@ -720,6 +1097,7 @@ class Rtf {
|
|
|
720
1097
|
if ((ch = rtfTxt[this._index++]) === String.fromCharCode(0)) {
|
|
721
1098
|
return Rtf_ErrorRtf.END_OF_FILE;
|
|
722
1099
|
}
|
|
1100
|
+
/* a control symbol; no delimiter. */
|
|
723
1101
|
if (!NChar.IsLetter(ch)) {
|
|
724
1102
|
szKeyword = szKeyword + ch;
|
|
725
1103
|
return this.TranslateKeyword(szKeyword, outputTxt);
|
|
@@ -741,6 +1119,13 @@ class Rtf {
|
|
|
741
1119
|
if (ch !== ' ')
|
|
742
1120
|
this._index--;
|
|
743
1121
|
if (szKeyword === Rtf.CHAR_PAR) {
|
|
1122
|
+
/* if we get a RTF sequence of \par[0xd][0xa], ie a \par kwd followed */
|
|
1123
|
+
/* immidiately by the CR and LF, then ignore the \par kwd. otherwise */
|
|
1124
|
+
/* we will translate the \par - which translates to a LF (0xa) and also */
|
|
1125
|
+
/* the following 0x0d is translated to 0x0a, thus resulting in TWO LF's */
|
|
1126
|
+
/* being inserted instead of just one LF. So by skipping [\par] and */
|
|
1127
|
+
/* translating only the [0xd 0xa] will result in only one LF appearing */
|
|
1128
|
+
/* - which is the desired behaviour */
|
|
744
1129
|
if (rtfTxt[this._index] === Rtf_RtfChar.CR && rtfTxt[this._index + 1] === Rtf_RtfChar.LF)
|
|
745
1130
|
this._processCrlfSpecial = true;
|
|
746
1131
|
}
|
|
@@ -751,22 +1136,37 @@ class Rtf {
|
|
|
751
1136
|
return this.TranslateKeyword(szKeyword, outputTxt);
|
|
752
1137
|
}
|
|
753
1138
|
}
|
|
1139
|
+
/// <summary> Step 3. Search rgsymRtf for szKeyword and evaluate it appropriately.
|
|
1140
|
+
///
|
|
1141
|
+
/// </summary>
|
|
1142
|
+
/// <param name="szKeyword">
|
|
1143
|
+
/// </param>
|
|
1144
|
+
/// <param name="outputTxt">
|
|
1145
|
+
/// </param>
|
|
1146
|
+
/// <returns>
|
|
1147
|
+
/// </returns>
|
|
754
1148
|
TranslateKeyword(szKeyword, outputTxt) {
|
|
755
1149
|
let result = Rtf_ErrorRtf.OK;
|
|
756
1150
|
let isym;
|
|
1151
|
+
/* search for szKeyword in rgsymRtf */
|
|
757
1152
|
for (isym = 0; isym < Rtf.rgsymRtf.length; isym++) {
|
|
758
1153
|
if (szKeyword === Rtf.rgsymRtf[isym].szKeyword) {
|
|
759
1154
|
break;
|
|
760
1155
|
}
|
|
761
1156
|
}
|
|
1157
|
+
/* control word not found */
|
|
762
1158
|
if (isym === Rtf.rgsymRtf.length) {
|
|
763
1159
|
if (this._skipDestIfUnk) {
|
|
1160
|
+
/* if this is a new destination */
|
|
764
1161
|
this._destState = Rtf_RDS.SKIP;
|
|
1162
|
+
/* skip the destination */
|
|
765
1163
|
}
|
|
1164
|
+
/* else just discard it */
|
|
766
1165
|
this._skipDestIfUnk = false;
|
|
767
1166
|
}
|
|
768
1167
|
else {
|
|
769
1168
|
result = Rtf_ErrorRtf.BAD_TABLE;
|
|
1169
|
+
/* found it! use kwd and idxInRgprop to determine what to do with it. */
|
|
770
1170
|
this._skipDestIfUnk = false;
|
|
771
1171
|
if (Rtf.rgsymRtf[isym].kwd === Rtf_KWD.PROP) {
|
|
772
1172
|
result = this.validateProp(Rtf.rgsymRtf[isym].idxInRgprop);
|
|
@@ -783,11 +1183,21 @@ class Rtf {
|
|
|
783
1183
|
}
|
|
784
1184
|
return result;
|
|
785
1185
|
}
|
|
1186
|
+
/// <summary> Validate the property identified by _iprop_ to the value _val_.
|
|
1187
|
+
/// previously called Applypropchange
|
|
1188
|
+
/// </summary>
|
|
1189
|
+
/// <param name="iprop">
|
|
1190
|
+
/// </param>
|
|
1191
|
+
/// <returns>
|
|
1192
|
+
/// </returns>
|
|
786
1193
|
validateProp(iprop) {
|
|
787
1194
|
let ret = Rtf_ErrorRtf.OK;
|
|
788
1195
|
if (this._destState === Rtf_RDS.SKIP) {
|
|
1196
|
+
/* If we're skipping text, */
|
|
789
1197
|
return ret;
|
|
1198
|
+
/* don't do anything. */
|
|
790
1199
|
}
|
|
1200
|
+
/* validate prop */
|
|
791
1201
|
if (Rtf.rgprop[iprop].prop !== Rtf_PROPTYPE.DOP && Rtf.rgprop[iprop].prop !== Rtf_PROPTYPE.SEP &&
|
|
792
1202
|
Rtf.rgprop[iprop].prop !== Rtf_PROPTYPE.PAP && Rtf.rgprop[iprop].prop !== Rtf_PROPTYPE.CHP &&
|
|
793
1203
|
Rtf.rgprop[iprop].actn !== Rtf_ACTN.SPEC) {
|
|
@@ -798,18 +1208,35 @@ class Rtf {
|
|
|
798
1208
|
}
|
|
799
1209
|
return ret;
|
|
800
1210
|
}
|
|
1211
|
+
/// <summary> Change to the destination state.
|
|
1212
|
+
/// previously called ChangeDest
|
|
1213
|
+
/// </summary>
|
|
1214
|
+
/// <returns>
|
|
1215
|
+
/// </returns>
|
|
801
1216
|
changeDestState() {
|
|
802
1217
|
if (this._destState === Rtf_RDS.SKIP) {
|
|
1218
|
+
/* if we're skipping text, */
|
|
803
1219
|
return Rtf_ErrorRtf.OK;
|
|
1220
|
+
/* don't do anything */
|
|
804
1221
|
}
|
|
805
1222
|
this._destState = Rtf_RDS.SKIP;
|
|
1223
|
+
/* when in doubt, skip it... */
|
|
806
1224
|
return Rtf_ErrorRtf.OK;
|
|
807
1225
|
}
|
|
1226
|
+
/// <summary> Evaluate an RTF control that needs special processing.
|
|
1227
|
+
///
|
|
1228
|
+
/// </summary>
|
|
1229
|
+
/// <param name="ipfn">
|
|
1230
|
+
/// </param>
|
|
1231
|
+
/// <returns>
|
|
1232
|
+
/// </returns>
|
|
808
1233
|
ParseSpecialKeyword(ipfn) {
|
|
809
1234
|
let ret = Rtf_ErrorRtf.OK;
|
|
810
1235
|
if (!UtilStrByteMode.isLocaleDefLangDBCS()) {
|
|
811
1236
|
if (this._destState === Rtf_RDS.SKIP && ipfn !== Rtf_IPFN.BIN) {
|
|
1237
|
+
/* if we're skipping, and it's not */
|
|
812
1238
|
return ret;
|
|
1239
|
+
/* the \bin keyword, ignore it. */
|
|
813
1240
|
}
|
|
814
1241
|
if (ipfn === Rtf_IPFN.FONT || ipfn === Rtf_IPFN.CHARSET || ipfn === Rtf_IPFN.UNICODE) {
|
|
815
1242
|
return ret;
|
|
@@ -863,6 +1290,15 @@ class Rtf {
|
|
|
863
1290
|
}
|
|
864
1291
|
return ret;
|
|
865
1292
|
}
|
|
1293
|
+
/// <summary> Checks if the byte is within the trailing byte range.
|
|
1294
|
+
///
|
|
1295
|
+
/// </summary>
|
|
1296
|
+
/// <param name="dbcsBytes">
|
|
1297
|
+
/// </param>
|
|
1298
|
+
/// <param name="charset">
|
|
1299
|
+
/// </param>
|
|
1300
|
+
/// <returns>
|
|
1301
|
+
/// </returns>
|
|
866
1302
|
static is2ndByte(dbcsBytes, charset) {
|
|
867
1303
|
let ret = false;
|
|
868
1304
|
if (dbcsBytes > 255)
|
|
@@ -881,21 +1317,35 @@ class Rtf {
|
|
|
881
1317
|
}
|
|
882
1318
|
return ret;
|
|
883
1319
|
}
|
|
1320
|
+
/// <summary> Create a hashtable of codepage associated with charset.
|
|
1321
|
+
///
|
|
1322
|
+
/// </summary>
|
|
1323
|
+
/// <param>
|
|
1324
|
+
/// <returns>
|
|
1325
|
+
/// </returns>
|
|
884
1326
|
setCodePageTable() {
|
|
885
|
-
|
|
886
|
-
this._codePageTable.set_Item(
|
|
887
|
-
this._codePageTable.set_Item(
|
|
888
|
-
this._codePageTable.set_Item(
|
|
889
|
-
this._codePageTable.set_Item(
|
|
890
|
-
this._codePageTable.set_Item(
|
|
891
|
-
this._codePageTable.set_Item(
|
|
892
|
-
this._codePageTable.set_Item(
|
|
893
|
-
this._codePageTable.set_Item(
|
|
894
|
-
this._codePageTable.set_Item(
|
|
895
|
-
this._codePageTable.set_Item(
|
|
896
|
-
this._codePageTable.set_Item(
|
|
897
|
-
this._codePageTable.set_Item(
|
|
898
|
-
|
|
1327
|
+
// add elements with key (charset) and value (codepage) into the table.
|
|
1328
|
+
this._codePageTable.set_Item(0, 1252); // ANSI_CHARSET
|
|
1329
|
+
this._codePageTable.set_Item(128, 932); // SHIFTJIS_CHARSET
|
|
1330
|
+
this._codePageTable.set_Item(129, 949); // HANGUL_CHARSET
|
|
1331
|
+
this._codePageTable.set_Item(134, 936); // GB2312_CHARSET
|
|
1332
|
+
this._codePageTable.set_Item(136, 950); // CHINESEBIG5_CHARSET
|
|
1333
|
+
this._codePageTable.set_Item(161, 1253); // GREEK_CHARSET
|
|
1334
|
+
this._codePageTable.set_Item(162, 1254); // TURKISH_CHARSET
|
|
1335
|
+
this._codePageTable.set_Item(177, 1255); // HEBREW_CHARSET
|
|
1336
|
+
this._codePageTable.set_Item(178, 1256); // ARABIC _CHARSET
|
|
1337
|
+
this._codePageTable.set_Item(186, 1257); // BALTIC_CHARSET
|
|
1338
|
+
this._codePageTable.set_Item(204, 1251); // RUSSIAN_CHARSET
|
|
1339
|
+
this._codePageTable.set_Item(222, 874); // THAI_CHARSET
|
|
1340
|
+
this._codePageTable.set_Item(238, 1250); // EASTEUROPE_CHARSET
|
|
1341
|
+
}
|
|
1342
|
+
/// <summary> Get codepage corresponding to the specified charset.
|
|
1343
|
+
///
|
|
1344
|
+
/// </summary>
|
|
1345
|
+
/// <param name="charset">
|
|
1346
|
+
/// </param>
|
|
1347
|
+
/// <returns>
|
|
1348
|
+
/// </returns>
|
|
899
1349
|
getCodePage(charset) {
|
|
900
1350
|
let codePage = 0;
|
|
901
1351
|
if (this._codePageTable.ContainsKey(charset)) {
|
|
@@ -903,6 +1353,13 @@ class Rtf {
|
|
|
903
1353
|
}
|
|
904
1354
|
return codePage;
|
|
905
1355
|
}
|
|
1356
|
+
/// <summary> Get charset corresponding to the specified font index.
|
|
1357
|
+
///
|
|
1358
|
+
/// </summary>
|
|
1359
|
+
/// <param name="font">
|
|
1360
|
+
/// </param>
|
|
1361
|
+
/// <returns>
|
|
1362
|
+
/// </returns>
|
|
906
1363
|
getCharset(font) {
|
|
907
1364
|
let charset = 0;
|
|
908
1365
|
if (this._charsetTable.ContainsKey(font)) {
|
|
@@ -923,6 +1380,7 @@ const HTML_2_SEQ = 4;
|
|
|
923
1380
|
const SEQ_2_STR = 5;
|
|
924
1381
|
class StrUtil {
|
|
925
1382
|
static _paddingSpaces = null;
|
|
1383
|
+
/// <summary> trim the end of the string</summary>
|
|
926
1384
|
static mem_trim(str, len) {
|
|
927
1385
|
let result;
|
|
928
1386
|
if (len > 0) {
|
|
@@ -957,6 +1415,15 @@ class StrUtil {
|
|
|
957
1415
|
}
|
|
958
1416
|
StrUtil.memcpy_1(dest, destCount, src, scrCountOrSrcCount, count);
|
|
959
1417
|
}
|
|
1418
|
+
/// <summary>
|
|
1419
|
+
/// copy part of string into another string, like memcpy of C, but 4 string only
|
|
1420
|
+
/// </summary>
|
|
1421
|
+
/// <param name = "dest">string</param>
|
|
1422
|
+
/// <param name = "destCount">of counter start from in destignation string</param>
|
|
1423
|
+
/// <param name = "src">string</param>
|
|
1424
|
+
/// <param name = "scrCount">of counter start from in source string</param>
|
|
1425
|
+
/// <param name = "count"></param>
|
|
1426
|
+
/// <returns> new value of destignation string</returns>
|
|
960
1427
|
static memcpy_0(dest, destCount, src, scrCount, count) {
|
|
961
1428
|
let stringBuilder = new StringBuilder(dest.substr(0, destCount));
|
|
962
1429
|
if (scrCount + count < src.length) {
|
|
@@ -983,6 +1450,14 @@ class StrUtil {
|
|
|
983
1450
|
}
|
|
984
1451
|
StrUtil.memset_1(dest, destCount, inVal, counter);
|
|
985
1452
|
}
|
|
1453
|
+
/// <summary>
|
|
1454
|
+
/// insert to string chars n times
|
|
1455
|
+
/// </summary>
|
|
1456
|
+
/// <param name = "dest">string</param>
|
|
1457
|
+
/// <param name = "destCount">of counter start from in destignation string to start insertion of char from</param>
|
|
1458
|
+
/// <param name = "inVal">2 insert</param>
|
|
1459
|
+
/// <param name = "counter">- number of times to insert the char</param>
|
|
1460
|
+
/// <returns> new value of destignation string</returns>
|
|
986
1461
|
static memset_0(dest, destCount, inVal, counter) {
|
|
987
1462
|
let first = new StringBuilder(dest.substr(0, destCount));
|
|
988
1463
|
while (counter > 0) {
|
|
@@ -1011,14 +1486,29 @@ class StrUtil {
|
|
|
1011
1486
|
}
|
|
1012
1487
|
return result;
|
|
1013
1488
|
}
|
|
1489
|
+
/*******************************/
|
|
1490
|
+
/// <summary>
|
|
1491
|
+
/// Reverses string values.
|
|
1492
|
+
/// </summary>
|
|
1493
|
+
/// <param name="text">The StringBuilder object containing the string to be reversed.</param>
|
|
1494
|
+
/// <returns>The reversed string contained in a StringBuilder object.</returns>
|
|
1014
1495
|
static ReverseString(text) {
|
|
1496
|
+
// TODO: use string.Reverse()
|
|
1015
1497
|
let array = NString.ToCharArray(text.ToString());
|
|
1016
1498
|
array.reverse();
|
|
1017
1499
|
return new StringBuilder(NString.FromChars(array));
|
|
1018
1500
|
}
|
|
1501
|
+
/// <summary> remove spaces from the right side of string</summary>
|
|
1502
|
+
/// <param name="str">the string to trim
|
|
1503
|
+
/// </param>
|
|
1019
1504
|
static rtrim(str) {
|
|
1020
1505
|
return StrUtil.rtrimWithNull(str, false);
|
|
1021
1506
|
}
|
|
1507
|
+
/// <summary> remove spaces and/or Null chars from the right side of string</summary>
|
|
1508
|
+
/// <param name="str">the string to trim
|
|
1509
|
+
/// </param>
|
|
1510
|
+
/// <param name="trimNullChars">Whether to remove NULL characters or not
|
|
1511
|
+
/// </param>
|
|
1022
1512
|
static rtrimWithNull(str, trimNullChars) {
|
|
1023
1513
|
let result;
|
|
1024
1514
|
if (typeof str === "undefined" || str === null || str.length === 0) {
|
|
@@ -1027,7 +1517,7 @@ class StrUtil {
|
|
|
1027
1517
|
else {
|
|
1028
1518
|
let idx = str.length - 1;
|
|
1029
1519
|
if (trimNullChars) {
|
|
1030
|
-
while (idx >= 0 && (str[idx] === ' ' || str[idx] === String.fromCharCode(0))) {
|
|
1520
|
+
while (idx >= 0 && (str[idx] === ' ' || str[idx] === String.fromCharCode(0) /*''*/)) {
|
|
1031
1521
|
idx = idx - 1;
|
|
1032
1522
|
}
|
|
1033
1523
|
}
|
|
@@ -1046,6 +1536,9 @@ class StrUtil {
|
|
|
1046
1536
|
}
|
|
1047
1537
|
return result;
|
|
1048
1538
|
}
|
|
1539
|
+
/// <summary> remove spaces from the left side of string</summary>
|
|
1540
|
+
/// <param name="str">the string to trim
|
|
1541
|
+
/// </param>
|
|
1049
1542
|
static ltrim(str) {
|
|
1050
1543
|
let length = str.length;
|
|
1051
1544
|
let i = 0;
|
|
@@ -1054,7 +1547,7 @@ class StrUtil {
|
|
|
1054
1547
|
result = str;
|
|
1055
1548
|
}
|
|
1056
1549
|
else {
|
|
1057
|
-
while (i < length && str[i] === ' ') {
|
|
1550
|
+
while (i < length && str[i] === ' ' /*' '*/) {
|
|
1058
1551
|
i = i + 1;
|
|
1059
1552
|
}
|
|
1060
1553
|
if (i > 0) {
|
|
@@ -1064,6 +1557,16 @@ class StrUtil {
|
|
|
1064
1557
|
}
|
|
1065
1558
|
return result;
|
|
1066
1559
|
}
|
|
1560
|
+
/// <summary>This function for Deleting String from end & start of input
|
|
1561
|
+
/// String
|
|
1562
|
+
/// </summary>
|
|
1563
|
+
/// <param name="str">String , which can include strToDelete spaces on input
|
|
1564
|
+
/// </param>
|
|
1565
|
+
/// <param name="strToDelete">need delete this String from start/end of str.
|
|
1566
|
+
/// </param>
|
|
1567
|
+
/// <returns> String without strToDelete on end & start,
|
|
1568
|
+
/// or 'null' if Sting hasn't not characters inside
|
|
1569
|
+
/// </returns>
|
|
1067
1570
|
static DeleteStringsFromEnds(str, strToDelete) {
|
|
1068
1571
|
if (str.startsWith(strToDelete)) {
|
|
1069
1572
|
str = str.substr(strToDelete.length);
|
|
@@ -1080,6 +1583,11 @@ class StrUtil {
|
|
|
1080
1583
|
}
|
|
1081
1584
|
return result;
|
|
1082
1585
|
}
|
|
1586
|
+
/// <summary> pad a string with trailing spaces up to the given length</summary>
|
|
1587
|
+
/// <param name="str">the string to pad
|
|
1588
|
+
/// </param>
|
|
1589
|
+
/// <param name="len">the expected length after padding
|
|
1590
|
+
/// </param>
|
|
1083
1591
|
static padStr(str, len) {
|
|
1084
1592
|
let padLen = len - str.length;
|
|
1085
1593
|
if (padLen > 0) {
|
|
@@ -1093,9 +1601,67 @@ class StrUtil {
|
|
|
1093
1601
|
}
|
|
1094
1602
|
return str;
|
|
1095
1603
|
}
|
|
1604
|
+
/// <summary> this method will serve as a string tokenizer instead of using the c# split method
|
|
1605
|
+
/// since there are diffrences btween java tokenizer and c# split
|
|
1606
|
+
/// the implimentation given by the conversion tool is not Sufficient
|
|
1607
|
+
/// </summary>
|
|
1608
|
+
/// <param name="source">- the source string to be converted
|
|
1609
|
+
/// </param>
|
|
1610
|
+
/// <param name="delim">- the string of delimiters used to split the string (each character in the String is a delimiter
|
|
1611
|
+
/// </param>
|
|
1612
|
+
/// <returns> array of token according which is the same as string tokenizer in java
|
|
1613
|
+
/// </returns>
|
|
1096
1614
|
static tokenize(source, delim) {
|
|
1615
|
+
// It is mentioned in the comment that we should not use String.Split()
|
|
1616
|
+
// because its behavior is different than Java's tokenizer.
|
|
1617
|
+
// So, we were suppose to use our own implementation (the commented code below).
|
|
1618
|
+
// But all these years, we were calling XmlParser.getToken() which was actually
|
|
1619
|
+
// using String.Split(). And we didn't face any problem.
|
|
1620
|
+
// So, it seems that we do not have problem in using String.Split().
|
|
1621
|
+
// But now, we can improve the performance here...
|
|
1622
|
+
// XmlParser.getTokens() was getting a String[] using String.Split().
|
|
1623
|
+
// It was then creating a List<String> from this String[] and was returning it to
|
|
1624
|
+
// tokenize().
|
|
1625
|
+
// tokenize() was again converting this List<String> back to String[].
|
|
1626
|
+
// So why not call String.Split() directly?
|
|
1097
1627
|
return source.split(delim);
|
|
1098
|
-
|
|
1628
|
+
/*
|
|
1629
|
+
String [] tokens = null;
|
|
1630
|
+
|
|
1631
|
+
char [] delimArry = delim.toCharArray();
|
|
1632
|
+
|
|
1633
|
+
//since java discards delimiters from the start and end of the string and c# does not
|
|
1634
|
+
//we need to remove them manually
|
|
1635
|
+
// source = source.TrimEnd(delimArry);
|
|
1636
|
+
// source = source.TrimStart(delimArry);
|
|
1637
|
+
source = source.trim();
|
|
1638
|
+
|
|
1639
|
+
//now that we have remove starting and ending delimiters we can split
|
|
1640
|
+
tokens = source.Split(delimArry);
|
|
1641
|
+
|
|
1642
|
+
/*
|
|
1643
|
+
* only one problem: if we have two Subsequent delimiters for example :
|
|
1644
|
+
* the delimiter is ';' and the string is: "first;;second;third"
|
|
1645
|
+
* then in java String tokenizer will give us only 3 tokens :first,second and third
|
|
1646
|
+
* while is c# split wethod will return 4 tokens: first,empty string,second and third
|
|
1647
|
+
* we need to deal with that
|
|
1648
|
+
*/
|
|
1649
|
+
/*
|
|
1650
|
+
List res = new List();
|
|
1651
|
+
for (int i = 0 ; i < tokens.length; i++)
|
|
1652
|
+
{
|
|
1653
|
+
if (tokens[i] != "" )
|
|
1654
|
+
res.addItem(tokens[i]);
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
return (String [])(res.getAllItems (String.class));*/
|
|
1658
|
+
}
|
|
1659
|
+
/// <summary>
|
|
1660
|
+
/// translate from string to hexa dump char by char
|
|
1661
|
+
/// </summary>
|
|
1662
|
+
/// <param name = "string">to translate it to the byte stream</param>
|
|
1663
|
+
/// <param name = "minLength">the minimal length of hexa digits for each char</param>
|
|
1664
|
+
/// <returns> the byte stream in form of string</returns>
|
|
1099
1665
|
static stringToHexaDump(str, minLength) {
|
|
1100
1666
|
let stringBuilder = new StringBuilder(str.length * minLength);
|
|
1101
1667
|
for (let indx = 0; indx < str.length; indx = indx + 1) {
|
|
@@ -1114,6 +1680,11 @@ class StrUtil {
|
|
|
1114
1680
|
}
|
|
1115
1681
|
return StrUtil.searchAndReplace_1(str, from, to);
|
|
1116
1682
|
}
|
|
1683
|
+
/// <summary> replace every appearance of 'from' in 'str' with 'to'</summary>
|
|
1684
|
+
/// <param name="str">the working base source string </param>
|
|
1685
|
+
/// <param name="from">the string to replace </param>
|
|
1686
|
+
/// <param name="to">the string use instead 'from' </param>
|
|
1687
|
+
/// <returns> modified String </returns>
|
|
1117
1688
|
static searchAndReplace_0(str, from, to) {
|
|
1118
1689
|
let lastSubStr = 0;
|
|
1119
1690
|
let startSubStr;
|
|
@@ -1134,6 +1705,11 @@ class StrUtil {
|
|
|
1134
1705
|
}
|
|
1135
1706
|
return result;
|
|
1136
1707
|
}
|
|
1708
|
+
/// <summary> replace every appearance of strings of 'from' in 'str' with the according string in 'to'</summary>
|
|
1709
|
+
/// <param name="str">the working base source string </param>
|
|
1710
|
+
/// <param name="from">the string to replace </param>
|
|
1711
|
+
/// <param name="to">the string use instead 'from' </param>
|
|
1712
|
+
/// <returns> modified String </returns>
|
|
1137
1713
|
static searchAndReplace_1(str, from, to) {
|
|
1138
1714
|
let lastSubStr = 0;
|
|
1139
1715
|
let sarIndex = 0;
|
|
@@ -1158,6 +1734,14 @@ class StrUtil {
|
|
|
1158
1734
|
result = tmpBuf.ToString();
|
|
1159
1735
|
return result;
|
|
1160
1736
|
}
|
|
1737
|
+
/// <summary> this functions is for use by the searchAndReplace() function -
|
|
1738
|
+
/// searches the offset of the strings from the array in the given string
|
|
1739
|
+
/// and returns the minimum offset found and sets the index of the found string
|
|
1740
|
+
/// to SARindex
|
|
1741
|
+
/// </summary>
|
|
1742
|
+
/// <param name="str">the string to search in </param>
|
|
1743
|
+
/// <param name="strings">an array of strings to search for </param>
|
|
1744
|
+
/// <param name="offset">where to start the search </param>
|
|
1161
1745
|
static indexOf(str, strings, offset, SARindex) {
|
|
1162
1746
|
let minOffset = -1;
|
|
1163
1747
|
for (let i = 0; i < strings.length; i = i + 1) {
|
|
@@ -1184,6 +1768,15 @@ class StrUtil {
|
|
|
1184
1768
|
}
|
|
1185
1769
|
return result;
|
|
1186
1770
|
}
|
|
1771
|
+
/// <summary> replace tokens in user string by vector values </summary>
|
|
1772
|
+
/// <param name="userString">- user buffer like "User %d, %d string"
|
|
1773
|
+
/// </param>
|
|
1774
|
+
/// <param name="token">- token used in user string - i.e. "%d"
|
|
1775
|
+
/// </param>
|
|
1776
|
+
/// <param name="occurrence">- number of token where replace will take part (1 for first occurrence)
|
|
1777
|
+
/// </param>
|
|
1778
|
+
/// <param name="value">- value to be inserted insted of token
|
|
1779
|
+
/// </param>
|
|
1187
1780
|
static replaceStringTokens(userString, token, occurrence, val) {
|
|
1188
1781
|
let tokenLen = token.length;
|
|
1189
1782
|
let currPosition = 0;
|
|
@@ -1206,6 +1799,12 @@ class StrUtil {
|
|
|
1206
1799
|
}
|
|
1207
1800
|
StrUtil.makePrintableTokens_1(source, type);
|
|
1208
1801
|
}
|
|
1802
|
+
/// <summary>
|
|
1803
|
+
/// converts special characters in a token to a printable format
|
|
1804
|
+
/// </summary>
|
|
1805
|
+
/// <param name = "source">a token </param>
|
|
1806
|
+
/// <param name = "type">type of conversion: STR_2_HTML, SEQ_2_HTML, HTML_2_SEQ, HTML_2_STR, SEQ_2_STR </param>
|
|
1807
|
+
/// <returns> token with converted special characters </returns>
|
|
1209
1808
|
static makePrintableTokens_0(source, type) {
|
|
1210
1809
|
let escStr = [
|
|
1211
1810
|
"\\", "-", ","
|
|
@@ -1239,6 +1838,11 @@ class StrUtil {
|
|
|
1239
1838
|
}
|
|
1240
1839
|
return result;
|
|
1241
1840
|
}
|
|
1841
|
+
/// <summary>
|
|
1842
|
+
/// converts special characters in a tokens collection to a printable format
|
|
1843
|
+
/// </summary>
|
|
1844
|
+
/// <param name = "source">vector of strings before tokenaizer </param>
|
|
1845
|
+
/// <param name = "type">type of conversion: STR_2_HTML, SEQ_2_HTML, HTML_2_SEQ, HTML_2_STR </param>
|
|
1242
1846
|
static makePrintableTokens_1(source, type) {
|
|
1243
1847
|
if (source !== null) {
|
|
1244
1848
|
let length = source.length;
|
|
@@ -1248,6 +1852,12 @@ class StrUtil {
|
|
|
1248
1852
|
}
|
|
1249
1853
|
}
|
|
1250
1854
|
}
|
|
1855
|
+
/// <summary>
|
|
1856
|
+
/// change non-printable characters like "new line" and "line feed" to their
|
|
1857
|
+
/// printable representation
|
|
1858
|
+
/// </summary>
|
|
1859
|
+
/// <param name = "source">is the string with non-printable characters </param>
|
|
1860
|
+
/// <returns> the new string where all the non-printable characters are converted </returns>
|
|
1251
1861
|
static makePrintable(source) {
|
|
1252
1862
|
let from = [
|
|
1253
1863
|
"\n", "\r", "'", "\\", "\"", "\0"
|
|
@@ -1257,6 +1867,12 @@ class StrUtil {
|
|
|
1257
1867
|
];
|
|
1258
1868
|
return StrUtil.searchAndReplace(source, from, to);
|
|
1259
1869
|
}
|
|
1870
|
+
/// <summary>
|
|
1871
|
+
/// change non-printable characters like "new line" and "line feed" to their
|
|
1872
|
+
/// printable representation (simplified version for range error message)
|
|
1873
|
+
/// </summary>
|
|
1874
|
+
/// <param name = "source">is the string with non-printable characters </param>
|
|
1875
|
+
/// <returns> the new string where all the non-printable characters are converted </returns>
|
|
1260
1876
|
static makePrintable2(source) {
|
|
1261
1877
|
let from = [
|
|
1262
1878
|
"\n", "\r", "\0"
|
|
@@ -1266,10 +1882,21 @@ class StrUtil {
|
|
|
1266
1882
|
];
|
|
1267
1883
|
return StrUtil.searchAndReplace(source, from, to);
|
|
1268
1884
|
}
|
|
1885
|
+
/// <summary>
|
|
1886
|
+
///
|
|
1887
|
+
/// </summary>
|
|
1888
|
+
/// <param name="s"></param>
|
|
1889
|
+
/// <param name="len"></param>
|
|
1890
|
+
/// <returns></returns>
|
|
1269
1891
|
static ZstringMake(s, len) {
|
|
1270
1892
|
len = StrUtil.mem_trim(s, len);
|
|
1271
1893
|
return s.substr(0, len);
|
|
1272
1894
|
}
|
|
1895
|
+
/// <summary>(public)
|
|
1896
|
+
/// returns plain text from rtf text
|
|
1897
|
+
/// </summary>
|
|
1898
|
+
/// <param name="rtfText">refer to the summary</param>
|
|
1899
|
+
/// <returns>refer to the summary</returns>
|
|
1273
1900
|
static GetPlainTextfromRtf(rtfText) {
|
|
1274
1901
|
if (Rtf.isRtf(rtfText)) {
|
|
1275
1902
|
let rtf = new Rtf();
|
|
@@ -1279,6 +1906,12 @@ class StrUtil {
|
|
|
1279
1906
|
}
|
|
1280
1907
|
return rtfText;
|
|
1281
1908
|
}
|
|
1909
|
+
/// <summary>
|
|
1910
|
+
/// Returns true if the string arrays str1 & str2 are equal
|
|
1911
|
+
/// </summary>
|
|
1912
|
+
/// <param name="str1"></param>
|
|
1913
|
+
/// <param name="str2"></param>
|
|
1914
|
+
/// <returns></returns>
|
|
1282
1915
|
static StringsArraysEqual(str1, str2) {
|
|
1283
1916
|
let result;
|
|
1284
1917
|
if (str1 === null && str2 === null) {
|
|
@@ -1305,6 +1938,12 @@ class StrUtil {
|
|
|
1305
1938
|
}
|
|
1306
1939
|
return result;
|
|
1307
1940
|
}
|
|
1941
|
+
/// <summary>
|
|
1942
|
+
/// The code is copied from tsk_open_bnd_wild and SearchAndReplaceWildChars
|
|
1943
|
+
/// The refactoring is not performed for backwards compatibility
|
|
1944
|
+
/// The code replaces special charachters :* ? with recieved filler
|
|
1945
|
+
/// </summary>
|
|
1946
|
+
/// <returns></returns>
|
|
1308
1947
|
static SearchAndReplaceWildChars(buf, len, filler) {
|
|
1309
1948
|
buf = NString.PadRight(buf, len);
|
|
1310
1949
|
let escChar = false;
|
|
@@ -1314,6 +1953,7 @@ class StrUtil {
|
|
|
1314
1953
|
case ('\\'):
|
|
1315
1954
|
{
|
|
1316
1955
|
let isNextCharWild = true;
|
|
1956
|
+
//If next char is not wild , then copy '\', if this is first char.
|
|
1317
1957
|
if ((i + 1 < len) && (buf[i + 1] != '*' && buf[i + 1] != '\\'))
|
|
1318
1958
|
isNextCharWild = false;
|
|
1319
1959
|
if (escChar || !isNextCharWild)
|
|
@@ -1342,12 +1982,22 @@ class StrUtil {
|
|
|
1342
1982
|
let text = tmpBuf.ToString();
|
|
1343
1983
|
return NString.TrimEnd(NString.TrimEnd(text, ['\0']));
|
|
1344
1984
|
}
|
|
1985
|
+
/// <summary>
|
|
1986
|
+
/// Remove the task path delimiter from the error string.
|
|
1987
|
+
/// </summary>
|
|
1988
|
+
/// <param name = "source">string with delimiter </param>
|
|
1989
|
+
/// <returns> string for console error </returns>
|
|
1345
1990
|
static getConsoleErorString(source) {
|
|
1346
1991
|
let consoleErorString = "";
|
|
1347
1992
|
if (!isNullOrUndefined(source))
|
|
1348
1993
|
consoleErorString = this.searchAndReplace(source, TASK_PATH_DELIMITER, "");
|
|
1349
1994
|
return consoleErorString;
|
|
1350
1995
|
}
|
|
1996
|
+
/// <summary>
|
|
1997
|
+
/// Remove the task path from the error string.
|
|
1998
|
+
/// </summary>
|
|
1999
|
+
/// <param name = "source">string with delimiter </param>
|
|
2000
|
+
/// <returns> string for console error </returns>
|
|
1351
2001
|
static getMsgBoxErorString(source) {
|
|
1352
2002
|
let tokens;
|
|
1353
2003
|
let msgBoxErorString = new StringBuilder("");
|
|
@@ -1362,11 +2012,32 @@ class StrUtil {
|
|
|
1362
2012
|
}
|
|
1363
2013
|
}
|
|
1364
2014
|
|
|
2015
|
+
// In order to convert some functionality to Visual C#, the Java Language Conversion Assistant
|
|
2016
|
+
// creates "support classes" that duplicate the original functionality.
|
|
2017
|
+
//
|
|
2018
|
+
// Support classes replicate the functionality of the original code, but in some cases they are
|
|
2019
|
+
// substantially different architecturally. Although every effort is made to preserve the
|
|
2020
|
+
// original architecture of the application in the converted project, the user should be aware that
|
|
2021
|
+
// the primary goal of these support classes is to replicate functionality, and that at times
|
|
2022
|
+
// the architecture of the resulting solution may differ somewhat.
|
|
2023
|
+
/// <summary>
|
|
2024
|
+
/// Contains conversion support elements such as classes, interfaces and static methods.
|
|
2025
|
+
/// </summary>
|
|
1365
2026
|
class Misc {
|
|
2027
|
+
/// <summary>
|
|
2028
|
+
/// Writes the exception stack trace to the received stream
|
|
2029
|
+
/// </summary>
|
|
2030
|
+
/// <param name="throwable">Exception to obtain information from</param>
|
|
2031
|
+
/// <param name="stream">Output sream used to write to</param>
|
|
1366
2032
|
static WriteStackTrace(throwable) {
|
|
1367
2033
|
console.log(throwable.Message);
|
|
1368
2034
|
console.log(throwable.StackTrace);
|
|
1369
2035
|
}
|
|
2036
|
+
/// <summary>
|
|
2037
|
+
/// Receives a byte array and returns it transformed in an byte array
|
|
2038
|
+
/// </summary>
|
|
2039
|
+
/// <param name="byteArray">Byte array to process</param>
|
|
2040
|
+
/// <returns>The transformed array</returns>
|
|
1370
2041
|
static ToSByteArray(byteArray) {
|
|
1371
2042
|
let sbyteArray = null;
|
|
1372
2043
|
if (byteArray !== null) {
|
|
@@ -1377,6 +2048,11 @@ class Misc {
|
|
|
1377
2048
|
}
|
|
1378
2049
|
return sbyteArray;
|
|
1379
2050
|
}
|
|
2051
|
+
/// <summary>
|
|
2052
|
+
/// Receives sbyte array and returns it transformed in a byte array
|
|
2053
|
+
/// </summary>
|
|
2054
|
+
/// <param name="sbyteArray">sbyte array to process</param>
|
|
2055
|
+
/// <returns>The transformed array</returns>
|
|
1380
2056
|
static ToByteArray(sbyteArray) {
|
|
1381
2057
|
let byteArray = null;
|
|
1382
2058
|
if (sbyteArray !== null) {
|
|
@@ -1387,6 +2063,11 @@ class Misc {
|
|
|
1387
2063
|
}
|
|
1388
2064
|
return byteArray;
|
|
1389
2065
|
}
|
|
2066
|
+
/// <summary> Compares number of bytes in two byte arrays</summary>
|
|
2067
|
+
/// <param name="source"></param>
|
|
2068
|
+
/// <param name="destination"></param>
|
|
2069
|
+
/// <param name="numberOfBytes"></param>
|
|
2070
|
+
/// <returns> boolen true if equal</returns>
|
|
1390
2071
|
static CompareByteArray(source, destination, numberOfBytes) {
|
|
1391
2072
|
if (source.length >= numberOfBytes && destination.length >= numberOfBytes) {
|
|
1392
2073
|
for (let len = 0; len < numberOfBytes; len++) {
|
|
@@ -1398,6 +2079,13 @@ class Misc {
|
|
|
1398
2079
|
return false;
|
|
1399
2080
|
return true;
|
|
1400
2081
|
}
|
|
2082
|
+
/// <summary>
|
|
2083
|
+
/// Performs an unsigned bitwise right shift with the specified number
|
|
2084
|
+
/// </summary>
|
|
2085
|
+
/// <param name="number">Number to operate on</param>
|
|
2086
|
+
/// <param name="bits">Ammount of bits to shift</param>
|
|
2087
|
+
/// <returns>The resulting number from the shift operation</returns>
|
|
2088
|
+
// TODO: instead of calling URShift(number, bits), we can use((uint)number) >> bits.
|
|
1401
2089
|
static URShift(number, bits) {
|
|
1402
2090
|
let result;
|
|
1403
2091
|
if (number >= 0) {
|
|
@@ -1408,9 +2096,20 @@ class Misc {
|
|
|
1408
2096
|
}
|
|
1409
2097
|
return result;
|
|
1410
2098
|
}
|
|
2099
|
+
/// <summary>
|
|
2100
|
+
/// get system's time in milliseconds
|
|
2101
|
+
/// </summary>
|
|
2102
|
+
/// <returns></returns>
|
|
1411
2103
|
static getSystemMilliseconds() {
|
|
2104
|
+
// TODO - check if we need this adjustment
|
|
1412
2105
|
return Math.floor((DateTime.Now.Ticks - 621355968000000000) / 10000);
|
|
1413
2106
|
}
|
|
2107
|
+
/// <summary>
|
|
2108
|
+
/// Compares 2 int arrays
|
|
2109
|
+
/// </summary>
|
|
2110
|
+
/// <param name="arrayOne"></param>
|
|
2111
|
+
/// <param name="arrayTwo"></param>
|
|
2112
|
+
/// <returns>true if arrays are equal else false</returns>
|
|
1414
2113
|
static CompareIntArrays(arrayOne, arrayTwo) {
|
|
1415
2114
|
let areEqual = false;
|
|
1416
2115
|
if (arrayOne === arrayTwo) {
|
|
@@ -1430,6 +2129,11 @@ class Misc {
|
|
|
1430
2129
|
}
|
|
1431
2130
|
return areEqual;
|
|
1432
2131
|
}
|
|
2132
|
+
/// <summary>
|
|
2133
|
+
/// Returns the comma separated string for the values passed in int array.
|
|
2134
|
+
/// </summary>
|
|
2135
|
+
/// <param name="values">Integer array</param>
|
|
2136
|
+
/// <returns>comma separated string</returns>
|
|
1433
2137
|
static GetCommaSeperatedString(intArray) {
|
|
1434
2138
|
let temp = new StringBuilder();
|
|
1435
2139
|
for (let val = 0; val < intArray.length; val = val + 1) {
|
|
@@ -1441,6 +2145,11 @@ class Misc {
|
|
|
1441
2145
|
}
|
|
1442
2146
|
return temp.ToString();
|
|
1443
2147
|
}
|
|
2148
|
+
/// <summary>
|
|
2149
|
+
/// Returns int array out of comma separated string
|
|
2150
|
+
/// </summary>
|
|
2151
|
+
/// <param name="value">comma separated string</param>
|
|
2152
|
+
/// <returns>Integer array</returns>
|
|
1444
2153
|
static GetIntArray(commaSeparatedValue) {
|
|
1445
2154
|
let intArray = new Array(0);
|
|
1446
2155
|
if (!NString.IsNullOrEmpty(commaSeparatedValue)) {
|
|
@@ -1468,6 +2177,14 @@ class Base64 {
|
|
|
1468
2177
|
else
|
|
1469
2178
|
return Base64.encode_1(str, isUseEnvCharset, encoding);
|
|
1470
2179
|
}
|
|
2180
|
+
/// <summary> Encodes string using the base64-encoding.
|
|
2181
|
+
/// If isUseEnvCharset is true, use the specific charset when converting
|
|
2182
|
+
/// string to byte array. (DBCS support)
|
|
2183
|
+
/// </summary>
|
|
2184
|
+
/// <param name="str">the string </param>
|
|
2185
|
+
/// <param name="isUseEnvCharset"> </param>
|
|
2186
|
+
/// <param name="encoding"> Environment.Encoding </param>
|
|
2187
|
+
/// <returns> the base64-encoded str </returns>
|
|
1471
2188
|
static encode_1(str, isUseEnvCharset, encoding) {
|
|
1472
2189
|
let result;
|
|
1473
2190
|
if (str === null) {
|
|
@@ -1496,12 +2213,18 @@ class Base64 {
|
|
|
1496
2213
|
}
|
|
1497
2214
|
return result;
|
|
1498
2215
|
}
|
|
2216
|
+
/// <summary> This method encodes the given byte[] using the base64-encoding
|
|
2217
|
+
/// specified in RFC-2045 (Section 6.8).
|
|
2218
|
+
/// </summary>
|
|
2219
|
+
/// <param name="data">the data </param>
|
|
2220
|
+
/// <returns> the base64-encoded data </returns>
|
|
1499
2221
|
static encodeBytes(data) {
|
|
1500
2222
|
if (data === null)
|
|
1501
2223
|
return null;
|
|
1502
2224
|
let dest = new Uint8Array(Math.floor((data.length + 2) / 3) * 4);
|
|
1503
2225
|
let sidx = 0;
|
|
1504
2226
|
let didx = 0;
|
|
2227
|
+
// 3-byte to 4-byte conversion + 0-63 to ASCII printable conversion
|
|
1505
2228
|
while (sidx < data.length - 2) {
|
|
1506
2229
|
dest[didx++] = Base64._base64EncMap[Misc.URShift(data[sidx], 2) & 63];
|
|
1507
2230
|
dest[didx++] = Base64._base64EncMap[(Misc.URShift(data[sidx + 1], 4) & 15) | (data[sidx] << 4 & 63)];
|
|
@@ -1519,6 +2242,7 @@ class Base64 {
|
|
|
1519
2242
|
dest[didx++] = Base64._base64EncMap[data[sidx] << 4 & 63];
|
|
1520
2243
|
}
|
|
1521
2244
|
}
|
|
2245
|
+
// add padding
|
|
1522
2246
|
while (didx < dest.length) {
|
|
1523
2247
|
dest[didx] = 61;
|
|
1524
2248
|
didx = didx + 1;
|
|
@@ -1530,6 +2254,12 @@ class Base64 {
|
|
|
1530
2254
|
encoding = null;
|
|
1531
2255
|
return Base64.decode_1(str, encoding);
|
|
1532
2256
|
}
|
|
2257
|
+
/// <summary> This method decodes the given string using the base64-encoding
|
|
2258
|
+
/// specified in RFC-2045 (Section 6.8).
|
|
2259
|
+
/// </summary>
|
|
2260
|
+
/// <param name="str">the base64-encoded string. </param>
|
|
2261
|
+
/// <param name="encoding">Environment.Encoding or null.</param>
|
|
2262
|
+
/// <returns> the decoded str.</returns>
|
|
1533
2263
|
static decode_1(str, encoding) {
|
|
1534
2264
|
let result;
|
|
1535
2265
|
if (str === null) {
|
|
@@ -1558,6 +2288,11 @@ class Base64 {
|
|
|
1558
2288
|
}
|
|
1559
2289
|
return result;
|
|
1560
2290
|
}
|
|
2291
|
+
/// <summary> This method decodes the given byte[] using the base64-encoding
|
|
2292
|
+
/// specified in RFC-2045 (Section 6.8).
|
|
2293
|
+
/// </summary>
|
|
2294
|
+
/// <param name="data">the base64-encoded data.</param>
|
|
2295
|
+
/// <returns> the decoded <var>data</va
|
|
1561
2296
|
static decodeBytes(data) {
|
|
1562
2297
|
if (data === null)
|
|
1563
2298
|
return null;
|
|
@@ -1566,9 +2301,11 @@ class Base64 {
|
|
|
1566
2301
|
tail = tail - 1;
|
|
1567
2302
|
}
|
|
1568
2303
|
let dest = new Uint8Array(tail - Math.floor(data.length / 4));
|
|
2304
|
+
// ASCII printable to 0-63 conversion
|
|
1569
2305
|
for (let idx = 0; idx < data.length; idx = idx + 1) {
|
|
1570
2306
|
data[idx] = Base64._base64DecMap[data[idx]];
|
|
1571
2307
|
}
|
|
2308
|
+
// 4-byte to 3-byte conversion
|
|
1572
2309
|
let sidx = 0;
|
|
1573
2310
|
let didx;
|
|
1574
2311
|
for (didx = 0; didx < dest.length - 2; didx = didx + 3) {
|
|
@@ -1583,6 +2320,7 @@ class Base64 {
|
|
|
1583
2320
|
dest[didx] = (((data[sidx + 1] << 4) & 255) | (Misc.URShift(data[sidx + 2], 2) & 15));
|
|
1584
2321
|
return dest;
|
|
1585
2322
|
}
|
|
2323
|
+
/// <summary> decoded and return an hex representation of the data</summary>
|
|
1586
2324
|
static decodeToHex(str) {
|
|
1587
2325
|
if (str === null)
|
|
1588
2326
|
return null;
|
|
@@ -1590,9 +2328,13 @@ class Base64 {
|
|
|
1590
2328
|
return str;
|
|
1591
2329
|
return StrUtil.stringToHexaDump(Base64.decode(str), 2);
|
|
1592
2330
|
}
|
|
2331
|
+
/// <summary> decodes a string to byte array</summary>
|
|
1593
2332
|
static decodeToByte(str) {
|
|
1594
2333
|
if (str === null)
|
|
1595
2334
|
return null;
|
|
2335
|
+
// QCR 740918 if we have and empty expression it is sent from the server as empty string
|
|
2336
|
+
// and changed locally to a string with one blank either way they are not valid base64 encoded
|
|
2337
|
+
// string and should not be decoded.
|
|
1596
2338
|
if (str === "" || str === " ")
|
|
1597
2339
|
return new Uint8Array(0);
|
|
1598
2340
|
try {
|
|
@@ -1621,6 +2363,18 @@ class Base64 {
|
|
|
1621
2363
|
}
|
|
1622
2364
|
|
|
1623
2365
|
class ChoiceUtils {
|
|
2366
|
+
/// <summary>
|
|
2367
|
+
/// init the display Value from string
|
|
2368
|
+
/// </summary>
|
|
2369
|
+
/// <param name = "choiceDispStr">the all substring separated with comma.
|
|
2370
|
+
/// The behavior:
|
|
2371
|
+
/// a. when have "\" before char a-z need to ignore the \ put the a-z char
|
|
2372
|
+
/// b. when "\," -> ","
|
|
2373
|
+
/// c. when "\-" -> "-"
|
|
2374
|
+
/// d. when "\\" -> "\"
|
|
2375
|
+
/// e. when "\\\\" -> "\\"
|
|
2376
|
+
/// the display can be all string. and we don't need to check validation according to the dataType(as we do in Link
|
|
2377
|
+
/// </param>
|
|
1624
2378
|
static GetDisplayListFromString(choiceDispStr, removeAccelerators, shouldMakePrintable, shouldTrimOptions) {
|
|
1625
2379
|
let fromHelp = new Array("\\\\", "\\-", "\\,");
|
|
1626
2380
|
let toHelp = new Array("XX", "XX", "XX");
|
|
@@ -1697,12 +2451,16 @@ class ChoiceUtils {
|
|
|
1697
2451
|
}
|
|
1698
2452
|
}
|
|
1699
2453
|
|
|
2454
|
+
//This class contains all the constants which are used in MgxpaRIA.exe as well as in MgGui.dll.
|
|
1700
2455
|
class Constants {
|
|
2456
|
+
/// <summary> Null Arithmetic values</summary>
|
|
1701
2457
|
static NULL_ARITH_NULLIFY = 'N';
|
|
1702
2458
|
static NULL_ARITH_USE_DEF = 'U';
|
|
2459
|
+
/// <summary> select program : select mode property</summary>
|
|
1703
2460
|
static SELPRG_MODE_BEFORE = 'B';
|
|
1704
2461
|
static SELPRG_MODE_AFTER = 'A';
|
|
1705
2462
|
static SELPRG_MODE_PROMPT = 'P';
|
|
2463
|
+
/// <summary> move in View</summary>
|
|
1706
2464
|
static MOVE_UNIT_TABLE = 'T';
|
|
1707
2465
|
static MOVE_UNIT_PAGE = 'P';
|
|
1708
2466
|
static MOVE_UNIT_ROW = 'R';
|
|
@@ -1716,6 +2474,7 @@ class Constants {
|
|
|
1716
2474
|
static MOVE_DIRECTION_FIRST_SON = 'F';
|
|
1717
2475
|
static MOVE_DIRECTION_NEXT_SIBLING = 'X';
|
|
1718
2476
|
static MOVE_DIRECTION_PREV_SIBLING = 'V';
|
|
2477
|
+
/// <summary> refresh types for a task form</summary>
|
|
1719
2478
|
static TASK_REFRESH_FORM = 'F';
|
|
1720
2479
|
static TASK_REFRESH_TABLE = 'T';
|
|
1721
2480
|
static TASK_REFRESH_TREE_AND_FORM = 'R';
|
|
@@ -1726,12 +2485,15 @@ class Constants {
|
|
|
1726
2485
|
static TASK_MODE_CREATE = 'C';
|
|
1727
2486
|
static TASK_MODE_DELETE = 'D';
|
|
1728
2487
|
static TASK_MODE_NONE = ' ';
|
|
2488
|
+
/// <summary> task level</summary>
|
|
1729
2489
|
static TASK_LEVEL_NONE = ' ';
|
|
1730
2490
|
static TASK_LEVEL_TASK = 'T';
|
|
1731
2491
|
static TASK_LEVEL_RECORD = 'R';
|
|
1732
2492
|
static TASK_LEVEL_CONTROL = 'C';
|
|
2493
|
+
/// <summary> special records constants</summary>
|
|
1733
2494
|
static MG_DATAVIEW_FIRST_RECORD = Int32.MinValue;
|
|
1734
2495
|
static MG_DATAVIEW_LAST_RECORD = Int32.MaxValue;
|
|
2496
|
+
/// <summary> action states for keyboard mapping</summary>
|
|
1735
2497
|
static ACT_STT_TBL_SCREEN_MODE = 0x0001;
|
|
1736
2498
|
static ACT_STT_TBL_LEFT_TO_RIGHT = 0x0002;
|
|
1737
2499
|
static ACT_STT_TBL_SCREEN_TOP = 0x0004;
|
|
@@ -1746,13 +2508,17 @@ class Constants {
|
|
|
1746
2508
|
static ACT_STT_EDT_EDITING = 0x0800;
|
|
1747
2509
|
static ACT_STT_TREE_PARK = 0x1000;
|
|
1748
2510
|
static ACT_STT_TREE_EDITING = 0x2000;
|
|
1749
|
-
static ForwardSlashWebUsage = "web";
|
|
2511
|
+
static ForwardSlashWebUsage = "web"; // refer to a forward slash as a relative web url.
|
|
1750
2512
|
static HTTP_PROTOCOL = "http://";
|
|
1751
2513
|
static HTTPS_PROTOCOL = "https://";
|
|
1752
2514
|
static FILE_PROTOCOL = "file://";
|
|
2515
|
+
/// <summary>threads constants</summary>
|
|
1753
2516
|
static MG_GUI_THREAD = "MG_GUI_THREAD";
|
|
1754
2517
|
static MG_WORK_THREAD = "MG_WORK_THREAD";
|
|
1755
2518
|
static MG_TIMER_THREAD = "MG_TIMER_THREAD";
|
|
2519
|
+
/// <summary>
|
|
2520
|
+
/// property name for the runtime designer
|
|
2521
|
+
/// </summary>
|
|
1756
2522
|
static ConfigurationFilePropertyName = "Configuration file";
|
|
1757
2523
|
static WinPropText = "Text";
|
|
1758
2524
|
static WinPropLayer = "Layer";
|
|
@@ -1786,9 +2552,12 @@ class XMLConstants {
|
|
|
1786
2552
|
static MG_TAG_TASK = "task";
|
|
1787
2553
|
static MG_TAG_TASK_END = "/task";
|
|
1788
2554
|
static MG_TAG_RECOMPUTE = "recompute";
|
|
2555
|
+
//TODO: this class contains the constants which are used for XML parsing.
|
|
2556
|
+
//Check if we can move it to Util.dll
|
|
1789
2557
|
static MG_ATTR_VB_VIEW_ROWIDX = "db_view_rowidx";
|
|
1790
2558
|
static MG_ATTR_CONTROL_ISN = "controlIsn";
|
|
1791
2559
|
static MG_HOR_ALIGMENT_IS_INHERITED = "horizontalAlignmentIsFromSystemDefault";
|
|
2560
|
+
// MainHeaders
|
|
1792
2561
|
static MAX_PATH = 260;
|
|
1793
2562
|
static FILE_NAME_SIZE = XMLConstants.MAX_PATH + 1;
|
|
1794
2563
|
static CDATA_START = "<![CDATA[";
|
|
@@ -1840,9 +2609,11 @@ class XMLConstants {
|
|
|
1840
2609
|
static MG_ATTR_PROGRAM_ISN = "programIsn";
|
|
1841
2610
|
static MG_ATTR_TASK_ISN = "taskIsn";
|
|
1842
2611
|
static MG_ATTR_ROUTER_PATH = "RouterPath";
|
|
2612
|
+
static MG_ATTR_DEF_ROUTER_NAME = "DefRouterName";
|
|
1843
2613
|
static MG_ATTR_IN_DEFAULT_ROUTER_OUTLET = "InDefaultRouterOutlet";
|
|
1844
2614
|
static MG_ATTR_EXPAND = "expand";
|
|
1845
2615
|
static MG_ATTR_EXP = "exp";
|
|
2616
|
+
static MG_ATTR_SUBFORM_EXP = "subformCtrlExpIdx";
|
|
1846
2617
|
static MG_ATTR_ERROR_EXP = "errorExp";
|
|
1847
2618
|
static MG_ATTR_ERROR = "errorMsg";
|
|
1848
2619
|
static MG_ATTR_IS_GENERIC = "isGeneric";
|
|
@@ -1874,11 +2645,13 @@ class XMLConstants {
|
|
|
1874
2645
|
static MG_ATTR_IS_GUI_THREAD_EXECUTION = "isGuiThreadExecution";
|
|
1875
2646
|
static MG_TAG_TASKDEFINITIONID_ENTRY = "taskDefinitionId";
|
|
1876
2647
|
static MG_TAG_OBJECT_REFERENCE = "objectRef";
|
|
2648
|
+
//Help types
|
|
1877
2649
|
static MG_ATTR_HLP_TYP_TOOLTIP = "T";
|
|
1878
2650
|
static MG_ATTR_HLP_TYP_PROMPT = "P";
|
|
1879
2651
|
static MG_ATTR_HLP_TYP_URL = "U";
|
|
1880
2652
|
static MG_ATTR_HLP_TYP_INTERNAL = "I";
|
|
1881
2653
|
static MG_ATTR_HLP_TYP_WINDOWS = "W";
|
|
2654
|
+
//Internal help attributes.
|
|
1882
2655
|
static MG_ATTR_INTERNAL_HELP_TYPE = "type";
|
|
1883
2656
|
static MG_ATTR_INTERNAL_HELP_NAME = "name";
|
|
1884
2657
|
static MG_ATTR_INTERNAL_HELP_FRAMEX = "framex";
|
|
@@ -1893,20 +2666,26 @@ class XMLConstants {
|
|
|
1893
2666
|
static MG_ATTR_INTERNAL_TITLE_BAR = "titlebar";
|
|
1894
2667
|
static MG_ATTR_INTERNAL_HELP_SYSTEM_MENU = "sysmenu";
|
|
1895
2668
|
static MG_ATTR_INTERNAL_HELP_FONT_TABLE_INDEX = "fonttableindex";
|
|
2669
|
+
//Windows help attributes.
|
|
1896
2670
|
static MG_ATTR_WINDOWS_HELP_FILE = "file";
|
|
1897
2671
|
static MG_ATTR_WINDOWS_HELP_COMMAND = "command";
|
|
1898
2672
|
static MG_ATTR_WINDOWS_HELP_KEY = "key";
|
|
2673
|
+
//Print data attributes.
|
|
1899
2674
|
static MG_TAG_PRINT_DATA = "Print_data";
|
|
1900
2675
|
static MG_TAG_PRINT_DATA_END = "/Print_data";
|
|
1901
2676
|
static MG_TAG_RECORD = "Record";
|
|
1902
2677
|
static MG_TAG_RECORD_END = "/Record";
|
|
2678
|
+
//Custom Validators attributes.
|
|
1903
2679
|
static MG_TAG_CUSTOM_VALIDATORS = "CustomValidators";
|
|
1904
2680
|
static MG_TAG_CUSTOM_VALIDATORS_END = "/CustomValidators";
|
|
1905
2681
|
static MG_TAG_CUSTOM_VALIDATOR = "CustomValidator";
|
|
2682
|
+
// date/time formats for DateTimeUtils
|
|
2683
|
+
//TODO: isolate to a different file?
|
|
1906
2684
|
static ERROR_LOG_TIME_FORMAT = "HH:mm:ss.S";
|
|
1907
2685
|
static ERROR_LOG_DATE_FORMAT = "DD/MM/YYYY";
|
|
1908
2686
|
static HTTP_ERROR_TIME_FORMAT = "HH:mm:ss";
|
|
1909
2687
|
static CACHED_DATE_TIME_FORMAT = "DD/MM/YYYY HH:mm:ss";
|
|
2688
|
+
//webs constants
|
|
1910
2689
|
static MG_TAG_WS_READ_REQUEST = "Read";
|
|
1911
2690
|
static MG_TAG_WS_CREATE_REQUEST = "Create";
|
|
1912
2691
|
static MG_TAG_WS_CREATE_REQUEST_END = "/Create";
|
|
@@ -1940,6 +2719,7 @@ class XMLConstants {
|
|
|
1940
2719
|
}
|
|
1941
2720
|
|
|
1942
2721
|
class DateTimeUtils {
|
|
2722
|
+
/// <summary> returns the number in a 2 digit string
|
|
1943
2723
|
static int2str(n) {
|
|
1944
2724
|
return (n > 9) ? n.toString() : ("0" + n);
|
|
1945
2725
|
}
|
|
@@ -1991,7 +2771,13 @@ class DateTimeUtils {
|
|
|
1991
2771
|
}
|
|
1992
2772
|
}
|
|
1993
2773
|
|
|
2774
|
+
/// <summary>
|
|
2775
|
+
/// An interface to define the constantes used by the Picture mechanism.
|
|
2776
|
+
/// </summary>
|
|
1994
2777
|
class PICInterface {
|
|
2778
|
+
//--------------------------------------------------------------------------
|
|
2779
|
+
// TEMP!
|
|
2780
|
+
//--------------------------------------------------------------------------
|
|
1995
2781
|
static PIC_X = 1;
|
|
1996
2782
|
static PIC_U = 2;
|
|
1997
2783
|
static PIC_L = 3;
|
|
@@ -2009,30 +2795,32 @@ class PICInterface {
|
|
|
2009
2795
|
static PIC_MMT = 15;
|
|
2010
2796
|
static PIC_SS = 16;
|
|
2011
2797
|
static PIC_PM = 17;
|
|
2012
|
-
static PIC_HYYYYY = 18;
|
|
2013
|
-
static PIC_HL = 19;
|
|
2014
|
-
static PIC_HDD = 20;
|
|
2015
|
-
static PIC_MS = 21;
|
|
2016
|
-
static PIC_LOCAL = 23;
|
|
2798
|
+
static PIC_HYYYYY = 18; // Hebrew year
|
|
2799
|
+
static PIC_HL = 19; // Hebrew thousand year
|
|
2800
|
+
static PIC_HDD = 20; // Hebrew day of month
|
|
2801
|
+
static PIC_MS = 21; // Milliseconds
|
|
2802
|
+
static PIC_LOCAL = 23; // the space between PIC_LOCAL and PIC_MAX_OP
|
|
2017
2803
|
static PIC_MAX_MSK_LEN = 100;
|
|
2018
|
-
|
|
2019
|
-
static
|
|
2020
|
-
static
|
|
2021
|
-
static
|
|
2022
|
-
static
|
|
2023
|
-
static
|
|
2024
|
-
|
|
2025
|
-
static
|
|
2026
|
-
static
|
|
2027
|
-
static
|
|
2804
|
+
// JPN: Japanese date picture support
|
|
2805
|
+
static PIC_JY1 = PICInterface.PIC_LOCAL + 0; // the name of an era (1 byte)
|
|
2806
|
+
static PIC_JY2 = PICInterface.PIC_LOCAL + 1; // the name of an era (2 bytes)
|
|
2807
|
+
static PIC_JY4 = PICInterface.PIC_LOCAL + 2; // the name of an era (4 bytes)
|
|
2808
|
+
static PIC_YJ = PICInterface.PIC_LOCAL + 3; // a year of an era
|
|
2809
|
+
static PIC_BB = PICInterface.PIC_LOCAL + 4; // a day of the week (2, 4 or 6 bytes)
|
|
2810
|
+
// DBCS pictures for iSeries
|
|
2811
|
+
static PIC_J = PICInterface.PIC_LOCAL + 5; // DBCS only (with SO/SI)
|
|
2812
|
+
static PIC_T = PICInterface.PIC_LOCAL + 6; // All SBCS or All DBCS (with SO/SI)
|
|
2813
|
+
static PIC_G = PICInterface.PIC_LOCAL + 7; // DBCS only (without SO/SI)
|
|
2814
|
+
static PIC_S = PICInterface.PIC_LOCAL + 8; // SBCS only
|
|
2815
|
+
static PIC_MAX_OP = 31; // is reserved for DLL"s picture
|
|
2028
2816
|
static NULL_CHAR = -1;
|
|
2029
2817
|
static DB_STR_MAX = 255;
|
|
2030
|
-
static DAYSINFOURCENT = 146097;
|
|
2031
|
-
static DAYSINCENTURY = 36524;
|
|
2032
|
-
static DAYSINFOURYEAR = 1461;
|
|
2818
|
+
static DAYSINFOURCENT = 146097; // ((365*4+1)*25-1)*4+1 */
|
|
2819
|
+
static DAYSINCENTURY = 36524; // (365*4+1)*25-1 */
|
|
2820
|
+
static DAYSINFOURYEAR = 1461; // 365*4+1 */
|
|
2033
2821
|
static DAYSINYEAR = 365;
|
|
2034
2822
|
static DAYSINMONTH = 31;
|
|
2035
|
-
static DATE_BUDDHIST_GAP = 543;
|
|
2823
|
+
static DATE_BUDDHIST_GAP = 543; // years above the gregorian date
|
|
2036
2824
|
static DEFAULT_DATE = "693961";
|
|
2037
2825
|
static DEFAULT_TIME = "0";
|
|
2038
2826
|
static date_day_tab = [
|
|
@@ -2044,6 +2832,9 @@ class PICInterface {
|
|
|
2044
2832
|
static date_dow_str = [
|
|
2045
2833
|
" ", "Sunday ", "Monday ", "Tuesday ", "Wednesday ", "Thursday ", "Friday ", "Saturday "
|
|
2046
2834
|
];
|
|
2835
|
+
//public final static readonly int DEF_century = 1920;
|
|
2836
|
+
//public final static readonly Nchar DEF_date_mode = 'E';
|
|
2837
|
+
// vec of pictures that can be given a numeric char only
|
|
2047
2838
|
static NumDirective = [
|
|
2048
2839
|
4, 5, 6, 7, 9, 10, 11, 12, 14, 15, 16
|
|
2049
2840
|
];
|
|
@@ -2056,9 +2847,15 @@ const DATE_DOW_LEN = 10;
|
|
|
2056
2847
|
class DateUtil {
|
|
2057
2848
|
static _localMonths = new Array(13);
|
|
2058
2849
|
static _localDays = new Array(8);
|
|
2850
|
+
/// <summary>
|
|
2851
|
+
/// extract the vector which contains the names of the months, as specified by the
|
|
2852
|
+
/// language CAB
|
|
2853
|
+
/// </summary>
|
|
2059
2854
|
static getLocalMonths(names) {
|
|
2060
2855
|
let monthLen = DATE_MONTH_LEN;
|
|
2856
|
+
// if it's the first time then access the language CAB and take the values
|
|
2061
2857
|
if (typeof DateUtil._localMonths[0] === "undefined") {
|
|
2858
|
+
//cut the string into separate values
|
|
2062
2859
|
if (names !== null) {
|
|
2063
2860
|
DateUtil._localMonths[0] = PICInterface.date_month_str[0];
|
|
2064
2861
|
for (let i = 1; i < DateUtil._localMonths.length; i = i + 1) {
|
|
@@ -2081,9 +2878,15 @@ class DateUtil {
|
|
|
2081
2878
|
}
|
|
2082
2879
|
return DateUtil._localMonths;
|
|
2083
2880
|
}
|
|
2881
|
+
/// <summary>
|
|
2882
|
+
/// extract the vector which contains the names of the days, as specified by the
|
|
2883
|
+
/// language CAB
|
|
2884
|
+
/// </summary>
|
|
2084
2885
|
static getLocalDays(names) {
|
|
2085
2886
|
let dowLen = DATE_DOW_LEN;
|
|
2887
|
+
// if it's the first time then access the language CAB and take the values
|
|
2086
2888
|
if (typeof DateUtil._localDays[0] === "undefined") {
|
|
2889
|
+
//cut the string into separate values
|
|
2087
2890
|
if (names !== null) {
|
|
2088
2891
|
DateUtil._localDays[0] = PICInterface.date_dow_str[0];
|
|
2089
2892
|
for (let i = 1; i < DateUtil._localDays.length; i = i + 1) {
|
|
@@ -3871,6 +4674,7 @@ var NotifyCollectionChangedAction;
|
|
|
3871
4674
|
NotifyCollectionChangedAction[NotifyCollectionChangedAction["Reset"] = 4] = "Reset";
|
|
3872
4675
|
})(NotifyCollectionChangedAction || (NotifyCollectionChangedAction = {}));
|
|
3873
4676
|
|
|
4677
|
+
/// <summary> this interface defines the internal events codes</summary>
|
|
3874
4678
|
class InternalInterface {
|
|
3875
4679
|
static MG_ACT_NONE = 0;
|
|
3876
4680
|
static MG_ACT_CHAR = 1;
|
|
@@ -4174,6 +4978,7 @@ class InternalInterface {
|
|
|
4174
4978
|
static MG_ACT_CONTEXT_REMOVE = 647;
|
|
4175
4979
|
static MG_ACT_DUMP_ENVIRONMENT = 653;
|
|
4176
4980
|
static MG_ACT_TOT_CNT = 654;
|
|
4981
|
+
// NEW INTERNAL EVENTS
|
|
4177
4982
|
static MG_ACT_TASK_PREFIX = 1001;
|
|
4178
4983
|
static MG_ACT_TASK_SUFFIX = 1002;
|
|
4179
4984
|
static MG_ACT_REC_PREFIX = 1003;
|
|
@@ -4190,6 +4995,7 @@ class InternalInterface {
|
|
|
4190
4995
|
static MG_ACT_CYCLE_NEXT_DELETE_REC = 1018;
|
|
4191
4996
|
static MG_ACT_COMPUTE = 1020;
|
|
4192
4997
|
static MG_ACT_DUMMY = 1111;
|
|
4998
|
+
// INTERNAL EVENTS for WebClient
|
|
4193
4999
|
static MG_ACT_CTRL_FOCUS = 2001;
|
|
4194
5000
|
static MG_ACT_CTRL_MOUSEUP = 2002;
|
|
4195
5001
|
static MG_ACT_CTRL_KEYDOWN = 2003;
|
|
@@ -4199,12 +5005,13 @@ class InternalInterface {
|
|
|
4199
5005
|
static MG_ACT_ROW_DATA_CURR_PAGE = 2007;
|
|
4200
5006
|
static MG_ACT_DV_TO_GUI = 2008;
|
|
4201
5007
|
static MG_ACT_DISABLE_EVENTS = 2010;
|
|
5008
|
+
// toggle insert is temp 539 , it should match the code in online once it will be created.
|
|
4202
5009
|
static MG_ACT_TOGGLE_INSERT = 2011;
|
|
4203
5010
|
static MG_ACT_INCREMENTAL_LOCATE = 2017;
|
|
4204
5011
|
static MG_ACT_MOVE_TO_FIRST_CTRL = 2018;
|
|
4205
5012
|
static MG_ACT_SET_EXTERNAL_VALUE = 2019;
|
|
4206
5013
|
static MG_ACT_CTRL_FOCUS_ON_NON_MAGIC_CONTROL = 2020;
|
|
4207
|
-
static MG_ACT_FETCH_RECORDS_AHEAD_FROM_SERVER = 2021;
|
|
5014
|
+
static MG_ACT_FETCH_RECORDS_AHEAD_FROM_SERVER = 2021; // for paginated table, fetch records in background depending on PROP_TYPE_SERVER_READ_AHEAD
|
|
4208
5015
|
static BuiltinEvent(eventCode) {
|
|
4209
5016
|
return eventCode >= 1000 || eventCode === InternalInterface.MG_ACT_POST_REFRESH_BY_PARENT;
|
|
4210
5017
|
}
|
|
@@ -4223,11 +5030,14 @@ class OSEnvironment {
|
|
|
4223
5030
|
static TabSeq = "\t";
|
|
4224
5031
|
static getStackTrace() {
|
|
4225
5032
|
let ex = new Exception();
|
|
4226
|
-
ex.errorLevel++;
|
|
5033
|
+
ex.errorLevel++; // we need to remove the line which contains call to this method
|
|
4227
5034
|
return ex.StackTrace;
|
|
4228
5035
|
}
|
|
4229
5036
|
}
|
|
4230
5037
|
|
|
5038
|
+
/// <summary>
|
|
5039
|
+
/// The class is responsible to maintain the Request information while sending a request to server
|
|
5040
|
+
/// </summary>
|
|
4231
5041
|
class RequestInfo {
|
|
4232
5042
|
serverCallAt;
|
|
4233
5043
|
runtimeTaskTree = new List();
|
|
@@ -4261,9 +5071,16 @@ var LogType;
|
|
|
4261
5071
|
LogType[LogType["warning"] = 2] = "warning";
|
|
4262
5072
|
LogType[LogType["error"] = 3] = "error";
|
|
4263
5073
|
})(LogType || (LogType = {}));
|
|
5074
|
+
/// <summary>
|
|
5075
|
+
/// Logger class will take care of client side logging . It will check for various log levels and accordingly will write messages in log file.
|
|
5076
|
+
/// </summary>
|
|
5077
|
+
//@dynamic
|
|
4264
5078
|
class Logger {
|
|
4265
5079
|
static instance = null;
|
|
4266
|
-
LogLevel = 0;
|
|
5080
|
+
LogLevel = 0; // InternalLogLevel
|
|
5081
|
+
/// <summary>
|
|
5082
|
+
/// While writing the error messages in the file play the beep.
|
|
5083
|
+
/// </summary>
|
|
4267
5084
|
ShouldBeep = false;
|
|
4268
5085
|
static set Instance(value) {
|
|
4269
5086
|
Logger.instance = value;
|
|
@@ -4274,10 +5091,26 @@ class Logger {
|
|
|
4274
5091
|
}
|
|
4275
5092
|
return Logger.instance;
|
|
4276
5093
|
}
|
|
5094
|
+
/// <summary>
|
|
5095
|
+
/// Initialize logger
|
|
5096
|
+
/// </summary>
|
|
5097
|
+
/// <param name="logLevel"></param>
|
|
5098
|
+
/// <param name="internalLogSync"></param>
|
|
4277
5099
|
Initialize(logLevel, shouldBeep) {
|
|
4278
5100
|
try {
|
|
5101
|
+
// let logSync: LogSyncMode = LogSyncMode.Session;
|
|
4279
5102
|
this.LogLevel = logLevel;
|
|
4280
5103
|
this.ShouldBeep = shouldBeep;
|
|
5104
|
+
// TODO: implement
|
|
5105
|
+
// String strLogSync = internalLogSync;
|
|
5106
|
+
// if (!string.IsNullOrEmpty(strLogSync))
|
|
5107
|
+
// {
|
|
5108
|
+
// if (strLogSync.StartsWith("M", StringComparison.CurrentCultureIgnoreCase))
|
|
5109
|
+
// logSync = LogSyncMode.Message;
|
|
5110
|
+
// else if (strLogSync.StartsWith("F", StringComparison.CurrentCultureIgnoreCase))
|
|
5111
|
+
// logSync = LogSyncMode.Flush;
|
|
5112
|
+
// }
|
|
5113
|
+
//
|
|
4281
5114
|
}
|
|
4282
5115
|
catch (e) {
|
|
4283
5116
|
this.WriteDevToLog("ClientManager.init(): " + e.Message);
|
|
@@ -4301,6 +5134,9 @@ class Logger {
|
|
|
4301
5134
|
ShouldLogExtendedServerRelatedMessages() {
|
|
4302
5135
|
return (Logger.Instance.ShouldLog(Logger_LogLevels.ServerMessages) || Logger.Instance.ShouldLog(Logger_LogLevels.Support) || Logger.Instance.ShouldLog(Logger_LogLevels.Development)) && this.LogLevel !== Logger_LogLevels.Basic;
|
|
4303
5136
|
}
|
|
5137
|
+
/// <summary></summary>
|
|
5138
|
+
/// <param name="msg"></param>
|
|
5139
|
+
/// <param name="openIfNecessary">open the log file if not opened yet</param>
|
|
4304
5140
|
WriteToLog(msg, openIfNecessary, logType = LogType.info) {
|
|
4305
5141
|
if (this.LogLevel > Logger_LogLevels.None || openIfNecessary) {
|
|
4306
5142
|
msg = NString.Format("{0} {1}", (this.LogLevel === Logger_LogLevels.Basic) ? new Date().toISOString() : DateTimeUtils.ToString(DateTime.Now, XMLConstants.ERROR_LOG_TIME_FORMAT, this), msg);
|
|
@@ -4316,16 +5152,26 @@ class Logger {
|
|
|
4316
5152
|
}
|
|
4317
5153
|
}
|
|
4318
5154
|
}
|
|
5155
|
+
/// <summary>
|
|
5156
|
+
/// write a server access to the log
|
|
5157
|
+
/// </summary>
|
|
5158
|
+
/// <param name="msg">the message to write to the log</param>
|
|
4319
5159
|
WriteServerToLog(msg) {
|
|
4320
5160
|
if (this.ShouldLogServerRelatedMessages()) {
|
|
4321
5161
|
this.WriteToLog(NString.Format("Server, Thread={0}: ", Thread.CurrentThread.ManagedThreadId) + msg, false, LogType.info);
|
|
4322
5162
|
}
|
|
4323
5163
|
}
|
|
5164
|
+
/// <summary>
|
|
5165
|
+
/// write a server access to the log, including the content
|
|
5166
|
+
/// </summary>
|
|
5167
|
+
/// <param name="msg">the message to write to the log</param>
|
|
4324
5168
|
WriteServerMessagesToLog(msg) {
|
|
4325
5169
|
if (this.ShouldLogExtendedServerRelatedMessages()) {
|
|
4326
5170
|
this.WriteToLog("Server#: " + msg, false, LogType.info);
|
|
4327
5171
|
}
|
|
4328
5172
|
}
|
|
5173
|
+
/// <summary>Write a QC message to the log</summary>
|
|
5174
|
+
/// <param name="msg">the message to write to the log</param>
|
|
4329
5175
|
WriteSupportToLog(msg, skipLine) {
|
|
4330
5176
|
if (this.LogLevel >= Logger_LogLevels.Support && this.LogLevel !== Logger_LogLevels.Basic) {
|
|
4331
5177
|
if (skipLine) {
|
|
@@ -4336,16 +5182,31 @@ class Logger {
|
|
|
4336
5182
|
}
|
|
4337
5183
|
}
|
|
4338
5184
|
}
|
|
5185
|
+
/// <summary>
|
|
5186
|
+
/// write a performance message to the log
|
|
5187
|
+
/// </summary>
|
|
5188
|
+
/// <param name="msg">the message to write to the log</param>
|
|
4339
5189
|
WriteGuiToLog(msg) {
|
|
4340
5190
|
if (this.LogLevel >= Logger_LogLevels.Gui && this.LogLevel !== Logger_LogLevels.Basic) {
|
|
4341
5191
|
this.WriteToLog(msg, false, LogType.info);
|
|
4342
5192
|
}
|
|
4343
5193
|
}
|
|
5194
|
+
/// <summary>
|
|
5195
|
+
/// write a developer message to the log
|
|
5196
|
+
/// </summary>
|
|
5197
|
+
/// <param name="msg">the message to write to the log</param>
|
|
4344
5198
|
WriteDevToLog(msg) {
|
|
4345
5199
|
if (this.LogLevel >= Logger_LogLevels.Development && this.LogLevel !== Logger_LogLevels.Basic) {
|
|
4346
5200
|
this.WriteToLog("DEV: " + msg, false, LogType.info);
|
|
4347
5201
|
}
|
|
4348
5202
|
}
|
|
5203
|
+
/// <summary>
|
|
5204
|
+
/// Writes a basic level entry to log
|
|
5205
|
+
/// </summary>
|
|
5206
|
+
/// <param name="messageDirection">message direction relative to the current module (RIA client). Can be either MessageEntering or MessageLeaving</param>
|
|
5207
|
+
/// <param name="statusCode">HTTP status code</param>
|
|
5208
|
+
/// <param name="contentLength">length of the http message</param>
|
|
5209
|
+
/// <param name="httpHeaders">HTTP headers</param>
|
|
4349
5210
|
WriteBasicToLog(messageDirection, contextID, sessionCounter, clientID, serverID, responseTime, statusCode, httpHeaders, contentLength) {
|
|
4350
5211
|
if (this.LogLevel === Logger_LogLevels.Basic) {
|
|
4351
5212
|
let text = httpHeaders;
|
|
@@ -4353,6 +5214,8 @@ class Logger {
|
|
|
4353
5214
|
text = NString.Replace(text, "\r\n", "|");
|
|
4354
5215
|
let arg_E4_0 = "RIA,{0}_{1},{2},{3},{4},{5},-,{6},{7},{8},{9},{10},{11}";
|
|
4355
5216
|
let expr_3E = new Array(12);
|
|
5217
|
+
// TODO : need to check How to handle Process class.
|
|
5218
|
+
// expr_3E[0] = Process.GetCurrentProcess().Id;
|
|
4356
5219
|
expr_3E[1] = Thread.CurrentThread.ManagedThreadId;
|
|
4357
5220
|
expr_3E[2] = new Date().toISOString();
|
|
4358
5221
|
expr_3E[3] = ((messageDirection === Logger_MessageDirection.MessageLeaving) ? "MSGL" : "MSGE");
|
|
@@ -4371,14 +5234,37 @@ class Logger {
|
|
|
4371
5234
|
console.log(value);
|
|
4372
5235
|
}
|
|
4373
5236
|
}
|
|
5237
|
+
/// <summary>
|
|
5238
|
+
/// Writes request information to log
|
|
5239
|
+
/// </summary>
|
|
5240
|
+
/// <param name="clientSession">The clientSession object to be logged</param>
|
|
4374
5241
|
WriteRequestInfoToLog(requestInfo, extraMessageStr) {
|
|
4375
5242
|
if (this.LogLevel === Logger_LogLevels.RequestInfo) {
|
|
5243
|
+
// Chrome debugger automatically recomputes logged objects.
|
|
5244
|
+
// Hence, clone the requestInfo object to print the details at the time of logging
|
|
4376
5245
|
console.log(extraMessageStr, RequestInfo.clone(requestInfo));
|
|
4377
5246
|
}
|
|
4378
5247
|
}
|
|
5248
|
+
/// <summary>
|
|
5249
|
+
/// Writes a request exception basic level entry to log
|
|
5250
|
+
/// </summary>
|
|
5251
|
+
/// <param name="contextID"></param>
|
|
5252
|
+
/// <param name="sessionCounter"></param>
|
|
5253
|
+
/// <param name="clientID"></param>
|
|
5254
|
+
/// <param name="serverID"></param>
|
|
5255
|
+
/// <param name="ex">the logged exception</param>
|
|
4379
5256
|
WriteBasicErrorToLog() {
|
|
4380
5257
|
Debug.Assert(this.LogLevel === Logger_LogLevels.Basic);
|
|
4381
|
-
|
|
5258
|
+
// TODO : Need to check how to handle Process
|
|
5259
|
+
// let value: string = NString.Format("RIA,{0}_{1},{2},{3},{4},{5},-,{6},{7},-,-,-,{8} {9}", [
|
|
5260
|
+
// Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId, DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"), "RES", contextID, sessionCounter, clientID, serverID, ex.GetType(), ex.Message
|
|
5261
|
+
// ]);
|
|
5262
|
+
// NConsole.WriteLine(value);
|
|
5263
|
+
}
|
|
5264
|
+
/// <summary>
|
|
5265
|
+
/// Write an error to the log
|
|
5266
|
+
/// </summary>
|
|
5267
|
+
/// <param name="msg">the message to write to the log</param>
|
|
4382
5268
|
WriteErrorToLog(msg) {
|
|
4383
5269
|
this.WriteToLog("MagicWeb [ERROR]: " + StrUtil.getConsoleErorString(msg), true, LogType.error);
|
|
4384
5270
|
}
|
|
@@ -4458,6 +5344,9 @@ class Logger {
|
|
|
4458
5344
|
}
|
|
4459
5345
|
this.WriteToLog(stringBuilder.ToString(), true);
|
|
4460
5346
|
}
|
|
5347
|
+
/// <summary>
|
|
5348
|
+
/// Flush the log writer.
|
|
5349
|
+
/// </summary>
|
|
4461
5350
|
Flush() {
|
|
4462
5351
|
}
|
|
4463
5352
|
constructor() {
|
|
@@ -4651,6 +5540,11 @@ class MsgInterface {
|
|
|
4651
5540
|
static RC_ERROR_ILLEGAL_RETURN_VAL_ATTR_TYPE = "RC_ERROR_ILLEGAL_RETURN_VAL_ATTR_TYPE";
|
|
4652
5541
|
static STR_ERR_WEBCLIENT_PROGRAM_RELOADED = "STR_ERR_WEBCLIENT_PROGRAM_RELOADED";
|
|
4653
5542
|
static STR_ERR_EXECUTED_PROGRAM_CHANGED = "STR_ERR_EXECUTED_PROGRAM_CHANGED";
|
|
5543
|
+
static STR_ERR_MAX_ALLOWED_LENGTH = "STR_ERR_MAX_ALLOWED_LENGTH";
|
|
5544
|
+
static STR_ERR_MAX_ALLOWED_VALUE = "STR_ERR_MAX_ALLOWED_VALUE";
|
|
5545
|
+
static STR_ERR_BLANK_SUBFORM_NAME = "STR_ERR_BLANK_SUBFORM_NAME";
|
|
5546
|
+
static STR_ERR_SUBFORM_NAME_EXCEEDS_LIMIT = "STR_ERR_SUBFORM_NAME_EXCEEDS_LIMIT";
|
|
5547
|
+
static STR_ERR_INVALID_HASH_ALGO_NUMBER = "STR_ERR_INVALID_HASH_ALGO_NUMBER";
|
|
4654
5548
|
static DefaultMessages = [
|
|
4655
5549
|
new DefaultMsgDetails("STR_ERR_NUM", "Invalid number"), new DefaultMsgDetails("STR_ERR_DATE", "Invalid date"), new DefaultMsgDetails("STR_ERR_TIME", "Invalid time"), new DefaultMsgDetails("MONTHS_PTR", "January February March April May June July August September October November December"), new DefaultMsgDetails("DAYS_PTR", "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"), new DefaultMsgDetails("STR_ERR_NEGETIVE", "Control value must be non-negative"), new DefaultMsgDetails("STR_RNG_TXT", "Valid control input range is:"), new DefaultMsgDetails("EDT_ERR_STR_1", "Numeric format is limited to %d.%d digits"), new DefaultMsgDetails("STR_ERR_PIPE_CONNECTION", "The connection to the runtime engine was lost. Process ID "), new DefaultMsgDetails("FMERROR_STR_BAD_NAME", "Invalid data source name:"), new DefaultMsgDetails("FMERROR_STR_BAD_DAMAGED", "Damaged data source:"), new DefaultMsgDetails("FMERROR_STR_BAD_BADCREATE", "Create error:"), new DefaultMsgDetails("FMERROR_STR_FILE_LOCKED", "Unable to lock the data source:"), new DefaultMsgDetails("FMERROR_STR_BAD_UNEXPECTED", "Unexpected error, data source:"), new DefaultMsgDetails("FMERROR_STR_BAD_SERVER_NOTFOUND", "Server not found, data source:"), new DefaultMsgDetails("FMERROR_STR_BAD_SERVER_INIT_FAILED", "Server initialization failed, data source:"), new DefaultMsgDetails("FMERROR_STR_UNLOCKED", "Releasing failed, data source:"), new DefaultMsgDetails("FMERROR_STR_BAD_DB_INIT_FAILED", "Database initialization error, data source:"), new DefaultMsgDetails("FMERROR_STR_BAD_LOCK_OPEN", "Failed to open lock file, data source:"),
|
|
4656
5550
|
new DefaultMsgDetails("FMERROR_STR_BAD_BADOPEN", "Failed to open, data source:"), new DefaultMsgDetails("FMERROR_STR_BAD_BADDEF", "Definition mismatch, data source:"), new DefaultMsgDetails("FMERROR_STR_DUP_KEY", "Duplicate index, data source:"), new DefaultMsgDetails("FMERROR_STR_COMM_LOADED", "Communication Gateway not loaded, data source:"), new DefaultMsgDetails("FMERROR_STR_COMM_CONNECT", "Failed to connect to server, data source:"), new DefaultMsgDetails("FMERROR_STR_READONLY", "Cannot modify Read Only, data source:"), new DefaultMsgDetails("FMERROR_STR_BAD_BADCLOSE", "Failed to close, data source:"), new DefaultMsgDetails("FMERROR_STR_REC_LOCKED", "Waiting for locked row, data source:"), new DefaultMsgDetails("FMERROR_STR_TRANS_OPEN", "Failed to open transaction, data source:"), new DefaultMsgDetails("FMERROR_STR_COMMIT", "Failed to commit transaction"), new DefaultMsgDetails("FMERROR_STR_ABORT", "Failed to abort transaction"), new DefaultMsgDetails("FMERROR_STR_RSRC_LOCKED", "Waiting for lock in database:"), new DefaultMsgDetails("FMERROR_STR_NODEF", "Database definition cannot be loaded, data source:"), new DefaultMsgDetails("FMERROR_STR_DEADLOCK", "Deadlock error, data source:"), new DefaultMsgDetails("FMERROR_STR_DB_PROT", "Exceeded database protection limits, data source:"), new DefaultMsgDetails("FMERROR_STR_OWNR_ALRDY_SET", "Access Key already set, data source:"), new DefaultMsgDetails("FMERROR_STR_INVALID_OWNR", "Invalid Access Key, data source:"), new DefaultMsgDetails("FMERROR_STR_CLR_OWNR_FAIL", "Failed to clear Access Key, data source:"), new DefaultMsgDetails("FMERROR_STR_NO_DATABASE", "Unknown database, data source:"), new DefaultMsgDetails("FMERROR_STR_DBMS_ALTER_FAIL", "Warning - Database failed to alter, data source:"),
|
|
@@ -4662,17 +5556,22 @@ class MsgInterface {
|
|
|
4662
5556
|
new DefaultMsgDetails("ERR_CANNOT_HANDLE_WEB_REQUEST", "Web client requests cannot be handled when the online MDI is open"),
|
|
4663
5557
|
new DefaultMsgDetails("STR_MDI_FRAME_MISMATCH", "The selected MDI Frame form cannot be used for the current task"), new DefaultMsgDetails("CHK_ERR_OFFLINE_NOT_SUPPORT_FRAME_INTERFACE", "Frames interface is not supported in an offline task"), new DefaultMsgDetails("STR_USER_ID", "User ID:"), new DefaultMsgDetails("STR_PASSWORD", "Password:"),
|
|
4664
5558
|
new DefaultMsgDetails("STR_LOGON_PARAMETERS", "Logon Parameters"), new DefaultMsgDetails("STR_LOGON_CAPTION", "Logon"), new DefaultMsgDetails("STR_LOGON_INSTRUCTION", "Please enter your user ID and password."), new DefaultMsgDetails("STR_GENERIC_ERROR_MESSAGE", "An error occurred (%d). Please contact your system administrator."), new DefaultMsgDetails("STR_GENERIC_ERROR_CONNECTION_PROBLEM_TITLE", "Connection problem:"), new DefaultMsgDetails("STR_GENERIC_ERROR_CONNECTION_PROBLEM_MESSAGE", "Try to reconnect?"), new DefaultMsgDetails("FMERROR_STR_TRANS_OPEN_FAILED", "The transaction was already opened by another task"), new DefaultMsgDetails("STR_ERR_CANNOT_CALL_OFFLINE_BYNAME_OR_BYEXP", "Offline programs cannot be called using the Call By Name or Call By Expression operations"), new DefaultMsgDetails("RT_STR_DELETE_MODE_WITHOUT_MAINSOURCE_NOTALLOWED", "Deleted task mode is not allowed without main source"), new DefaultMsgDetails("RC_ERROR_INCOMPATIBLE_DATASOURCES", "Failed to update the local data. Please clear the application cache or reinstall the application."), new DefaultMsgDetails("RC_ERROR_INVALID_SOURCES", "Failed to update the application."), new DefaultMsgDetails("RC_ERROR_OFFLINE_NEXT_EXECUTION_INVALID_SOURCES", "Failed to start the application. Please restart while the application is connected to the server."), new DefaultMsgDetails("RC_ERR_ANDROID_LOAD_FROM_URL", "Cannot access the server."), new DefaultMsgDetails("STR_CLIENT_DB_DEL_OPERATION_FAILED", "ClientDbDel opeartion failed."), new DefaultMsgDetails("STR_DATAVIEW_TO_DATASOURCE_OPERATION_FAILED", "DataViewToDataSource operation failed."), new DefaultMsgDetails("STR_CLIENT_DB_DISCONNECT_DATASOURCE_OPEN", "Failed to disconnect, data source is open."), new DefaultMsgDetails("STR_CLIENT_DB_DISCONNECT_DATASOURCE_NOT_EXIST", "Failed to disconnect, database does not exist."), new DefaultMsgDetails("FMERROR_STR_INVALID_PASSWORD", "Invalid Password, data source:"), new DefaultMsgDetails("STR_MOBILE_TAB_CONTROL_CANNOT_BE_USED", "Tab control cannot be used in a container control."), new DefaultMsgDetails("STR_MOBILE_CONTROLS_CANNOT_BE_OUTSIDE_TAB", "Controls cannot be placed outside a tab control."),
|
|
4665
|
-
new DefaultMsgDetails("STR_MOBILE_TAB_CONTROL_LAYER_0", "Controls cannot be linked to layer 0 of the tab control."), new DefaultMsgDetails("STR_MOBILE_TAB_DISPLAY_LIST_ERROR", "The number of entries in the Display List property must be zero or match the number of entries in the Items List property."), new DefaultMsgDetails("RC_ERROR_ARG_TYPE_STRING_NUMBER_MISMATCH", "The number of characters in the argument type string does not match the number of total arguments"), new DefaultMsgDetails("RC_ERROR_ILLEGAL_ARG_ATTR_TYPE", "Illegal argument attribute type"), new DefaultMsgDetails("RC_ERROR_ILLEGAL_RETURN_VAL_ATTR_TYPE", "Illegal return value attribute type"), new DefaultMsgDetails("STR_ERR_WEBCLIENT_PROGRAM_RELOADED", "Changes were done at the server side. Browser will be refreshed in order to get the latest changes."), new DefaultMsgDetails("STR_ERR_EXECUTED_PROGRAM_CHANGED", "Executed program changed at the server side. Browser will be refreshed in order to get the latest changes.")
|
|
5559
|
+
new DefaultMsgDetails("STR_MOBILE_TAB_CONTROL_LAYER_0", "Controls cannot be linked to layer 0 of the tab control."), new DefaultMsgDetails("STR_MOBILE_TAB_DISPLAY_LIST_ERROR", "The number of entries in the Display List property must be zero or match the number of entries in the Items List property."), new DefaultMsgDetails("RC_ERROR_ARG_TYPE_STRING_NUMBER_MISMATCH", "The number of characters in the argument type string does not match the number of total arguments"), new DefaultMsgDetails("RC_ERROR_ILLEGAL_ARG_ATTR_TYPE", "Illegal argument attribute type"), new DefaultMsgDetails("RC_ERROR_ILLEGAL_RETURN_VAL_ATTR_TYPE", "Illegal return value attribute type"), new DefaultMsgDetails("STR_ERR_WEBCLIENT_PROGRAM_RELOADED", "Changes were done at the server side. Browser will be refreshed in order to get the latest changes."), new DefaultMsgDetails("STR_ERR_EXECUTED_PROGRAM_CHANGED", "Executed program changed at the server side. Browser will be refreshed in order to get the latest changes."), new DefaultMsgDetails("STR_ERR_MAX_ALLOWED_LENGTH", "Max length allowed is :"), new DefaultMsgDetails("STR_ERR_MAX_ALLOWED_VALUE", "Max value allowed is :"),
|
|
5560
|
+
new DefaultMsgDetails("STR_ERR_BLANK_SUBFORM_NAME", "Subform Destination is blank."), new DefaultMsgDetails("STR_ERR_SUBFORM_NAME_EXCEEDS_LIMIT", "Subform Destination exceeds 30 characters."),
|
|
5561
|
+
new DefaultMsgDetails("STR_ERR_INVALID_HASH_ALGO_NUMBER", "Invalid algorithm number. Please enter among 1-3."),
|
|
4666
5562
|
];
|
|
4667
5563
|
constructor() {
|
|
4668
5564
|
}
|
|
4669
5565
|
}
|
|
4670
5566
|
|
|
5567
|
+
/// <summary> implementation of a general queue</summary>
|
|
4671
5568
|
class Queue {
|
|
4672
5569
|
_queueVec = null;
|
|
5570
|
+
/// <summary> </summary>
|
|
4673
5571
|
constructor() {
|
|
4674
5572
|
this._queueVec = new List();
|
|
4675
5573
|
}
|
|
5574
|
+
/// <summary> returns the first object in the queue</summary>
|
|
4676
5575
|
get() {
|
|
4677
5576
|
let returnValue = null;
|
|
4678
5577
|
if (this._queueVec.length > 0) {
|
|
@@ -4681,15 +5580,20 @@ class Queue {
|
|
|
4681
5580
|
}
|
|
4682
5581
|
return returnValue;
|
|
4683
5582
|
}
|
|
5583
|
+
/// <summary> add an object to the end of the queue</summary>
|
|
5584
|
+
/// <param name="obj">the object to add
|
|
4684
5585
|
put(obj) {
|
|
4685
5586
|
this._queueVec.push(obj);
|
|
4686
5587
|
}
|
|
5588
|
+
/// <summary> remove all the objects from the queue</summary>
|
|
4687
5589
|
clear() {
|
|
4688
5590
|
this._queueVec.Clear();
|
|
4689
5591
|
}
|
|
5592
|
+
/// <summary> returns true if the queue is empty</summary>
|
|
4690
5593
|
isEmpty() {
|
|
4691
5594
|
return this._queueVec.length === 0;
|
|
4692
5595
|
}
|
|
5596
|
+
/// <summary> returns size of the queue</summary>
|
|
4693
5597
|
Size() {
|
|
4694
5598
|
return this._queueVec.length;
|
|
4695
5599
|
}
|
|
@@ -4729,7 +5633,15 @@ class Randomizer {
|
|
|
4729
5633
|
}
|
|
4730
5634
|
}
|
|
4731
5635
|
|
|
5636
|
+
/// <summary>
|
|
5637
|
+
/// type checking for enum 'StorageAttribute'
|
|
5638
|
+
/// </summary>
|
|
4732
5639
|
class StorageAttributeCheck {
|
|
5640
|
+
/// <summary>
|
|
5641
|
+
/// is the both types belong to the same inner data types
|
|
5642
|
+
/// </summary>
|
|
5643
|
+
/// <param name = "type1">data type</param>
|
|
5644
|
+
/// <param name = "type2">data type</param>
|
|
4733
5645
|
static isTheSameType(type1, type2) {
|
|
4734
5646
|
return type1 === type2 || (StorageAttributeCheck.isTypeNumeric(type1) && StorageAttributeCheck.isTypeNumeric(type2)) || (StorageAttributeCheck.isTypeLogical(type1) && StorageAttributeCheck.isTypeLogical(type2)) || (StorageAttributeCheck.IsTypeAlphaOrUnicode(type1) && StorageAttributeCheck.IsTypeAlphaOrUnicode(type2)) || (StorageAttributeCheck.isTypeBlob(type1) && StorageAttributeCheck.isTypeBlob(type2)) || (StorageAttributeCheck.isTypeDotNet(type1) && StorageAttributeCheck.isTypeDotNet(type2));
|
|
4735
5647
|
}
|
|
@@ -4739,18 +5651,36 @@ class StorageAttributeCheck {
|
|
|
4739
5651
|
static isTypeAlpha(type) {
|
|
4740
5652
|
return type === StorageAttribute.ALPHA || type === StorageAttribute.MEMO;
|
|
4741
5653
|
}
|
|
5654
|
+
/// <summary>
|
|
5655
|
+
/// is the both types belong to the NUMERIC inner type
|
|
5656
|
+
/// </summary>
|
|
4742
5657
|
static isTypeNumeric(type) {
|
|
4743
5658
|
return type === StorageAttribute.DATE || type === StorageAttribute.TIME || type === StorageAttribute.NUMERIC;
|
|
4744
5659
|
}
|
|
5660
|
+
/// <summary>
|
|
5661
|
+
/// is the both types belong to the LOGICAL inner type
|
|
5662
|
+
/// </summary>
|
|
4745
5663
|
static isTypeLogical(type) {
|
|
4746
5664
|
return type === StorageAttribute.BOOLEAN;
|
|
4747
5665
|
}
|
|
5666
|
+
/// <summary>
|
|
5667
|
+
/// is the type is DOTNET
|
|
5668
|
+
/// </summary>
|
|
4748
5669
|
static isTypeDotNet(type) {
|
|
4749
5670
|
return type === StorageAttribute.DOTNET;
|
|
4750
5671
|
}
|
|
5672
|
+
/// <summary>
|
|
5673
|
+
/// is the type ALPHA or UNICODE
|
|
5674
|
+
/// </summary>
|
|
5675
|
+
/// <param name = "type">data type</param>
|
|
4751
5676
|
static IsTypeAlphaOrUnicode(type) {
|
|
4752
5677
|
return type === StorageAttribute.ALPHA || type === StorageAttribute.UNICODE;
|
|
4753
5678
|
}
|
|
5679
|
+
/// <summary>
|
|
5680
|
+
/// is the inner type ALPHA or UNICODE
|
|
5681
|
+
/// </summary>
|
|
5682
|
+
/// <param name = "type1">data type</param>
|
|
5683
|
+
/// <param name = "type2">data type</param>
|
|
4754
5684
|
static StorageFldAlphaOrUnicode(type1, type2) {
|
|
4755
5685
|
return StorageAttributeCheck.IsTypeAlphaOrUnicode(type1) && StorageAttributeCheck.IsTypeAlphaOrUnicode(type2);
|
|
4756
5686
|
}
|
|
@@ -4766,6 +5696,12 @@ class StorageAttributeCheck {
|
|
|
4766
5696
|
return ((type1AlphaOrUnicode && type2Blob) || (type2AlphaOrUnicode && type1Blob));
|
|
4767
5697
|
}
|
|
4768
5698
|
}
|
|
5699
|
+
/// <summary>
|
|
5700
|
+
/// Check if types are compatible or not.
|
|
5701
|
+
/// </summary>
|
|
5702
|
+
/// <param name="sourceAttribute"></param>
|
|
5703
|
+
/// <param name="destinationAttribute"></param>
|
|
5704
|
+
/// <returns></returns>
|
|
4769
5705
|
static IsTypeCompatibile(sourceAttribute, destinationAttribute) {
|
|
4770
5706
|
let isTypeCompatible = false;
|
|
4771
5707
|
switch (sourceAttribute) {
|
|
@@ -4812,22 +5748,39 @@ class StorageAttributeCheck {
|
|
|
4812
5748
|
}
|
|
4813
5749
|
}
|
|
4814
5750
|
|
|
5751
|
+
/// <summary>
|
|
5752
|
+
/// Helper class for synchronized execution.
|
|
5753
|
+
/// It works by creating a promise and then waiting for the promise to be completed
|
|
5754
|
+
/// </summary>
|
|
5755
|
+
// @dynamic
|
|
4815
5756
|
class SyncExecutionHelper {
|
|
4816
5757
|
static _instance = null;
|
|
5758
|
+
/// <summary>
|
|
5759
|
+
/// get instance of SyncExecutionHelper
|
|
5760
|
+
/// </summary>
|
|
4817
5761
|
static get Instance() {
|
|
4818
5762
|
if (SyncExecutionHelper._instance === null)
|
|
4819
5763
|
SyncExecutionHelper._instance = new SyncExecutionHelper();
|
|
4820
5764
|
return SyncExecutionHelper._instance;
|
|
4821
5765
|
}
|
|
5766
|
+
// resolver is caller when promise is fullfilled
|
|
4822
5767
|
resolver = null;
|
|
5768
|
+
/// <summary>
|
|
5769
|
+
/// To wait, create a promise and add wait for it to complete
|
|
5770
|
+
/// </summary>
|
|
4823
5771
|
Wait() {
|
|
5772
|
+
// Logger.Instance.WriteDevToLog("SyncExecutionHelper.Wait()");
|
|
4824
5773
|
return new Promise((resolve) => {
|
|
4825
5774
|
this.resolver = resolve;
|
|
4826
5775
|
}).then();
|
|
4827
5776
|
}
|
|
5777
|
+
/// <summary>
|
|
5778
|
+
/// To resume call the resolver
|
|
5779
|
+
/// </summary>
|
|
4828
5780
|
Pulse() {
|
|
4829
5781
|
let resolver = this.resolver;
|
|
4830
5782
|
if (resolver != null) {
|
|
5783
|
+
// Logger.Instance.WriteDevToLog("SyncExecutionHelper.Pulse()");
|
|
4831
5784
|
resolver();
|
|
4832
5785
|
}
|
|
4833
5786
|
}
|
|
@@ -4835,6 +5788,12 @@ class SyncExecutionHelper {
|
|
|
4835
5788
|
|
|
4836
5789
|
const MAX_GENGO = 6;
|
|
4837
5790
|
class UtilDateJpn {
|
|
5791
|
+
/// <summary>
|
|
5792
|
+
/// JPN: Japanese date picture support
|
|
5793
|
+
/// Utility Class for Japanese date
|
|
5794
|
+
/// </summary>
|
|
5795
|
+
/// <author> Toshiro Nakayoshi (MSJ)
|
|
5796
|
+
/// </author>
|
|
4838
5797
|
static _instance = null;
|
|
4839
5798
|
static JweekStr = [
|
|
4840
5799
|
" ", "日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"
|
|
@@ -4860,10 +5819,11 @@ class UtilDateJpn {
|
|
|
4860
5819
|
[1926, 12, 25, 359],
|
|
4861
5820
|
[1989, 1, 8, 8],
|
|
4862
5821
|
[2019, 5, 1, 121],
|
|
4863
|
-
[0, 0, 0, 0],
|
|
5822
|
+
[0, 0, 0, 0], // reserve for extra gengo x 3
|
|
4864
5823
|
[0, 0, 0, 0],
|
|
4865
5824
|
[0, 0, 0, 0]
|
|
4866
5825
|
];
|
|
5826
|
+
// ---- gengo (the name of an era) ---------------------------------------
|
|
4867
5827
|
MaxGengo = MAX_GENGO;
|
|
4868
5828
|
static getInstance() {
|
|
4869
5829
|
if (UtilDateJpn._instance === null) {
|
|
@@ -4888,6 +5848,18 @@ class UtilDateJpn {
|
|
|
4888
5848
|
}
|
|
4889
5849
|
return UtilDateJpn.JmonthStr[month];
|
|
4890
5850
|
}
|
|
5851
|
+
/// <summary>
|
|
5852
|
+
/// Convert a year (A.D.) into Japanese year of an era
|
|
5853
|
+
/// This method is modeled after "date_jpn_year_ofs" function in
|
|
5854
|
+
/// "\mglocal\jpn\jpndate_jpn.cpp".
|
|
5855
|
+
/// </summary>
|
|
5856
|
+
/// <param name = "intYear:">year (A.D.)
|
|
5857
|
+
/// </param>
|
|
5858
|
+
/// <param name = "intDoy:">DOY
|
|
5859
|
+
/// </param>
|
|
5860
|
+
/// <returns> year of an era.
|
|
5861
|
+
/// if either param is invalid, it returns 0.
|
|
5862
|
+
/// </returns>
|
|
4891
5863
|
date_jpn_year_ofs(intYear, intDoy) {
|
|
4892
5864
|
let result;
|
|
4893
5865
|
if (intYear < 1 || intDoy < 1) {
|
|
@@ -4905,6 +5877,20 @@ class UtilDateJpn {
|
|
|
4905
5877
|
}
|
|
4906
5878
|
return result;
|
|
4907
5879
|
}
|
|
5880
|
+
/// <summary>
|
|
5881
|
+
/// Convert a year (A.D.) into a name of a Japanese era
|
|
5882
|
+
/// This method is modeled after "date_jpn_yr_2_a" function in
|
|
5883
|
+
/// "\mglocal\jpn\jpndate_jpn.cpp".
|
|
5884
|
+
/// </summary>
|
|
5885
|
+
/// <param name = "intYear:">year (A.D.)
|
|
5886
|
+
/// </param>
|
|
5887
|
+
/// <param name = "intDoy:">DOY
|
|
5888
|
+
/// </param>
|
|
5889
|
+
/// <param name = "isKanji:">return a full name (true) or the first letter (false).
|
|
5890
|
+
/// </param>
|
|
5891
|
+
/// <returns> name of an era
|
|
5892
|
+
/// if either param is invalid, it returns "?".
|
|
5893
|
+
/// </returns>
|
|
4908
5894
|
date_jpn_yr_2_a(intYear, intDoy, isKanji) {
|
|
4909
5895
|
let num;
|
|
4910
5896
|
if (intYear < 1 || intDoy < 1) {
|
|
@@ -4928,6 +5914,17 @@ class UtilDateJpn {
|
|
|
4928
5914
|
}
|
|
4929
5915
|
return result;
|
|
4930
5916
|
}
|
|
5917
|
+
/// <summary>
|
|
5918
|
+
/// Get the first year (A.D.) of a specified Japanese era
|
|
5919
|
+
/// This method is modeled after "date_jpn_yr_4_a" function in
|
|
5920
|
+
/// "\mglocal\jpn\jpndate_jpn.cpp".
|
|
5921
|
+
/// </summary>
|
|
5922
|
+
/// <param name = "ucp_str:">name of a specified Japanese era
|
|
5923
|
+
/// </param>
|
|
5924
|
+
/// <param name = "s_len:">length (the number of bytes) of ucp_str
|
|
5925
|
+
/// </param>
|
|
5926
|
+
/// <returns> year (A.D.)
|
|
5927
|
+
/// </returns>
|
|
4931
5928
|
date_jpn_yr_4_a(ucp_str, s_len) {
|
|
4932
5929
|
let i = this.MaxGengo - 1;
|
|
4933
5930
|
if (s_len > 0) {
|
|
@@ -4966,6 +5963,17 @@ class UtilDateJpn {
|
|
|
4966
5963
|
}
|
|
4967
5964
|
return result;
|
|
4968
5965
|
}
|
|
5966
|
+
/// <summary>
|
|
5967
|
+
/// Get the name of an era in date string
|
|
5968
|
+
/// </summary>
|
|
5969
|
+
/// <param name = "strDate:">string of input strDate
|
|
5970
|
+
/// </param>
|
|
5971
|
+
/// <param name = "strPicture:">string of picture
|
|
5972
|
+
/// </param>
|
|
5973
|
+
/// <param name = "intStartPos:">start position to search
|
|
5974
|
+
/// </param>
|
|
5975
|
+
/// <returns> name of an era
|
|
5976
|
+
/// </returns>
|
|
4969
5977
|
static getEraNameStrInDate(strDate, strPicture, intStartPos) {
|
|
4970
5978
|
let result = null;
|
|
4971
5979
|
let intPicIdxOfs = 0;
|
|
@@ -4984,6 +5992,7 @@ class UtilDateJpn {
|
|
|
4984
5992
|
intLetters = 2;
|
|
4985
5993
|
}
|
|
4986
5994
|
else {
|
|
5995
|
+
// If "strDate" contains DBCS, the position of "strPicture" has to skip next index.
|
|
4987
5996
|
if (i < strDate.length) {
|
|
4988
5997
|
if (!UtilStrByteMode.isHalfWidth(strDate[i]) && UtilStrByteMode.isHalfWidth(strPicture[i + intPicIdxOfs])) {
|
|
4989
5998
|
intPicIdxOfs = intPicIdxOfs + 1;
|
|
@@ -4995,10 +6004,19 @@ class UtilDateJpn {
|
|
|
4995
6004
|
}
|
|
4996
6005
|
}
|
|
4997
6006
|
result = strDate.substr(i, intLetters);
|
|
4998
|
-
break;
|
|
6007
|
+
break; // exit loop
|
|
4999
6008
|
}
|
|
5000
6009
|
return result;
|
|
5001
6010
|
}
|
|
6011
|
+
/// <summary>
|
|
6012
|
+
/// Get the length of the name of an era in picture
|
|
6013
|
+
/// </summary>
|
|
6014
|
+
/// <param name = "strPicture">string of picture
|
|
6015
|
+
/// </param>
|
|
6016
|
+
/// <param name = "intStartPos">start position to search
|
|
6017
|
+
/// </param>
|
|
6018
|
+
/// <returns> length of the name (the number of bytes)
|
|
6019
|
+
/// </returns>
|
|
5002
6020
|
static getEraNameLenInPicture(strPicture, intStartPos) {
|
|
5003
6021
|
let intLetters = 0;
|
|
5004
6022
|
for (let i = intStartPos; i < strPicture.length; i = i + 1) {
|
|
@@ -5021,6 +6039,15 @@ class UtilDateJpn {
|
|
|
5021
6039
|
}
|
|
5022
6040
|
return intLetters;
|
|
5023
6041
|
}
|
|
6042
|
+
/// <summary>
|
|
6043
|
+
/// Get the start year of an era in picture
|
|
6044
|
+
/// </summary>
|
|
6045
|
+
/// <param name = "strDate:">string of input strDate
|
|
6046
|
+
/// </param>
|
|
6047
|
+
/// <param name = "strPicture:">string of picture
|
|
6048
|
+
/// </param>
|
|
6049
|
+
/// <returns> start year of the era
|
|
6050
|
+
/// </returns>
|
|
5024
6051
|
getStartYearOfEra(strDate, strPicture) {
|
|
5025
6052
|
let eraNameStrInDate = UtilDateJpn.getEraNameStrInDate(strDate, strPicture, 0);
|
|
5026
6053
|
let result;
|
|
@@ -5039,7 +6066,13 @@ class UtilDateJpn {
|
|
|
5039
6066
|
}
|
|
5040
6067
|
return result;
|
|
5041
6068
|
}
|
|
6069
|
+
/// <summary> Add extra Gengo data into the Gengo tables</summary>
|
|
6070
|
+
/// <param name="strExtraGengo:">
|
|
6071
|
+
/// </param>
|
|
6072
|
+
/// <returns>
|
|
6073
|
+
/// </returns>
|
|
5042
6074
|
addExtraGengo(strExtraGengo) {
|
|
6075
|
+
// e.g. strExtraGengo = "2012/04/01,092,AaABCD;2013/04/01,091,WwWXYZ;"
|
|
5043
6076
|
let strGengoInfo = strExtraGengo.split(';');
|
|
5044
6077
|
for (let i = 0; i < strGengoInfo.length; i = i + 1) {
|
|
5045
6078
|
if (strGengoInfo[i].length > 0) {
|
|
@@ -5047,13 +6080,13 @@ class UtilDateJpn {
|
|
|
5047
6080
|
if (strTok.length === 3 && strTok[0].length > 0 && strTok[1].length > 0 && strTok[2].length > 0) {
|
|
5048
6081
|
let strDate = strTok[0].split('/');
|
|
5049
6082
|
if (strDate.length === 3 && strDate[0].length > 0 && strDate[1].length > 0 && strDate[2].length > 0) {
|
|
5050
|
-
UtilDateJpn.GengoStr[MAX_GENGO + i][0] = strTok[2].substr(0, 1);
|
|
5051
|
-
UtilDateJpn.GengoStr[MAX_GENGO + i][1] = strTok[2].substr(1, 1);
|
|
5052
|
-
UtilDateJpn.GengoStr[MAX_GENGO + i][2] = strTok[2].substr(2);
|
|
5053
|
-
UtilDateJpn.StartDayOfGengo[MAX_GENGO + i][0] = NNumber.Parse(strDate[0]);
|
|
5054
|
-
UtilDateJpn.StartDayOfGengo[MAX_GENGO + i][1] = NNumber.Parse(strDate[1]);
|
|
5055
|
-
UtilDateJpn.StartDayOfGengo[MAX_GENGO + i][2] = NNumber.Parse(strDate[2]);
|
|
5056
|
-
UtilDateJpn.StartDayOfGengo[MAX_GENGO + i][3] = NNumber.Parse(strTok[1]);
|
|
6083
|
+
UtilDateJpn.GengoStr[MAX_GENGO + i][0] = strTok[2].substr(0, 1); // symbol name (upper case): A
|
|
6084
|
+
UtilDateJpn.GengoStr[MAX_GENGO + i][1] = strTok[2].substr(1, 1); // symbol name (lower case): a
|
|
6085
|
+
UtilDateJpn.GengoStr[MAX_GENGO + i][2] = strTok[2].substr(2); // gengo name: ABCD
|
|
6086
|
+
UtilDateJpn.StartDayOfGengo[MAX_GENGO + i][0] = NNumber.Parse(strDate[0]); // start year: 2012
|
|
6087
|
+
UtilDateJpn.StartDayOfGengo[MAX_GENGO + i][1] = NNumber.Parse(strDate[1]); // start month: 4
|
|
6088
|
+
UtilDateJpn.StartDayOfGengo[MAX_GENGO + i][2] = NNumber.Parse(strDate[2]); // start day: 1
|
|
6089
|
+
UtilDateJpn.StartDayOfGengo[MAX_GENGO + i][3] = NNumber.Parse(strTok[1]); // days since January 1: 92
|
|
5057
6090
|
this.MaxGengo++;
|
|
5058
6091
|
}
|
|
5059
6092
|
}
|
|
@@ -5062,12 +6095,24 @@ class UtilDateJpn {
|
|
|
5062
6095
|
}
|
|
5063
6096
|
}
|
|
5064
6097
|
|
|
6098
|
+
/// <summary>JPN: IME support
|
|
6099
|
+
/// Utility Class for Input Method Editor
|
|
6100
|
+
/// </summary>
|
|
6101
|
+
/// <author> Toshiro Nakayoshi (MSJ)
|
|
6102
|
+
/// </author>
|
|
5065
6103
|
class UtilImeJpn {
|
|
5066
6104
|
static IME_ZEN_HIRAGANA_ROMAN = 1;
|
|
5067
|
-
static IME_FORCE_OFF = 15;
|
|
5068
|
-
|
|
6105
|
+
static IME_FORCE_OFF = 15; // if (ImeMode property == 0 and (picture has K0 or PIC_S)) or
|
|
6106
|
+
// (attribute is not alpha, unicode, nor blob), set IME_FORCE_OFF.
|
|
6107
|
+
static IME_DISABLE = 10; // to completely disable IME (even not allowing to change the mode)
|
|
5069
6108
|
ImeAutoOff = false;
|
|
5070
6109
|
StrImeRead = null;
|
|
6110
|
+
/// <summary> check if the IME mode is within valid range
|
|
6111
|
+
/// </summary>
|
|
6112
|
+
/// <param name="imeMode">(IME mode in Magic)
|
|
6113
|
+
/// </param>
|
|
6114
|
+
/// <returns> bool
|
|
6115
|
+
/// </returns>
|
|
5071
6116
|
isValid(imeMode) {
|
|
5072
6117
|
return (0 <= imeMode && imeMode <= 9) || imeMode === 15 || imeMode === 10;
|
|
5073
6118
|
}
|
|
@@ -5075,15 +6120,25 @@ class UtilImeJpn {
|
|
|
5075
6120
|
}
|
|
5076
6121
|
}
|
|
5077
6122
|
|
|
6123
|
+
/// <summary> a helper class for the parsing of the XML</summary>
|
|
5078
6124
|
class XmlParser {
|
|
5079
6125
|
static endOfNameChar = [' ', '>'];
|
|
5080
6126
|
_currIndex = 0;
|
|
5081
6127
|
_xmLdata = "";
|
|
5082
|
-
_history = new List();
|
|
6128
|
+
_history = new List(); // In order to allow recursive parsing we save prev data
|
|
6129
|
+
/// <summary>
|
|
6130
|
+
///
|
|
6131
|
+
/// </summary>
|
|
6132
|
+
/// <param name="data"></param>
|
|
5083
6133
|
constructor(data = NString.Empty) {
|
|
5084
6134
|
this.setXMLdata(data);
|
|
5085
6135
|
this.setCurrIndex(0);
|
|
5086
6136
|
}
|
|
6137
|
+
/// <summary> parse a string according to a set of delimiters and return the result in a vector</summary>
|
|
6138
|
+
/// <param name="str">the String which need be parted </param>
|
|
6139
|
+
/// <param name="delimiter">the delimiter which part different parts of str </param>
|
|
6140
|
+
/// <param name="isMagicXML">is needed tokenizer working on Magic XML, so the "=" sign will be delited in the end of every first token </param>
|
|
6141
|
+
/// <returns> tmpVector dynamically array, which consist tokens in every element, every token is String </returns>
|
|
5087
6142
|
static getTokens(str, delimiter, isMagicXML = true) {
|
|
5088
6143
|
let tokensVec = new List();
|
|
5089
6144
|
let token = null;
|
|
@@ -5092,17 +6147,22 @@ class XmlParser {
|
|
|
5092
6147
|
}
|
|
5093
6148
|
let strTok = str.split(delimiter.charAt(0));
|
|
5094
6149
|
for (let i = 0; i < strTok.length; i = i + 1) {
|
|
6150
|
+
// Split in C# creates a last empty string token if the source string ends with
|
|
6151
|
+
// the delimiter or if the string is empty (as opposed to Java that will ignore it)
|
|
6152
|
+
// therefore we have to break this loop if such case occurs.
|
|
5095
6153
|
if (isMagicXML && i === strTok.length - 1 && strTok.length % 2 === 1) {
|
|
5096
6154
|
break;
|
|
5097
6155
|
}
|
|
5098
6156
|
token = strTok[i];
|
|
5099
6157
|
if (isMagicXML) {
|
|
6158
|
+
// the 1st token in the pair comes with "=", remove it.
|
|
5100
6159
|
if (i % 2 === 0) {
|
|
5101
6160
|
token = token.trim();
|
|
5102
6161
|
if (token.endsWith("=")) {
|
|
5103
6162
|
token = token.substr(0, token.length - 1);
|
|
5104
6163
|
}
|
|
5105
6164
|
}
|
|
6165
|
+
// 2nd token in the pair can be an empty string, in that case set it to " ".
|
|
5106
6166
|
else if (token === "")
|
|
5107
6167
|
token = " ";
|
|
5108
6168
|
}
|
|
@@ -5112,6 +6172,11 @@ class XmlParser {
|
|
|
5112
6172
|
}
|
|
5113
6173
|
return tokensVec;
|
|
5114
6174
|
}
|
|
6175
|
+
/// <summary>unscape from:
|
|
6176
|
+
/// {"&",\\, \q, \o, \l, \g, \e, \\r, \\n}, to:
|
|
6177
|
+
/// {"&", \, ", ', <, >, =, \r, \n}
|
|
6178
|
+
/// <param name="str">String to be converted</param>
|
|
6179
|
+
/// <returns>unescaped string</returns>
|
|
5115
6180
|
static unescape(str) {
|
|
5116
6181
|
let unescapedString = new StringBuilder(str.length);
|
|
5117
6182
|
for (let i = 0; i < str.length; i++) {
|
|
@@ -5148,6 +6213,11 @@ class XmlParser {
|
|
|
5148
6213
|
}
|
|
5149
6214
|
return (unescapedString.ToString());
|
|
5150
6215
|
}
|
|
6216
|
+
/// <summary>escape from:
|
|
6217
|
+
/// {\, ", ', <, >, =, \r, \n}, to:
|
|
6218
|
+
/// {\\, \q, \0, \l, \g, \e, \\r, \\n}
|
|
6219
|
+
/// <param name="str">String to be converted</param>
|
|
6220
|
+
/// <returns>escaped string</returns>
|
|
5151
6221
|
static escape(str) {
|
|
5152
6222
|
let escapedString = new StringBuilder(str.length * 2);
|
|
5153
6223
|
for (let i = 0; i < str.length; i++) {
|
|
@@ -5183,15 +6253,23 @@ class XmlParser {
|
|
|
5183
6253
|
}
|
|
5184
6254
|
return (escapedString.ToString());
|
|
5185
6255
|
}
|
|
6256
|
+
/// <summary>
|
|
6257
|
+
/// here we only need to take care of "&" so that Sax parser will be able to handle url
|
|
6258
|
+
/// </summary>
|
|
6259
|
+
/// <param name="str"></param>
|
|
6260
|
+
/// <returns></returns>
|
|
5186
6261
|
static escapeUrl(str) {
|
|
5187
6262
|
return NString.Replace(str, "&", "&");
|
|
5188
6263
|
}
|
|
6264
|
+
/// <summary>get next tag name from current index in XML string</summary>
|
|
6265
|
+
/// <returns> next tag name </returns>
|
|
5189
6266
|
getNextTag() {
|
|
5190
6267
|
if (this._xmLdata.length - this._currIndex <= 1) {
|
|
5191
|
-
return null;
|
|
6268
|
+
return null; // end of XML string
|
|
5192
6269
|
}
|
|
5193
6270
|
for (let tmpIndx = this._currIndex + 1; tmpIndx < this._xmLdata.length; tmpIndx++) {
|
|
5194
6271
|
let tmpChar = this._xmLdata[tmpIndx];
|
|
6272
|
+
// a letter starts an element and ends with " ". "/" starts an element closing and ends with '>'.
|
|
5195
6273
|
if (NChar.IsLetter(tmpChar) || tmpChar === '/') {
|
|
5196
6274
|
let endOfTag = NString.IndexOfAny(this._xmLdata, XmlParser.endOfNameChar, tmpIndx, this._xmLdata.length - tmpIndx);
|
|
5197
6275
|
if (endOfTag === -1)
|
|
@@ -5202,25 +6280,34 @@ class XmlParser {
|
|
|
5202
6280
|
}
|
|
5203
6281
|
return null;
|
|
5204
6282
|
}
|
|
6283
|
+
/// <summary>Substring of XMLstring</summary>
|
|
6284
|
+
/// <returns> substring of XML string -from currIndex to endContext </returns>
|
|
5205
6285
|
getXMLsubstring(endContext) {
|
|
5206
6286
|
return this._xmLdata.substr(this._currIndex, endContext - this._currIndex);
|
|
5207
6287
|
}
|
|
6288
|
+
/// <summary>get current element value</summary>
|
|
6289
|
+
/// <returns> element's value </returns>
|
|
5208
6290
|
GetCurrentElementValue() {
|
|
5209
6291
|
this.setCurrIndex2EndOfTag();
|
|
5210
6292
|
let endContext = this.getXMLdata().indexOf(XMLConstants.TAG_OPEN, this.getCurrIndex());
|
|
6293
|
+
// read value of xml element
|
|
5211
6294
|
let value = this.getXMLsubstring(endContext);
|
|
5212
6295
|
this.setCurrIndex2EndOfTag();
|
|
5213
6296
|
return value;
|
|
5214
6297
|
}
|
|
6298
|
+
/// <summary>set current index (on parsing time) to the end of current tag</summary>
|
|
5215
6299
|
setCurrIndex2EndOfTag() {
|
|
5216
6300
|
this._currIndex = this._xmLdata.indexOf(XMLConstants.TAG_CLOSE, this._currIndex) + 1;
|
|
5217
6301
|
}
|
|
6302
|
+
/// <summary>get int from string at parsing time</summary>
|
|
5218
6303
|
static getInt(valueStr) {
|
|
5219
6304
|
return NNumber.Parse(valueStr.trim());
|
|
5220
6305
|
}
|
|
6306
|
+
/// <summary>get boolean from string at parsing time</summary>
|
|
5221
6307
|
static getBoolean(valueStr) {
|
|
5222
6308
|
return valueStr[0] === '1';
|
|
5223
6309
|
}
|
|
6310
|
+
/// <summary>get/set functions 4 XMLstring & currIndex, for parser</summary>
|
|
5224
6311
|
getCurrIndex() {
|
|
5225
6312
|
return this._currIndex;
|
|
5226
6313
|
}
|
|
@@ -5241,46 +6328,81 @@ class XmlParser {
|
|
|
5241
6328
|
this.setCurrIndex(0);
|
|
5242
6329
|
}
|
|
5243
6330
|
}
|
|
6331
|
+
/// <summary>
|
|
6332
|
+
/// prepare the parser to read from the newXmlString
|
|
6333
|
+
/// </summary>
|
|
6334
|
+
/// <param name="newXmlString"></param>
|
|
5244
6335
|
PrepareFormReadString(newXmlString) {
|
|
5245
6336
|
this.setXMLdata(newXmlString);
|
|
5246
6337
|
this.setCurrIndex(0);
|
|
5247
6338
|
}
|
|
6339
|
+
/// <summary> push the current parsing information into the history stack</summary>
|
|
5248
6340
|
push() {
|
|
5249
6341
|
this._history.push(this._currIndex);
|
|
5250
6342
|
this._history.push(this._xmLdata);
|
|
5251
6343
|
}
|
|
6344
|
+
/// <summary> restore the previous parsing information from the history stack</summary>
|
|
5252
6345
|
pop() {
|
|
5253
6346
|
let count = this._history.length;
|
|
5254
6347
|
this._xmLdata = this._history.get_Item(count - 1);
|
|
5255
6348
|
this._currIndex = this._history.get_Item(count - 2);
|
|
5256
6349
|
this._history.SetSize(count - 2);
|
|
5257
6350
|
}
|
|
6351
|
+
/// <summary>gets a table cache xml and set the xmlparser data and index accordingly</summary>
|
|
5258
6352
|
loadTableCacheData(data) {
|
|
5259
6353
|
this.setXMLdata(data);
|
|
5260
6354
|
this.setCurrIndex(0);
|
|
5261
6355
|
}
|
|
6356
|
+
/// <summary>
|
|
6357
|
+
/// Reads the XML from the element at the current position until the end of
|
|
6358
|
+
/// the element, returning the contents as a string. This allows deferring the
|
|
6359
|
+
/// processing of an element until the time is right to do so.<br/>
|
|
6360
|
+
/// The returned string contains the element tag itself. For example:<br/>
|
|
6361
|
+
/// - Assuming that the current element is 'element1', with 2 'innerElement' elements, the
|
|
6362
|
+
/// resulting string will look like this:<br/>
|
|
6363
|
+
/// <element1>
|
|
6364
|
+
/// <innerelement/>
|
|
6365
|
+
/// <innerelement/>
|
|
6366
|
+
/// </element1>
|
|
6367
|
+
///
|
|
6368
|
+
/// This makes the result valid for processing by this XML parser.
|
|
6369
|
+
/// </summary>
|
|
6370
|
+
/// <returns></returns>
|
|
5262
6371
|
ReadToEndOfCurrentElement() {
|
|
6372
|
+
// Get the current tag according to the value of _currIndex.
|
|
5263
6373
|
let currentTag = this.getNextTag();
|
|
5264
6374
|
let currentTagIndex = this._xmLdata.indexOf(XMLConstants.TAG_OPEN + currentTag, this.getCurrIndex());
|
|
6375
|
+
// Find the end of the element's block in the XML.
|
|
6376
|
+
// find next open tag
|
|
5265
6377
|
let nextOpenTagIndex = this._xmLdata.indexOf(XMLConstants.TAG_OPEN, currentTagIndex + 1);
|
|
5266
6378
|
if (nextOpenTagIndex === -1)
|
|
5267
6379
|
nextOpenTagIndex = this._xmLdata.length;
|
|
6380
|
+
// find a close tag BEFORE the next open tag
|
|
5268
6381
|
let elementEndIndex = NString.IndexOf(this._xmLdata, XMLConstants.TAG_TERM, this.getCurrIndex(), nextOpenTagIndex - this.getCurrIndex());
|
|
5269
6382
|
if (elementEndIndex === -1)
|
|
6383
|
+
// close tag was not found in range - we have inner elements, look for the full close tag
|
|
5270
6384
|
elementEndIndex = this._xmLdata.indexOf("/" + currentTag, this.getCurrIndex()) + currentTag.length + XMLConstants.TAG_TERM.length;
|
|
5271
6385
|
else
|
|
5272
6386
|
elementEndIndex = elementEndIndex + XMLConstants.TAG_TERM.length;
|
|
6387
|
+
// Copy the element data so it can be returned.
|
|
5273
6388
|
let elementBlock = this.getXMLsubstring(elementEndIndex);
|
|
6389
|
+
// Move the parser to the end of the element block.
|
|
5274
6390
|
this.setCurrIndex(elementEndIndex);
|
|
5275
6391
|
return elementBlock;
|
|
5276
6392
|
}
|
|
5277
6393
|
ReadContentOfCurrentElement() {
|
|
6394
|
+
// Get the current tag according to the value of _currIndex.
|
|
5278
6395
|
let currentTag = this.getNextTag();
|
|
6396
|
+
// Find the end of the element's block in the XML.
|
|
5279
6397
|
let elementEndIndex = this._xmLdata.indexOf("</" + currentTag + ">", this.getCurrIndex());
|
|
5280
6398
|
if (elementEndIndex === -1)
|
|
6399
|
+
// Can't find the end of the current element - either XML is faulty or the element is empty.
|
|
5281
6400
|
return NString.Empty;
|
|
6401
|
+
// Move to the end of the opening tag
|
|
5282
6402
|
this.setCurrIndex2EndOfTag();
|
|
6403
|
+
// Copy the content of the element (from the end of the opening tag to the beginning of the closing tag).
|
|
5283
6404
|
let elementBlock = this.getXMLsubstring(elementEndIndex);
|
|
6405
|
+
// Move the parser to the end of the element block.
|
|
5284
6406
|
this.setCurrIndex(elementEndIndex);
|
|
5285
6407
|
this.setCurrIndex2EndOfTag();
|
|
5286
6408
|
return elementBlock;
|
|
@@ -5291,9 +6413,29 @@ class XmlParser {
|
|
|
5291
6413
|
}
|
|
5292
6414
|
return this.ToString_1(headCharCount, tailCharCount);
|
|
5293
6415
|
}
|
|
6416
|
+
/// <summary>
|
|
6417
|
+
/// Generates a string that visualizes the XML parser state (e.g. for debug watch list.)<br/>
|
|
6418
|
+
/// The method will show the XML data, trimming it to 20 characters before the
|
|
6419
|
+
/// current position (_currIndex) and up to 50 characters after the current position.
|
|
6420
|
+
/// The current position itself will be marked with a marker that looks like:
|
|
6421
|
+
/// |-{current index}-| <br/>
|
|
6422
|
+
/// The marker will be placed immediately before _xmlData[_currIndex].
|
|
6423
|
+
/// </summary>
|
|
6424
|
+
/// <returns></returns>
|
|
5294
6425
|
ToString_0() {
|
|
5295
6426
|
return this.toString(20, 50);
|
|
5296
6427
|
}
|
|
6428
|
+
/// <summary>
|
|
6429
|
+
/// Generates a string that visualizes the XML parser state (e.g. for debug watch list.)<br/>
|
|
6430
|
+
/// The method will show the XML data, trimming it to headCharCount characters before the
|
|
6431
|
+
/// current position (_currIndex) and up to tailCharCount characters after the current position.
|
|
6432
|
+
/// The current position itself will be marked with a marker that looks like:
|
|
6433
|
+
/// |-{current index}-| <br/>
|
|
6434
|
+
/// The marker will be placed immediately before _xmlData[_currIndex].
|
|
6435
|
+
/// </summary>
|
|
6436
|
+
/// <param name="headCharCount">Number of characters to show before the current position marker.</param>
|
|
6437
|
+
/// <param name="tailCharCount">Number of characters to show after the current position marker.</param>
|
|
6438
|
+
/// <returns></returns>
|
|
5297
6439
|
ToString_1(headCharCount, tailCharCount) {
|
|
5298
6440
|
let markerPosition = Math.min(this._currIndex, this._xmLdata.length);
|
|
5299
6441
|
let segmentStartIndex = Math.max(0, markerPosition - headCharCount);
|
|
@@ -5320,5 +6462,13 @@ class XmlParser {
|
|
|
5320
6462
|
}
|
|
5321
6463
|
}
|
|
5322
6464
|
|
|
6465
|
+
/**
|
|
6466
|
+
* @file Automatically generated by barrelsby.
|
|
6467
|
+
*/
|
|
6468
|
+
|
|
6469
|
+
/**
|
|
6470
|
+
* Generated bundle index. Do not edit.
|
|
6471
|
+
*/
|
|
6472
|
+
|
|
5323
6473
|
export { APGDisplayMode, APGFormSize, APGInvokedFrom, APGMode, APGOption, APGType, Access, AlignmentTypeHori, AlignmentTypeVert, AllowedDirectionType, Area, AutoFit, Axis, Base64, BindingLevel, BlobContent, BlockTypes, BorderType, BottomPositionInterval, BoxDir, BrkLevel, BrkScope, BrkType, CacheStrategy, CallComOption, CallOperationMode, CallOsShow, CallUDPType, CallUdpConvention, CallWsStyle, CallbackType, CharacterSet, CheckExist, CheckboxMainStyle, ChoiceControlStyle, ChoiceUtils, ColumnUpdateStyle, CompTypes, ComponentItemType, Constants, ControlStyle, CtrlButtonType, CtrlButtonTypeGui, CtrlHotspotType, CtrlImageStyle, CtrlLineDirection, CtrlLineType, CtrlOleDisplayType, CtrlOleStoreType, CtrlTextType, DBHCache, DBHRowIdentifier, DataTranslation, DataViewHeaderType, DataViewOperationType, DataViewOutputType, DatabaseDataType, DatabaseDefinitionType, DatabaseFilters, DatabaseOperations, DataviewType, DateTimeUtils, DateUtil, DbDelUpdMode, DbOpen, DbShare, DbhKeyDirection, DbhKeyIndexType, DbhKeyMode, DbhKeyRangeMode, DbhSegmentDirection, DefaultMsgDetails, DisplayTextType, DitAttribute, DitType, DriverDB, DspInterface, EndMode, EngineDirect, EnterAnimation, ErrStrategy, ErrorClassific, ExeState, ExecOn, ExitAnimation, ExportType, FieldComAlloc, FieldComType, FieldViewModelType, FldStorage, FldStyle, FlowDirection, FlwMode, ForceExit, FormDelimiter, FormExpandType, FormOperationType, FormPage, FrameLayoutTypes, GradientStyle, HTML_2_STR, HelpCommand, HelpType, HtmlAlignmentType, HttpStatusCode, ImageEffects, InitialMode, InternalInterface, ItemMasks, JSON_Utils, KeyMode, KeyboardReturnKeys, KeyboardTypes, LDir, LineDirection, LineManipulationType, ListboxSelectionMode, LnkEval_Cond, LnkMode, LoadedValues, LockingStrategy, LogType, Logger, Logger_LogLevels, Logger_MessageDirection, LogicHeaderAction, LogicHeaderType, LogicLevel, LogicOperationType, LogicUnit, MagicProperties, MediaAccess, MediaFormat, MediaOrientation, MediaType, MgControlType, MgModelType, Misc, ModelAttGuiFrame, ModelAttMerge, ModelAttRichClientFrameSet, ModelAttrBrowser, ModelAttrField, ModelAttrFramesetForm, ModelAttrGui0, ModelAttrGui1, ModelAttrHelp, ModelAttrRichClient, ModelAttrText, ModelClass, MsgInterface, NotifyCollectionChangedAction, NullArithmetic, OSEnvironment, OSType, OpenEditDialog, Opr, Order, OrientationLock, PICInterface, PaperSize, PaperSizePdfDisabled, PaperSizePdfEnabled, PositionUsage, PrgExecPlace, Priority, Queue, RaiseAt, Randomizer, RangeMode, RbAppearance, Recursion, RemarkType, RequestInfo, Resident, RowType, Rtf, Rtf_ACTN, Rtf_ErrorRtf, Rtf_IDEST, Rtf_IPFN, Rtf_IPROP, Rtf_KWD, Rtf_PROP, Rtf_PROPTYPE, Rtf_RDS, Rtf_RIS, Rtf_RtfChar, Rtf_SYMBOL, SEQ_2_HTML, SEQ_2_STR, ScrollBarThumbType, SelprgMode, SideType, SliderType, SourceContextType, SplitPrimaryDisplay, SplitWindowType, StartupMode, Storage, StorageAttribute, StorageAttributeCheck, StorageAttributeType, StrUtil, SubformType, SyncExecutionHelper, TabControlTabsWidth, TabbingCycleType, TabbingOrderType, TableBehaviour, TableType, TaskFlow, TransBegin, TransMode, TriggerType, TrueFalseValues, UndoRedoAction, UniqueTskSort, UpdateMode, UseSQLCursor, UtilDateJpn, UtilImeJpn, UtilStrByteMode, ValType, VeeDiffUpdate, VeeMode, VeePartOfDataview, VerifyButtons, VerifyDisplay, VerifyImage, VerifyMode, ViewRefreshMode, ViewSelectType, WinCptn, WinHtmlType, WinUom, WindowPosition, WindowType, XMLConstants, XmlParser, YesNoValues };
|
|
5324
6474
|
//# sourceMappingURL=magic-xpa-utils.mjs.map
|