1 /*
2 * JLib - Jacob's Library.
3 * Copyright (C) 2003, 2004 Juan Carlos Seijo P�rez
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Juan Carlos Seijo P�rez
20 * jacob@mainreactor.net
21 */
22
23 /** Text string class.
24 * @file JString.h
25 * @author Juan Carlos Seijo P�rez
26 * @date 19/04/2003
27 * @version 0.0.1 - 19/04/2003 - First version.
28 */
29
30 #ifndef _JSTRING_INCLUDED
31 #define _JSTRING_INCLUDED
32
33 #include <JLib/Util/JTypes.h>
34 #include <stdio.h>
35 #include <stdarg.h>
36 #include <string.h>
37 #include <ctype.h>
38 #include <JLib/Util/JLoadSave.h>
39
40 class JString : public JLoadSave
41 {
42 friend bool operator==(const char *s1, const JString& s2);
43 friend bool operator==(const JString& s1, const char *s2);
44 friend bool operator!=(const char *s1, const JString& s2);
45 friend bool operator!=(const JString& s1, const char *s2);
46 friend bool operator>(const char *s1, const JString& s2);
47 friend bool operator<(const char *s1, const JString& s2);
48 friend bool operator>=(const char *s1, const JString& s2);
49 friend bool operator<=(const char *s1, const JString& s2);
50 //friend const JString operator+(const char *s1, const JString &s2);
51 friend const JString operator+(const JString &s1, const char *s2);
52 friend const JString operator+(const JString &s1, const JString &s2);
53
54 protected:
55 char *data; // Caracteres
56 u32 length; // Longitud
57
58 public:
59
60 /** Creates an empty string.
61 */
62 inline JString();
63
64 /** Creates a string that is a copy of the given string.
65 * @param s String to be copied.
66 */
67 inline JString(const char *s);
68
69 /** Creates a string from a substring of the given string.
70 * @param s String.
71 * @param start Start of the substring.
72 * @param end Of the substring, -1 for the string length.
73 */
74 inline JString(const JString& s, u32 start, u32 end = (u32)-1);
75
76 /** Creates a string from a substring of the given string.
77 * @param s String.
78 * @param start Start of the substring.
79 * @param end Of the substring, -1 for the string length.
80 */
81 inline JString(const char *s, u32 start, u32 end = (u32)-1);
82
83 /** Creates a string that is a copy of the given string.
84 * @param s String to be copied.
85 */
86 inline JString(const JString& s);
87
88 /** Destroys this string and frees the allocated resources.
89 */
90 inline virtual ~JString();
91
92 /** Clears the string.
93 */
94 inline void Clear();
95
96 /** Compares this string to another one.
97 * @param s Another string.
98 * @return <b>true</b> if they are equal, <b>false</b> otherwise.
99 */
100 inline bool Equals(const JString& s) const;
101
102 /** Compares this string to another one.
103 * @param s Another string.
104 * @return <b>true</b> if they are equal, <b>false</b> otherwise.
105 */
106 inline bool operator==(const JString& s) const;
107
108 /** Compares this string to another one.
109 * @param s Another string.
110 * @return 0 i they are equal, >0 if this string is ASCII-greater than the given, <0 if its ASCII-lower.
111 */
112 inline s32 CompareTo(const JString& s) const;
113
114 /** Compares this string to another one.
115 * @param s Another string.
116 * @return 0 i they are equal, >0 if this string is ASCII-greater than the given, <0 if its ASCII-lower.
117 */
118 inline s32 CompareTo(const char *s) const;
119
120 /** Test if this string is ASCII-greater than another.
121 * @param s Another string.
122 * @return <b>true</b> if so, <b>false</b> otherwise.
123 */
124 inline bool operator>(const JString& s) const;
125
126 /** Test if this string is ASCII-lower than another.
127 * @param s Another string.
128 * @return <b>true</b> if so, <b>false</b> otherwise.
129 */
130 inline bool operator<(const JString& s) const;
131
132 /** Test if this string is ASCII-greater or equal than another.
133 * @param s Another string.
134 * @return <b>true</b> if so, <b>false</b> otherwise.
135 */
136 inline bool operator>=(const JString& s) const;
137
138 /** Test if this string is ASCII-lower or equal than another.
139 * @param s Another string.
140 * @return <b>true</b> if so, <b>false</b> otherwise.
141 */
142 inline bool operator<=(const JString& s) const;
143
144 /** Compares this string to another one.
145 * @param s Another string.
146 * @return <b>true</b> if they are different, <b>false</b> otherwise.
147 */
148 inline bool operator!=(const JString& s) const;
149
150 /** Returns the char at the given pos.
151 * @param pos Index of the character to be retrieved.
152 */
153 inline char& operator[](s32 pos);
154
155 /** Assigns a copy of the given string to this one.
156 * @param s Another string.
157 */
158 inline void operator=(const char *s);
159
160 /** Assigns a copy of the given string to this one.
161 * @param s Another string.
162 */
163 inline void operator=(const JString &s);
164
165 /** Returns the internal character array.
166 * @return internal character array.
167 */
168 inline const char* Str() const;
169
170
171 /** Appends the given string to this one.
172 * @param s Another string.
173 */
174 inline void Append(const JString& s);
175
176 /** Appends the given string to this one.
177 * @param s Another string.
178 */
179 inline void Append(const char * s);
180
181 /** Appends the given string to this one.
182 * @param s Another string.
183 */
184 inline void operator+=(const JString& s);
185
186 /** Appends the given string to this one.
187 * @param s Another string.
188 */
189 inline void operator+=(const char *s);
190
191 /** Appends the given char to this string.
192 * @param c Character to append.
193 */
194 inline void Append(char c);
195
196 /** Appends the given char to this string.
197 * @param c Character to append.
198 */
199 inline void operator+=(char c);
200
201 /** Creates a string from a format string (as printf uses).
202 * @param fmt Format string.
203 * @param ... Format parameters.
204 * @return <b>true</b> if it could be formatted, <b>false</b> otherwise.
205 */
206 inline bool Format(const char *fmt, ...);
207
208 /** Converts this string to uppercase.
209 */
210 inline void Uppercase();
211
212 /** Converts this string to lowercase.
213 */
214 inline void Lowercase();
215
216 /** Searchs for the given character from the given position within the string.
217 * @param c Character to be found.
218 * @param from Index within the string where to start the search (inclusive).
219 * @return index of the character searched or -1 if it wasn't found.
220 */
221 inline s32 Find(char c, u32 from = 0);
222
223 /** Searchs for the last index of the given character from the given position within the string.
224 * @param c Character to be found.
225 * @param from Index within the string where to start the search (inclusive).
226 * @return index of the character searched or -1 if it wasn't found.
227 */
228 inline s32 FindLast(char c, u32 from = 0);
229
230 /** Searchs for the index of the given string from the given position within this string.
231 * @param str String to be found.
232 * @param from Index within the string where to start the search (inclusive).
233 * @return index of the character searched or -1 if it wasn't found.
234 */
235 inline s32 Find(const char *str, u32 from = 0);
236
237 /** Searchs for the last index of the given string from the given position within this string.
238 * @param str String to be found.
239 * @param from Index within the string where to start the search (inclusive).
240 * @return index of the character searched or -1 if it wasn't found.
241 */
242 inline s32 FindLast(const char *str, u32 from = 0);
243
244 /** Replaces pat with rep from the given index, max number of times within this string.
245 * @param pat Character to look for.
246 * @param rep Character to replace pat with.
247 * @param from Start index within the string where to start the search (inclusive).
248 * @param max Maximum number of replacements to be made.
249 * @return Number of replacements doen.
250 */
251 inline s32 Replace(const char pat, const char rep, u32 from = 0, u32 max = 0);
252
253 /** Replaces pat with rep from the given index, max number of times within this string.
254 * @param pat String pattern to look for.
255 * @param rep String replacement to replace pat with.
256 * @param from Start index within the string where to start the search (inclusive).
257 * @param max Maximum number of replacements to be made.
258 * @return Number of replacements doen.
259 */
260 inline s32 Replace(const char *pat, const char *rep, u32 from = 0, u32 max = 0);
261
262 /** Returns a string that is a substring of this string.
263 * @param start Substring start position.
264 * @param end Substring end position.
265 * @return Substring.
266 */
267 inline const JString Substring(u32 start, u32 end = (u32)-1);
268
269
270 /** Cast to const char * type.
271 * @return const char * string.
272 */
273 inline operator const char *() const {return data;} // Cast a cadena
274
275
276 /** Returns the length of this string.
277 * @return Length of this string.
278 */
Length()279 inline u32 Length() const {return length;} // Devuelve la longitud
280
281 // Lee la cadena de un fichero (longitud + cadena)
282
283 /** Reads a string from a JRW object (length in four bytes + characters)
284 * @param f JRW object.
285 * @return 0 if succeeded, 1 if I/O error, 2 if data integrity error.
286 */
287 inline u32 Load(JRW &f);
288
289 // Escribe la cadena a un fichero (longitud + cadena)
290
291 /** Writes a string to a JRW object (length in four bytes + characters)
292 * @param f JRW object.
293 * @return 0 if succeeded, 1 if I/O error, 2 if data integrity error.
294 */
295 inline u32 Save(JRW &f);
296 };
297
298 /** Test the equality of two strings.
299 * @param s1 First string.
300 * @param s1 Second string.
301 * @return <b>true</b> if they are equal, <b>false</b> otherwise.
302 */
303 inline bool operator==(const char *s1, const JString& s2)
304 {
305 return (strcmp(s1, s2.data) == 0);
306 }
307
308 /** Test the equality of two strings.
309 * @param s1 First string.
310 * @param s1 Second string.
311 * @return <b>true</b> if they are equal, <b>false</b> otherwise.
312 */
313 inline bool operator==(const JString& s1, const char *s2)
314 {
315 return (strcmp(s1.data, s2) == 0);
316 }
317
318 /** Test if the given strings are different.
319 * @param s1 First string.
320 * @param s1 Second string.
321 * @return <b>true</b> if so, <b>false</b> otherwise.
322 */
323 inline bool operator!=(const char *s1, const JString& s2)
324 {
325 return (strcmp(s1, s2.data) != 0);
326 }
327
328 /** Test if the given strings are different.
329 * @param s1 First string.
330 * @param s1 Second string.
331 * @return <b>true</b> if so, <b>false</b> otherwise.
332 */
333 inline bool operator!=(const JString& s1, const char *s2)
334 {
335 return (strcmp(s1.data, s2) != 0);
336 }
337
338 /** Test if the first string is ASCII-greater than the second.
339 * @param s1 First string.
340 * @param s1 Second string.
341 * @return <b>true</b> if so, <b>false</b> otherwise.
342 */
343 inline bool operator>(const char *s1, const JString& s2)
344 {
345 return (strcmp(s1, s2.data) > 0);
346 }
347
348 /** Test if the first string is ASCII-lower than the second.
349 * @param s1 First string.
350 * @param s1 Second string.
351 * @return <b>true</b> if so, <b>false</b> otherwise.
352 */
353 inline bool operator<(const char *s1, const JString& s2)
354 {
355 return (strcmp(s1, s2.data) < 0);
356 }
357
358 /** Test if the first string is ASCII-greater or equal than the second.
359 * @param s1 First string.
360 * @param s1 Second string.
361 * @return <b>true</b> if so, <b>false</b> otherwise.
362 */
363 inline bool operator>=(const char *s1, const JString& s2)
364 {
365 return (strcmp(s1, s2.data) >= 0);
366 }
367
368 /** Test if the first string is ASCII-lower or equal than the second.
369 * @param s1 First string.
370 * @param s1 Second string.
371 * @return <b>true</b> if so, <b>false</b> otherwise.
372 */
373 inline bool operator<=(const char *s1, const JString& s2)
374 {
375 return (strcmp(s1, s2.data) <= 0);
376 }
377
378 // Constructor
JString()379 JString::JString() : length(0)
380 {
381 data = new char[1];
382 data [0] = '\0';
383 }
384
385 // Constructor
JString(const char * s)386 JString::JString(const char *s)
387 {
388 if (s)
389 {
390 length = (u32)strlen(s);
391 data = new char[length + 1];
392 strcpy(data, s);
393 }
394 else
395 {
396 data = new char[1];
397 data [0] = '\0';
398 length = 0;
399 }
400 }
401
402 // Constructor de subcadena
JString(const JString & s,u32 start,u32 end)403 inline JString::JString(const JString& s, u32 start, u32 end)
404 {
405 if (end == (u32)-1)
406 end = s.Length();
407
408 if (start >= 0 && start < s.Length() && end > start && end <= s.Length())
409 {
410 length = end - start;
411 data = new char[length + 1];
412 strncpy(data, s.data + start, length);
413 data[length] = '\0';
414 }
415 else
416 {
417 data = new char[1];
418 data [0] = '\0';
419 length = 0;
420 }
421 }
422
423 // Constructor de subcadena
JString(const char * s,u32 start,u32 end)424 inline JString::JString(const char *s, u32 start, u32 end)
425 {
426 if (s)
427 {
428 u32 len = (u32)strlen(s);
429 if (end == (u32)-1)
430 end = len;
431
432 if (start >= 0 && start < len && end > start && end <= len)
433 {
434 length = end - start;
435 data = new char[length + 1];
436 strncpy(data, s + start, length);
437 data[length] = '\0';
438 }
439 else
440 {
441 data = new char[1];
442 data [0] = '\0';
443 length = 0;
444 }
445 }
446 else
447 {
448 data = new char[1];
449 data [0] = '\0';
450 length = 0;
451 }
452 }
453
454 // Constructor copia
JString(const JString & s)455 JString::JString(const JString &s)
456 {
457 length = s.length;
458 data = new char[length + 1];
459 strcpy(data, s.data);
460 }
461
462 // Destructor
~JString()463 JString::~JString()
464 {
465 delete[] data;
466 }
467
468 // Borra la cadena
Clear()469 inline void JString::Clear()
470 {
471 delete[] data;
472 data = new char[1];
473
474 // La cadena no tiene estado 'nulo', como mucho estar� vac�a
475 data [0] = '\0';
476 length = 0;
477 }
478
479 // �Son iguales?
Equals(const JString & s)480 inline bool JString::Equals(const JString& s) const
481 {
482 return (strcmp(data, s.data) == 0);
483 }
484
485 // �Son iguales?
486 inline bool JString::operator==(const JString& s) const
487 {
488 return (strcmp(data, s.data) == 0);
489 }
490
491 // Comparaci�n de cadenas
CompareTo(const JString & s)492 inline s32 JString::CompareTo(const JString &s) const
493 {
494 return (strcmp(data, s.data));
495 }
496
497 // Comparaci�n de cadenas
CompareTo(const char * s)498 inline s32 JString::CompareTo(const char *s) const
499 {
500 return (strcmp(data, s));
501 }
502
503 // �Es la primera mayor?
504 inline bool JString::operator>(const JString& s) const
505 {
506 return (strcmp(data, s.data) > 0);
507 }
508
509 // �Es la primera menor?
510 inline bool JString::operator<(const JString& s) const
511 {
512 return (strcmp(data, s.data) < 0);
513 }
514
515 // �Es la primera mayor o igual?
516 inline bool JString::operator>=(const JString& s) const
517 {
518 return (strcmp(data, s.data) >= 0);
519 }
520
521 // �Es la primera menor o igual?
522 inline bool JString::operator<=(const JString& s) const
523 {
524 return (strcmp(data, s.data) <= 0);
525 }
526
527 // �Son diferentes?
528 inline bool JString::operator!=(const JString& s) const
529 {
530 return (strcmp(data, s.data) != 0);
531 }
532
533 // Devuelve el caracter en la posici�n dada
534 inline char& JString::operator[](s32 pos)
535 {
536 return data[pos];
537 }
538
539 // Asignaci�n
540 inline void JString::operator=(const char *s)
541 {
542 if (s)
543 {
544 u32 len;
545
546 len = (u32)strlen(s);
547 if (len > length)
548 {
549 delete[] data;
550 data = new char[len + 1];
551 }
552
553 length = len;
554 strcpy(data, s);
555 }
556 else
557 {
558 delete[] data;
559 data = new char[1];
560 data[0] = '\0';
561 length = 0;
562 }
563 }
564
565 // Asignaci�n
566 inline void JString::operator=(const JString &s)
567 {
568 if (s.Length() > length)
569 {
570 delete[] data;
571 data = new char[s.length + 1];
572 }
573 length = s.length;
574 strcpy(data, s.data);
575 }
576
577 // Devuelve el array de caracteres
Str()578 inline const char* JString::Str() const
579 {
580 return ((const char*)data);
581 }
582
583 // Concatenaci�n de cadenas
Append(const JString & s)584 inline void JString::Append(const JString& s)
585 {
586 if (s.length)
587 {
588 u32 len;
589 len = s.length;
590
591 char *strAux = new char[length + len + 1];
592 strAux[0] = 0;
593
594 strcpy(strAux, data);
595 delete[] data;
596
597 // Evita contar los caracteres en strcat(), ya que sabemos la longitud
598 strcpy(strAux + length, s.data);
599
600 data = strAux;
601 length += len;
602 }
603 }
604
605 // Concatenaci�n de cadenas
Append(const char * s)606 inline void JString::Append(const char *s)
607 {
608 u32 len = (u32)strlen(s);
609
610 if (len)
611 {
612 char *strAux = new char[length + len + 1];
613 strAux[0] = 0;
614
615 strcpy(strAux, data);
616 delete[] data;
617
618 // Evita contar los caracteres en strcat(), ya que sabemos la longitud
619 strcpy(strAux + length, s);
620
621 data = strAux;
622 length += len;
623 }
624 }
625
626 // Concatenaci�n de cadenas
627 inline void JString::operator+=(const JString& s)
628 {
629 if (s.length)
630 {
631 u32 len;
632 len = s.length;
633
634 char *strAux = new char[length + len + 1];
635 strAux[0] = 0;
636
637 strcpy(strAux, data);
638
639 // Evita contar los caracteres en strcat(), ya que sabemos la longitud
640 strcpy(strAux + length, s.data);
641
642 delete[] data;
643 data = strAux;
644 length += len;
645 }
646 }
647
648 // Concatenaci�n de cadenas
649 inline void JString::operator+=(const char *s)
650 {
651 u32 len = (u32)strlen(s);
652
653 if (len)
654 {
655 char *strAux = new char[length + len + 1];
656 strAux[0] = 0;
657
658 strcpy(strAux, data);
659 delete[] data;
660
661 // Evita contar los caracteres en strcat(), ya que sabemos la longitud
662 strcpy(strAux + length, s);
663
664 data = strAux;
665 length += len;
666 }
667 }
668
669 // Concatena la cadena
670 inline const JString operator+(const JString &s1, const char *s2)
671 {
672 JString s(s1);
673 s.Append(s2);
674 return s;
675 }
676
677 inline const JString operator+(const JString &s1, const JString &s2)
678 {
679 JString s(s1);
680 s.Append(s2);
681 return s;
682 }
683
684 inline const JString operator+(const char *s1, const JString& s2)
685 {
686 JString s(s1);
687 s.Append(s2);
688 return s;
689 }
690
691 // Concatena un caracter
Append(char c)692 inline void JString::Append(char c)
693 {
694 if (c)
695 {
696 char *strAux = new char[length + 2];
697 strAux[0] = 0;
698
699 if (data)
700 {
701 strcpy(strAux, data);
702 delete[] data;
703 }
704
705 strAux[length] = c;
706 data = strAux;
707 length += 1;
708 strAux[length] = 0;
709 }
710 }
711
712 // Concatena un caracter
713 inline void JString::operator+=(char c)
714 {
715 if (c)
716 {
717 char *strAux = new char[length + 2];
718 strAux[0] = 0;
719
720 if (data)
721 {
722 strcpy(strAux, data);
723 delete[] data;
724 }
725
726 strAux[length] = c;
727 data = strAux;
728 length += 1;
729 strAux[length] = 0;
730 }
731 }
732
733 // Formatea la cadena tipo printf
Format(const char * fmt,...)734 inline bool JString::Format(const char *fmt, ...)
735 {
736 int n, size = 0;
737 char *p = 0;
738
739 va_list ap;
740
741 while (1)
742 {
743 // Intenta escribir hasta que la escritura tenga �xito
744 va_start(ap, fmt);
745 n = vsnprintf (p, size, fmt, ap);
746 va_end(ap);
747
748 // Si tiene �xito, sale del bucle para asignar la nueva cadena
749 if (n > -1 && n < size)
750 break;
751
752 // Si no, intenta determinar el espacio necesario
753 if (n > -1) // Esto ocurre con glibc >= 2.1
754 {
755 // Justo lo necesario
756 size = n+1;
757 }
758 else // Esto ocurre con glibc < 2.1
759 {
760 // Incrementa el tama�o
761 size += (64 + size);
762 }
763
764 if (p)
765 {
766 delete[] p;
767 }
768
769 if ((p = new char[size]) == 0)
770 {
771 // No hay memoria
772 return false;
773 }
774 }
775
776 delete[] data;
777 data = p;
778 length = size - 1;
779
780 return true;
781 }
782
783 // Convierte a may�sculas
Uppercase()784 void JString::Uppercase()
785 {
786 char *p = data;
787 while (*p)
788 {
789 *p = toupper(*p);
790 ++p;
791 }
792 }
793
794 // Convierte a min�sculas
Lowercase()795 void JString::Lowercase()
796 {
797 char *p = data;
798 while (*p)
799 {
800 *p = tolower(*p);
801 ++p;
802 }
803 }
804
805 // Devuelve la posici�n del primer car�cter c desde el comienzo de la cadena
Find(char c,u32 from)806 s32 JString::Find(char c, u32 from)
807 {
808 if (from >= length)
809 {
810 return -1;
811 }
812
813 char *p;
814 if ((p = strchr(data + from, c)))
815 {
816 if (p > data)
817 return p - data;
818 else
819 return data - p;
820 }
821
822 return -1;
823 }
824
825 // Devuelve la posici�n del �ltimo car�cter c desde el comienzo de la cadena
FindLast(char c,u32 from)826 s32 JString::FindLast(char c, u32 from)
827 {
828 if (from >= length)
829 {
830 return -1;
831 }
832
833 char *p;
834 if ((p = strrchr(data + from, c)))
835 {
836 if (p > data)
837 return p - data;
838 else
839 return data - p;
840 }
841
842 return -1;
843 }
844
845 // Devuelve la posici�n de la cadena str desde el comienzo de la cadena
Find(const char * str,u32 from)846 s32 JString::Find(const char *str, u32 from)
847 {
848 if (from >= length)
849 {
850 return -1;
851 }
852
853 char *p;
854 if ((p = strstr(data + from, str)))
855 {
856 if (p > data)
857 return p - data;
858 else
859 return data - p;
860 }
861
862 return -1;
863 }
864
865 // Reemplaza las ocurrencias 'pat' con 'rep' desde 'from', hasta 'max' veces
Replace(const char pat,const char rep,u32 from,u32 max)866 s32 JString::Replace(const char pat, const char rep, u32 from, u32 max)
867 {
868 s32 i, num = 0;
869
870 while ((i = Find(pat, from)) > -1)
871 {
872 data[i] = rep;
873 ++num;
874 }
875
876 return num;
877 }
878
879 // Reemplaza las ocurrencias 'pat' con 'rep' desde 'from', hasta 'max' veces
Replace(const char * pat,const char * rep,u32 from,u32 max)880 s32 JString::Replace(const char *pat, const char *rep, u32 from, u32 max)
881 {
882 s32 cur, patLen, repLen, num = 0;
883
884 patLen = strlen(pat);
885 repLen = strlen(rep);
886
887 if (patLen == repLen)
888 {
889 // Caso especial, esto se hace m�s r�pido
890 while ((cur = Find(pat, from)) > -1)
891 {
892 strncpy(data + cur, rep, repLen);
893 ++num;
894 from = cur + patLen;
895 }
896
897 return num;
898 }
899
900 JString str(*this, 0, from);
901
902 while ((cur = Find(pat, from)) > -1)
903 {
904 str += Substring(from, cur);
905 str += rep;
906 ++num;
907 from = cur + patLen;
908 }
909
910 str += Substring(from);
911 *this = str;
912
913 return num;
914 }
915
916 // Devuelve una subcadena de esta cadena
Substring(u32 start,u32 end)917 inline const JString JString::Substring(u32 start, u32 end)
918 {
919 return JString(*this, start, end);
920 }
921
922 // Lee la cadena de un fichero (longitud + cadena)
Load(JRW & f)923 inline u32 JString::Load(JRW &f)
924 {
925 f.ReadLE32(&length);
926 delete[] data;
927 data = new char[length + 1];
928 f.Read(data, length);
929 data[length] = 0;
930
931 return 0;
932 }
933
934 // Escribe la cadena a un fichero (longitud + cadena)
Save(JRW & f)935 inline u32 JString::Save(JRW &f)
936 {
937 f.WriteLE32(&length);
938 f.Write(data, length);
939
940 return 0;
941 }
942
943 #endif // _JSTRING_INCLUDED
944