@magic-xpa/utils 4.1200.0-dev4120.21 → 4.1200.0-dev4120.213

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.
@@ -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
- this._codePageTable.set_Item(0, 1252);
886
- this._codePageTable.set_Item(128, 932);
887
- this._codePageTable.set_Item(129, 949);
888
- this._codePageTable.set_Item(134, 936);
889
- this._codePageTable.set_Item(136, 950);
890
- this._codePageTable.set_Item(161, 1253);
891
- this._codePageTable.set_Item(162, 1254);
892
- this._codePageTable.set_Item(177, 1255);
893
- this._codePageTable.set_Item(178, 1256);
894
- this._codePageTable.set_Item(186, 1257);
895
- this._codePageTable.set_Item(204, 1251);
896
- this._codePageTable.set_Item(222, 874);
897
- this._codePageTable.set_Item(238, 1250);
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
- static PIC_JY1 = PICInterface.PIC_LOCAL + 0;
2019
- static PIC_JY2 = PICInterface.PIC_LOCAL + 1;
2020
- static PIC_JY4 = PICInterface.PIC_LOCAL + 2;
2021
- static PIC_YJ = PICInterface.PIC_LOCAL + 3;
2022
- static PIC_BB = PICInterface.PIC_LOCAL + 4;
2023
- static PIC_J = PICInterface.PIC_LOCAL + 5;
2024
- static PIC_T = PICInterface.PIC_LOCAL + 6;
2025
- static PIC_G = PICInterface.PIC_LOCAL + 7;
2026
- static PIC_S = PICInterface.PIC_LOCAL + 8;
2027
- static PIC_MAX_OP = 31;
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
- static IME_DISABLE = 10;
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
+ /// {"&amp;",\\, \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, "&", "&amp;");
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