string.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**
  2. * This file is part of Threema Web.
  3. *
  4. * Threema Web is free software: you can redistribute it and/or modify it
  5. * under the terms of the GNU Affero General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or (at
  7. * your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Affero General Public License
  15. * along with Threema Web. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. export class StringService {
  18. public byteChunk(str: string, byteLength: number, offset: number = null): string[] {
  19. const chars = [...str];
  20. const chunks = [''];
  21. let currentChunkSize = 0;
  22. let chunkIndex = 0;
  23. const offsetChars = [' ', '\r', '\n', '\t', '.'];
  24. let lastSeparator = -1;
  25. chars.forEach ((charString: string) => {
  26. const length = Buffer.byteLength(charString, 'utf8');
  27. if (offset !== null) {
  28. if (offsetChars.indexOf(charString) > -1) {
  29. lastSeparator = currentChunkSize + 1;
  30. }
  31. }
  32. if (currentChunkSize + length > byteLength) {
  33. let appendNewChunk = true;
  34. if (lastSeparator > -1) {
  35. // check if separator in offset
  36. if (currentChunkSize - lastSeparator <= offset
  37. && chunks.length >= 1) {
  38. // create new chunk with existing data
  39. chunks.push(chunks[chunkIndex].substr(lastSeparator).trim());
  40. // modify old chunk
  41. chunks[chunkIndex] = chunks[chunkIndex].substr(0, lastSeparator).trim();
  42. appendNewChunk = false;
  43. currentChunkSize -= lastSeparator;
  44. chunkIndex++;
  45. lastSeparator = -1;
  46. }
  47. }
  48. if (appendNewChunk) {
  49. chunkIndex++;
  50. currentChunkSize = 0;
  51. // create a new chunk
  52. chunks.push('');
  53. }
  54. }
  55. chunks[chunkIndex] = (chunks[chunkIndex] + charString);
  56. currentChunkSize += length;
  57. });
  58. return chunks;
  59. }
  60. public getWord(input: string, pos: number, additionalSeparators: string[] = null): threema.WordResult {
  61. const result = {
  62. word: null,
  63. realLength: 0,
  64. };
  65. if (input !== null && input.length > 0) {
  66. const chars = [...input];
  67. let charFound = false;
  68. const realPos = Math.min(pos, chars.length) - 1;
  69. if (realPos > 0) {
  70. const wordChars = new Array(realPos);
  71. for (let n = realPos; n >= 0; n--) {
  72. const realChar = chars[n].trim();
  73. if (realChar === '') {
  74. // Abort
  75. if (charFound === false) {
  76. result.realLength++;
  77. continue;
  78. } else {
  79. break;
  80. }
  81. } else if (additionalSeparators !== null) {
  82. if (additionalSeparators.indexOf(chars[n]) > -1) {
  83. // append char
  84. result.realLength++;
  85. wordChars[n] = realChar;
  86. if (charFound === false) {
  87. continue;
  88. } else {
  89. break;
  90. }
  91. }
  92. }
  93. result.realLength++;
  94. wordChars[n] = realChar;
  95. charFound = true;
  96. }
  97. result.word = wordChars.join('');
  98. }
  99. }
  100. return result;
  101. }
  102. }