001/****************************************************************************
002 * Copyright/Copyleft:
003 *
004 * For this source the LGPL Lesser General Public License,
005 * published by the Free Software Foundation is valid.
006 * It means:
007 * 1) You can use this source without any restriction for any desired purpose.
008 * 2) You can redistribute copies of this source to everybody.
009 * 3) Every user of this source, also the user of redistribute copies
010 *    with or without payment, must accept this license for further using.
011 * 4) But the LPGL is not appropriate for a whole software product,
012 *    if this source is only a part of them. It means, the user
013 *    must publish this part of source,
014 *    but don't need to publish the whole source of the own product.
015 * 5) You can study and modify (improve) this source
016 *    for own using or for redistribution, but you have to license the
017 *    modified sources likewise under this LGPL Lesser General Public License.
018 *    You mustn't delete this Copyright/Copyleft inscription in this source file.
019 *
020 * @author Hartmut Schorrig: hartmut.schorrig@vishia.de, www.vishia.org
021 * @version 0.93 2011-01-05  (year-month-day)
022 *******************************************************************************/ 
023package org.vishia.java2C.test;
024
025//import java.io.File;
026import java.io.File;
027import java.io.FileNotFoundException;
028import java.io.FileOutputStream;
029import java.io.IOException;
030import java.io.OutputStream;
031import java.text.SimpleDateFormat;
032import java.util.Date;
033
034/**This class contains some examples to test String functionality.
035 * <br><br>
036 * <b>Situation for String preparation in C:</b>
037 * A String preparation in C in embedded applications is often necessary in situations of error reporting
038 * or output of states. The typically choice is usage of <code>sprintf(buffer, "text-format", arguments, ...)</code>.
039 * This approach have some risks which may produce errors in runtime:
040 * <ul>
041 * <li>The type of arguments should be matched to the designation of parts in text-format. 
042 *   An error of detail is possible, the user should programmed carefully. The compiler doesn't detect errors.
043 * <li>If the size of <code>buffer</code> is less, an overflow isn't detect. An overflow may occur, if a value is unexpected, 
044 *   and the numbering formating produce a less longer output. <code>char*</code>-Arguments are critically too,
045 *   because there length may be rate faulty because that is depending of outer code.
046 * <li>If a <code>char*</code> is used as argument, and the pointer is faulty, an unexpected buffer overflow 
047 *   may be produced in the <code>sprintf</code>.
048 * <li>The buffer should be provided by the users environment. If the buffer is defined in Stack, 
049 *   and the String is produced and used temporary, it's okay. But a software correction in calling routines,
050 *   which doesn't uses to pointer to the buffer for copy, instead save the pointer, are not detected at compile time.
051 * </ul>
052 * The usage of <code>sprintf(...)</code> in C should implement carefully, it is sensitive. 
053 * <br><br>
054 * The usage of Strings in Java is some more unsensitive and simple. But the standard-Java uses the system of garbage collection
055 * to accomplish this requirements. This may not able to use in all situations of embedded control-software.
056 * The preparation of Strings may realized in Java in three ways:
057 * <ul>
058 * <li>Simple concatenations of Strings just like <code>String result = "value=" + value</code>. This variant needs a buffer,
059 *   which is allocated in the heap and managed by garbage collection.
060 * <li>Usage of a StringBuffer or StringBuilder. 
061 *   The adequate code is <code>result.setLength(0); result.append("value=").append(value);</code>
062 *   The StringBuffer-Object can be allocated as an element of any class, the memory space is allocated
063 *   in the instance including the buffer itself, hence no dynamic memory allocation is necessary.
064 * <li>Java knows a adequate to <code>sprintf</code> approach using <code>String.format(formatString, arguments ...)</code>. 
065 *   This method is some more safety as the C-<code>sprintf</code>, because a buffer overflow is detected and the types
066 *   of arguments are well known. But the method works with dynamic memory only.
067 * </ul>
068 * If embedded software written in Java and translated to C shouldn't used dynamic memory and garbage collection,
069 * the second approach using <code>StringBuffer</code> is proper. The <code>StringBuffer</code> can be defined
070 * as embedded Buffer with a fix length inside a class type. Examples using such a fix <code>StringBuffer</code>
071 * allocated in the Stack too are test and shown in the method {@link #testStringBuffer()}.
072 * <br><br>
073 * If the garbage collector is able to use, a String concatenation is able to use. The user doesn't need to
074 * provide any buffers.      
075 *
076 */
077public class TestString
078{
079  
080  
081  /**A reference to another struct. */
082  StringBuilder buffer1;
083  
084  /**A reference to another struct, but without need of garbage collection. @java2c=noGC. */
085  final StringBuffer bufferInit;
086  
087  
088  final StringBuilder bufferEmbedded = new StringBuilder(1000);
089
090  final static String empty = "                                     ";
091  
092  /**A reference to a String in memory. The String may be a reference to a constant String 
093   * or to the content inside a StringBuffer. see usages. */
094  String stringRef;
095  
096  /**Creates an embedded instance as StringBuffer with immediate space for the chars. */
097  private final StringBuffer sbufferFix = new StringBuffer(250);
098  
099  private final String[] strArray = new String[10];
100  
101  private String[] strArray2;
102  
103  private char[] charArray = new char[10];
104  
105  TestString(StringBuffer bufferInit)
106  {
107    buffer1 = new StringBuilder(122);
108    this.bufferInit = bufferInit;    
109  }
110  
111  /**Help method which processes a String. */
112  static int processString(String str)
113  { return str.length();
114  }
115  
116  
117  
118  /**Examples for String concatenations.
119   * <br><br>
120   * This method tests and shows a concatenation of String without using dynamic memory.
121   * it uses Stack instances only, because all Strings are used temporary.
122   * This patterns are able to use in a system without any dynamically memory,
123   * at example for String preparing in an interrupt routine of embedded control. 
124   * <br><br>
125   * See comments on the code line of java source-code in comparision with the produced C-code 
126   * in <a href="../xxx">xxx</a>
127   */
128  void testStringConcatenationInStack(int value, float fValue)
129  { /**Because it is set 'java2c=StringBuilderInStack=100'. The concatenation will be done
130     * in an buffer created in Stack instead in an new allocated buffer in heap.
131     * The operation toString builds a reference to this stack instance anyway.
132     * The stack variable ssn refers the string in stack.
133     * Because it is set 'java2c=toStringNonPersist'. The StringBuilderJc in stack
134     * will not designated as 'freezed' for further usage. That are another aspect.
135     * The result is a temporary non persistent String in stack.
136     * @java2c=toStringNonPersist, StringBuilderInStack=100.
137     */
138        String ssn = "test-Concatenation " + value + ", float " + fValue;
139        /**This String can be used as input for any method, which processed the String
140         * but not references the original source-string. Most of routines do so.
141         */
142        processString(ssn);
143    /**
144     * The next statement reuses the buffer and changes the String. The reuse is done
145     * only because the same buffer in stack is dedicated with 'java2c=StringBuilderInStack',
146     * not derived from the previous used buffer. 
147     * It is another way of controlling as on operation '+='.
148     * 
149     * @java2c=toStringNonPersist, StringBuilderInStack=100. */
150        ssn = "second " + value;
151        processString(ssn);
152      /**
153     * The next statement appends something on the String. It is a typically operation
154     * while preparing Strings in more as one line. The buffer can be enlarged, 
155     * because the last operation for assign ssn was designated with 'java2c=toStringNonPersist'.
156     * Therefore the Buffer is not dedicated as 'freezed'. Which buffer is used? 
157     * It is the buffer, which is used for the previous preparation of the String.  
158     * The designation with 'java2c=toStringNonPersist' would have an effect 
159     * for further '+='-operations with this variable. In this example it has an effect
160     * only for further usage of the same buffer. It is possible to use the buffer.
161     * The enlarging-operation of the buffer (call of append) doesn't depend on that designation.
162     * @java2c=toStringNonPersist.
163     */
164        ssn += ", third";
165    /**
166     * This String should be built in an own buffer, because ssn is used for concatenation too. 
167     * but it may be @java2c=toStringNonPersist.*/
168        //ssn = "forth, " + ssn;
169    /**Use it: */
170        processString(ssn);
171        
172        int pos = ssn.indexOf('.');
173        if(pos < 0 ){
174                pos = 0;
175        }
176        { int pos2 = ssn.indexOf("third");
177          if(pos2 >=0){
178                pos += pos2;
179          }
180        }
181  }
182
183  
184  
185  
186  
187  /**Examples for String concatenations.
188   * <br><br>
189   * This method tests and shows a concatenation of String using garbage collection. 
190   * <br><br>
191   * <b>First example: concatenation and assignment</b>: The Java-code is:
192   * <pre class="Java">
193    String ss = "test " + value + " miles";
194    System.out.println(ss);
195    this.stringRef = ss;
196   * </pre>
197   * A String will be built stack-locally with concatenation. Than this String will be used 
198   * first as parameter for a method, than it is saved in the instance (persistent). 
199   * In C it is translated to:
200   * <pre>
201    StringJc ss;
202      ...
203    StringBufferJc *_tempString1_1=null; //J2C: temporary Stringbuffer for String concatenation
204      ...
205    ss = 
206      ( _tempString1_1 = new_StringBufferJc(-1, _thCxt)
207      , setTemporary_StringBufferJc(_tempString1_1)
208      , append_z_StringBufferJc(_tempString1_1, "test ", _thCxt)
209      , append_I_StringBufferJc(_tempString1_1, value, _thCxt)
210      , append_z_StringBufferJc(_tempString1_1, " miles", _thCxt)
211      , toString_StringBufferJc(_tempString1_1)
212      );
213    println_s_PrintStreamJc(REFJc(out_SystemJc), ss, _thCxt);
214    set_StringJc(&(ythis->stringRef), ss);
215      ....
216    activateGC_ObjectJc(&_tempString1_1->base.object, null, _thCxt);
217   * </pre>
218   * The following principles are used:
219   * <ul>
220   * <li>Adequate to the implementation in Java the concatenation uses a StringBuffer internally 
221   *   for the concatenation expression. The StringBuffer is allocated in heap 
222   *   calling <code>new_StringBufferJc(...)</code>. 
223   * <li>There is a possibility of working without allocated memory
224   *   for such embedded software systems, which should not use any dynamic memory and garbage collection:
225   *   The new StringBuffer can be a thread-local existing buffer. In this case only one concatenation of Strings
226   *   is able to use per Thread. The content of the produced String should be copied in the next instruction.
227   *   That is a restriction of programming, but it allows to work without garbage collection. Commonly
228   *   a garbage collector and dynamic memory should be able to use. The CRuntimeJavalike-Library provides a solution
229   *   using blocks with equal size (<code>BlockHeap</code>).
230   * <li>The StringBuffer is dedicated as temporary. The reference to the StringBuffer isn't known
231   *   in the users programming. Therefore the user can't work with it. Only the result String <code>ss</code>
232   *   uses the buffer.
233   * <li>All concatenations are implemented using <code>append...(...)</code>-methods.
234   * <li>The last operation with the StringBuffer is the call of <code>toString(...)</code> to get the String.
235   *   A String instance contains only the pointer to the text itself (<code>char* in Buffer</code>), 
236   *   the number of chars and a few special bits. That are at maximum 2 Registers with 32 bit, 
237   *   compendious in a <code>struct StringJc</code> and defined operation-system-depend 
238   *   in a <code>struct OS_ValuePtr</code> to support optimal memory and register usage for the target platform.
239   * <li>The String is stored and taken as parameter as value, never as a reference (not as <code>StringJc*</code>).
240   *   The method <code>println(...)</code> got the String as value.
241   * <li>To store a String in class variables (persistent), the method <code>setref_StringJc(...)</code> is used.
242   *   This method sets the backward reference to the memory block of the block-heap, which contains
243   *   the pointer to the text and sets the index of backward reference in the reference in class (<code>ythis->stringRef</code>)
244   *   With this operation the block is referenced now.
245   * <li>The temporary StringBufferJc is designated to managed by Garbage collection at least, before finish the routine.
246   *   Because the String is referenced in this example, the garbage collector will test the reference.
247   *   Elsewhere the block will be freed from garbage collector. That is typically if a String is prepared
248   *   and used only locally.
249   * </ul>    
250   */
251  void testStringConcatenationWithTemps(int value, float fValue)
252  { String ssn = "test " + value + " miles";
253          processString(ssn);
254    //System.out.println(ssn);
255    //this.stringRef = ssn;
256    ssn = "second " + value;
257    ssn += ", third";
258    ssn = "forth, " + ssn;
259    //System.out.println(ssn);
260        processString(ssn);
261    /**A buffer in stack: @java2c=stackInstance. */
262    //StringBuffer buffer = new StringBuffer(40);
263    //buffer.append("buffer:");
264    //ssn = buffer + ssn;
265    /**Test substring, indexof. */
266    //int pos = ssn.substring(4).indexOf('i');
267
268  }
269 
270  void testStringConcatenationUsingBuilder(int value)
271  { /**A buffer in stack: @java2c=stackInstance. */
272    StringBuffer buffer = new StringBuffer(40);
273    buffer.append("buffer:");
274    buffer.append(123); 
275    String ssn = buffer.toString();
276    /**Test substring, indexof. */
277    int pos = ssn.substring(4).indexOf('i');
278
279  }
280 
281  
282  
283  String testStringParameter(String s1, String s2)
284  { /** @java2c=StringBuilderInThreadCxt.*/
285    String ret = s1 + " to " + s2;
286    return ret;
287        
288  }
289  
290  
291  void testStringParameter()
292  { 
293        /**@java2c=stackInstance. */
294        Date dateFrom = new Date();
295        /**@java2c=stackInstance. */
296        Date dateTo = new Date(dateFrom.getTime() + 3600000);
297        /**@java2c=stackInstance. */
298        SimpleDateFormat dateFormat = new SimpleDateFormat("yy_MMM_dd_HHmmss_SS");
299        String sResult= testStringParameter(dateFormat.format(dateFrom), dateFormat.format(dateTo));
300    System.out.println(sResult);
301  }
302  
303  
304  
305  /**
306   * @param value
307   * @param fValue
308   * @return
309   * @java2c=return-new.
310   */
311  private String testFormat(int value, float fValue)
312  {
313        /**@java2c=toStringNonPersist. */
314        String result = String.format("format intVal=%d floatVal=%3.4f test", value, fValue);
315        processString(result);
316        return result; 
317  }
318  
319  
320  private void testReplace()
321  {
322        String src = "C:\\directory/myFolder/myFile.x";
323        String dst = src.replace('\\', '/');
324        buffer1.setLength(0);
325        buffer1.append(src.replace('\\', '/'));
326        buffer1.setLength(0); buffer1.append(src);
327        /**@java2c=toStringNonPersist. The replacement should done in the buffer itself. */
328        src = buffer1.toString();
329        /**This expression copies the replaced text in the buffer1.
330         * It is the same, if the original text is copied and than replaced in the buffer.
331         * But Java doesn't know a simple char replacement in a StringBuilder.
332         * The Java2C translates to ...TODO
333         */
334        buffer1.replace(0, buffer1.length(), src.replace('\\', '/'));
335  
336  }
337
338  
339  private void testInsertCharArray()
340  { buffer1.setLength(0);
341    buffer1.append("1234");
342    charArray[0] = 'A';
343    charArray[1] = 'Q';
344    charArray[2] = 'X' ;
345    buffer1.insert(2, charArray, 1,2);
346    /**@java2c=toStringNonPersist. */
347    assert(buffer1.toString().equals("12QX34"));
348  }
349  
350  
351  
352  public String toString()
353  { return stringRef;
354  }
355  
356
357  void testGarbageString()
358  {
359    stringRef = "other String";
360    
361  }
362  
363  /**Example for StringBuffer usage.
364   * <br><br>
365   * The StringBuffer {@link #bufferEmbedded} is created as an embedded part of this class structure.
366   * It has a fix length, the text is part of the instance, using immediate buffer.
367   * The usage of such an buffer for string preparing is a proper decision if no dynamic memory
368   * should be used, and the user has the controlling and responsibility about the String instances.
369   * <br>
370   * The Java-code to prepare a string is:
371   * <pre class="Java">
372    bufferEmbedded.setLength(0);
373    bufferEmbedded.append("content:").append(stringRef);
374    System.out.println(bufferEmbedded);
375    String s1 = bufferEmbedded.toString();
376    System.out.println(s1);
377    this.stringRef = s1;
378   * </pre>
379   * In this example the buffer is cleared, than a content is appended. The Result is used to print out
380   * with given StringBuffer. Than the buffer-content is stored in a String calling the <code>toString(...)</code>-method.
381   * That result is used to print out too. At last the String is stored in a class variable.
382   * <br><br>
383   * The resulting C-code is:
384   * <pre>
385    StringJc s1;
386    ...
387    setLength_StringBufferJc(& (ythis->bufferEmbedded.sb), 0, _thCxt);
388      ( append_s_StringBufferJc(& (ythis->bufferEmbedded.sb), s0_StringJc("content:"), _thCxt)
389      , append_s_StringBufferJc(& (ythis->bufferEmbedded.sb), ythis->stringRef, _thCxt)
390      );
391    println_sb_PrintStreamJc(REFJc(out_SystemJc), & (ythis->bufferEmbedded.sb), _thCxt);
392    s1 = toString_StringBufferJc(& (ythis->bufferEmbedded.sb));
393    println_s_PrintStreamJc(REFJc(out_SystemJc), s1, _thCxt);
394    set_StringJc(&(ythis->stringRef), s1);
395   * </pre>
396   * The C-code follows the Java-code. The concatenation of append is resolved like described in 
397   * {@link TestAllConcepts#checkConcatenationSimple()}.
398   * <br><br>
399   * 
400   */
401  void testStringBuffer()
402  { bufferEmbedded.setLength(0);
403    bufferEmbedded.append("content:").append(stringRef);
404    System.out.println(bufferEmbedded);
405    /**@java2c=toStringNonPersist. */
406    String s1 = bufferEmbedded.toString();
407    System.out.println(s1);
408    this.stringRef = s1;
409     /**The StringBuffer is allocated in BlockHeapJc, containing the max possible buffer size, 
410     * this size is limited in C implementation. */
411    StringBuffer sb = new StringBuffer();
412    sb.setLength(0);
413    sb.append("test ").append(5).append(" Stringbuffer");
414    System.out.println(sb);
415    /**@java2c=toStringNonPersist. */
416    /**The toString() is only used in the thread immediately. 
417     * Therefore: @java2c=toStringNonPersist. */
418    String ss = sb.toString();
419    System.out.println(ss);
420  }
421
422  
423  
424  
425  
426  
427  
428  
429  
430  
431  /**
432   * <b>Persistence of Strings</b> 
433   * The method <code>toString(...)</code> needs to turn one's attentions: Generally, a String is constant.
434   * Because the buffer content of a StringBuffer may be changed after calling <code>toString(...)</code>, 
435   * the text have to be copied to an independent buffer. The Java implementation do so. 
436   * But this is an additional effort regarding typically applications in the fast real-time embedded world. 
437   * Mostly the StringBuffer isn't change immediately, rather the got String is processed and thereby copied 
438   * in the current thread like shown in the example {@link #testStringBuffer()}.
439   * <br><br>
440   * Thats why some methods <code>toString...(...)</code> in the CRuntimeJavalike-Library have two modes:
441   * <ul>
442   * <li>Compatible-mode with Java, but with more effort: <code>toString...(...)</code> creates an extra
443   *   buffer for the returned String in heap.
444   * <li>Small-effort-mode: <code>toString_StringBufferJc</code> references the String in the 
445   *   StringBuffer-instance, no extra buffer is used. <code>toString...(...)</code> from other classes
446   *   uses the thread-local Buffer, it can be used only one for one toString-result in thread, the result is to copy outside.
447   *   This mode saves calculation time and prevent an extra memory allocation. 
448   *   In this case the String is dedicated with a bit <code>mNonPersists__StringJc</code>.
449   * </ul>    
450   * Both modes are able to choice. The default is the compatible mode with Java. A method which uses 
451   * the small-effort mode can be designated with a <code>@ java2c=optimize-toString</code> annotation 
452   * in its description block. Than the small-effort-mode is valid for that method body. 
453   * <br><br>
454   * The prevention of copy a String in a allocated buffer is not only a question of calculation time effort.
455   * If a routine in a fast interrupt uses a lightweight String preparation but an allocated buffer is necessary,
456   * that module needs resources, which are inadequately for it. Therefore the optimize mode is recommended.
457   * The Java-source should written in a form, which doesn't change a StringBuffer from which a derived 
458   * temporary String is still in use. First do all with the String, than change the Buffer. 
459   * Than the optimized C-code works correctly.
460   * <br><br>
461   * If the String is saved persistent in a class variable, it must copy to an own buffer. In this case
462   * an alteration of the StringBuffer content is able to expect while the persistent String is ready to use.
463   * It would be a non-obvious programming situation if the persistent String is referenced the buffer evermore.
464   * Thats why the assignment using <code>set_StringJc(...)</code> checks whether the String is non persistent.
465   * If it is so, a new StringBuffer is allocated in heap and the String is copied into. That StringBuffer
466   * is only referenced by this String, and therefore it is fix and managed by garbage collection.
467   * <br><br>
468   * An adequate problem are given by the <code>toString(...)</code> implementations of some other Objects.
469   * Because mostly the Strings will be processed immediately, at example as input for an concatenation,
470   * extra buffers should be saved to minimize effort. For preparing the returned String a thread-local StringBuffer
471   * is able to use. That is thread-save, but only one instance of that buffer exists per thread. 
472   * This buffer have never to be referenced. Thats why the same dedication is used: <code>mNonPersists__StringJc</code>.
473   * The user can produce a faulty code, a code which runs in Java because Java is save but it doesn't run in C after translation.
474   * This is the disadvantage of this concept, the concession to the optimizing of calculation time and preventing
475   * additional dynamically memory management. The user may write minimal other statements to get a safety code.
476   * <br><br>
477   * This routine is designated with the <code>@ java2c=optimize-toString.</code>, but the code is faulty for that:
478   * <pre class="Java">
479    bufferEmbedded.setLength(0);
480    String ss = bufferEmbedded.append("content:").append(234).toString();
481    bufferEmbedded.setLength(0);
482    bufferEmbedded.append(" TEST ").append(ss);
483    ss = bufferEmbedded.toString();
484    System.out.println(ss);
485   * </pre>
486   * The buffer content is saved in <code>ss</code>, but after them the buffer is changed. The translated C-code is:
487   * <pre>
488  bool _bOptimizeStringSave;  //J2C: annotation optimize-toString
489    ...
490  _bOptimizeStringSave = optimizeString_ThCxt(_thCxt, true);
491  { 
492    StringJc ss;
493    setLength_StringBufferJc(& (ythis->bufferEmbedded.sb), 0, _thCxt);
494    ss = 
495      ( append_s_StringBufferJc(& (ythis->bufferEmbedded.sb), s0_StringJc("content:"), _thCxt)
496      , append_i_StringBufferJc(& (ythis->bufferEmbedded.sb), 234, _thCxt)
497      , toString_StringBufferJc(& (ythis->bufferEmbedded.sb), _thCxt)
498      );
499    setLength_StringBufferJc(& (ythis->bufferEmbedded.sb), 0, _thCxt);
500    
501      ( append_s_StringBufferJc(& (ythis->bufferEmbedded.sb), s0_StringJc(" TEST "), _thCxt)
502      , append_s_StringBufferJc(& (ythis->bufferEmbedded.sb), ss, _thCxt)
503      );
504    ss = toString_StringBufferJc(& (ythis->bufferEmbedded.sb), _thCxt);
505    println_s_PrintStreamJc(REFJc(out_SystemJc), ss, _thCxt);
506  }
507  optimizeString_ThCxt(_thCxt, _bOptimizeStringSave);
508   * </pre>
509   * 
510   * The optimizing is set in the Thread-context-data. After the routine the saved state of optimizing
511   * is recovered.
512   * 
513   */
514  void testNonPersistenceOfStrings()
515  {
516    bufferEmbedded.setLength(0);
517    /**@java2c=toStringNonPersist. */
518    String ss = bufferEmbedded.append("content:").append(234).toString();
519    bufferEmbedded.setLength(0);
520    bufferEmbedded.append(" TEST ").append(ss);
521    /**@java2c=toStringNonPersist. */
522    ss = bufferEmbedded.toString();
523    System.out.println(ss);
524  }
525  
526  
527  
528  /**This routine has the same content like {@link #testNonPersistenceOfStrings()}, 
529   * but the persistence is set per default,
530   * no <code>@ java2c=optimize-toString</code>. is written here.
531   * The result is correct. Debug it in C!
532   */
533  void testPersistenceOfStrings()
534  {
535    bufferEmbedded.setLength(0);
536    String ss = bufferEmbedded.append("content:").append(234).toString();
537    bufferEmbedded.setLength(0);
538    bufferEmbedded.append(" TEST ").append(ss);
539    ss = bufferEmbedded.toString();
540    System.out.println(ss);
541  }
542  
543  
544  /**This routine uses the class java.lang.Date und SimpleFormatter
545   * to produce a String with a date and time information. 
546   * The translated code uses the CRuntimeJavalike-classes Date etc.
547   * Some annotations cause, that only stack-instances and the buffer in the thread context
548   * is used, no dynamically memory.
549   */
550  String testDateString(String sPath, int ident)
551  { /**@java2c=stackInstance. */
552        Date date = new Date();
553        /**@java2c=stackInstance. */
554        SimpleDateFormat dateFormat = new SimpleDateFormat("yy_MMM_dd_HHmmss_SS");
555        /**@java2c=toStringNonPersist.*/
556        String sDateString = dateFormat.format(date);
557        /**@java2c=StringBuilderInStack:150. */
558        String sFileName = sPath + "file_" + ident + "_" + sDateString + ".txt";
559        /**@java2c=returnInThreadCxt. */
560        return sFileName;
561  }
562  
563  /**This routine uses the class java.lang.Date und SimpleFormatter
564   * to produce a String with a date and time information. 
565   * The translated code uses the CRuntimeJavalike-classes Date etc.
566   * It is the same routine in Java like {@link #testDateString(String, int)},
567   * but there are no annotations. Therefore dynamically memory is used.
568   */
569  String testDateStringDynamic(String sPath, int ident)
570  { Date date = new Date();
571        SimpleDateFormat dateFormat = new SimpleDateFormat("yy_MMM_dd_HHmmss_SS");
572        String sDateString = dateFormat.format(date);
573        String sFileName = sPath + "file_" + ident + "_" + sDateString + ".txt";
574        return sFileName;
575  }
576  
577  /**@java2c=embedded Type:FileOutputStream. */
578  FileOutputStream oStream1, oStream2; 
579        
580  
581  void testOutStream(String sPath)
582  { try{
583                /**@java2c=StringBuilderInStack:100, toStringNonPersist. */
584      oStream1 = new FileOutputStream(sPath+ "file1.txt");
585      /**@java2c=StringBuilderInStack=256,toStringNonPersist. */
586      oStream2 = new FileOutputStream(sPath+ "file2.txt");
587      oStream1.close();
588      oStream2.close();
589    } catch(FileNotFoundException exc){
590        System.out.println("not found: " + sPath);
591    } catch (IOException e) {
592        System.out.println("file error: " + sPath);
593    }
594  }     
595  
596  private int testSomeSimpleStringMethods()
597  { int ret;
598    int pos;
599    boolean bOk;
600    final String s1 = "abcdecde";
601    final String s2 = "abc";
602    char cc = s1.charAt(3);
603    bOk = (cc == 'd');
604    bOk = bOk && ! s1.equals(s2);
605    bOk = bOk && s1.startsWith(s2);
606    
607    /**This case works in Java, but it is unnecessary. It doesn't work in Java2C. */
608    //bOk = bOk && s1.equals((Object)s1);  //error while compiling, fault type conversion.
609    //Object oString = s1;  //error while translating Java2C, a StringJc is not an ObjectJc
610    
611    ret = pos = s1.indexOf('c');
612    ret += pos = s1.indexOf('c', 2);  //pos = 2, same as above, but seach from position 2 only  
613    ret += pos = s1.indexOf('c', 3);  //pos = -1 because not found. 
614  
615    ret = pos = s1.indexOf("de");
616    ret += pos = s1.indexOf("de", 2);  //pos = 3, same as above, but seach from position 2 only  
617    ret += pos = s1.indexOf( "de", 4);  //pos = -1 because not found. 
618  
619    ret += pos = s1.indexOf("de", 99);  //pos = -1 because not found. Not an exception 
620  
621    ret += pos = s1.indexOf("de", -1);  //pos = 3 because search from 0. Not an exception.
622  
623    ret = pos = s1.lastIndexOf('c');
624    ret += pos = s1.lastIndexOf('c', 2);  //pos = 2, same as above, but seach from position 2 only  
625    ret += pos = s1.lastIndexOf('c', 3);  //pos = -1 because not found. 
626  
627    ret = pos = s1.lastIndexOf("de");
628    ret += pos = s1.lastIndexOf("de", 2);  //pos = -1, because not found.  
629    ret += pos = s1.lastIndexOf( "de", 3);  //pos = 3 because the string starts at 3.  
630  
631    ret += pos = s1.lastIndexOf("de", 99);  //pos = -1 because not found. Not an exception 
632  
633    ret += pos = s1.lastIndexOf("de", -1);  //pos = 3 because search from 0. Not an exception.
634  
635  
636    return ret;
637  }
638  
639  
640  
641  /**A CharSequence is the super-class of java.lang.String and java.lang.StringBuilder.
642   * In C it is the same as a StringJc, because the StringJc has the necessary methods
643   * and refers a sequence of chars.
644   * <br><br>
645   * The expression <code>CharSequence csq1 = buffer1</code> is a simple downcast 
646   * from StringBuilder in Java, but in C it is a toString()-call. The text itself isn't copy
647   * thereby, it is referenced. This is the equal functionality. Note that the StringJc is
648   * a simple value-struct with reference and length.
649   * 
650   */
651  private void testCharSequence()
652  {
653        buffer1.setLength(0); buffer1.append("csq1");
654        CharSequence csq1 = buffer1;  //StringBuffer to charSequence
655        bufferEmbedded.setLength(0);
656        bufferEmbedded.append("be_").append(csq1);
657        /**@java2c=toStringNonPersist. */
658        assert(bufferEmbedded.toString().equals("be_csq1"));
659  }
660  
661  
662  
663  /**Calls the test routines.
664   * 
665   */
666  public String testStringProcessing()
667  { long timeStart, timeEnd;
668    int timeRun;
669    float adjustTime;
670    String str;
671    timeStart = System.nanoTime();
672        try {
673                        Thread.sleep(10);
674                } catch (InterruptedException e) {
675                }
676    timeEnd = System.nanoTime();
677    timeRun = (int)(timeEnd - timeStart);
678    /**Runtime output @java2c=StringBuilderInStack=100, toStringNonPersist. */
679    System.out.println("10 ms: " + timeRun + "ns");
680    
681    timeStart = System.nanoTime();
682        try {
683                        Thread.sleep(100);
684                } catch (InterruptedException e) {
685                }
686    timeEnd = System.nanoTime();
687    timeRun = (int)(timeEnd - timeStart);
688    adjustTime = 100000.0F / timeRun;
689    /**Runtime output @java2c=StringBuilderInStack=100, toStringNonPersist. */
690    System.out.println("100 ms: " + (timeRun * adjustTime) + "us");
691    
692    timeStart = System.nanoTime();
693        timeEnd = System.nanoTime();
694    timeRun = (int)(timeEnd - timeStart);
695    /**Runtime output @java2c=StringBuilderInStack=100, toStringNonPersist. */
696    System.out.println("emtpy measurement: " +  (timeRun * adjustTime) + "us");
697    
698    
699    timeStart = System.nanoTime();
700    TestString_classic.concatenate(456, 3.14F);
701    TestString_classic.concatenate(457, 3.14F);
702    TestString_classic.concatenate(458, 3.14F);
703    TestString_classic.concatenate(459, 3.14F);
704    TestString_classic.concatenate(42, 3.14F);
705    TestString_classic.concatenate(43, 3.14F);
706    TestString_classic.concatenate(44, 3.14F);
707    TestString_classic.concatenate(45, 3.14F);
708    TestString_classic.concatenate(46, 3.14F);
709    TestString_classic.concatenate(47, 3.14F);
710    timeEnd = System.nanoTime();
711    timeRun = (int)(timeEnd - timeStart);
712    /**Runtime output @java2c=StringBuilderInStack=100, toStringNonPersist. */
713    System.out.println("TestString_classic.concatenate: " + (timeRun * adjustTime) + "us");
714    
715    timeStart = System.nanoTime();
716    testStringConcatenationInStack(456, 3.14F);
717    testStringConcatenationInStack(456, 3.14F);
718    testStringConcatenationInStack(456, 3.14F);
719    testStringConcatenationInStack(456, 3.14F);
720    testStringConcatenationInStack(456, 3.14F);
721    testStringConcatenationInStack(456, 3.14F);
722    testStringConcatenationInStack(456, 3.14F);
723    testStringConcatenationInStack(456, 3.14F);
724    testStringConcatenationInStack(456, 3.14F);
725    testStringConcatenationInStack(456, 3.14F);
726    timeEnd = System.nanoTime();
727    timeRun = (int)(timeEnd - timeStart);
728    /**Runtime output @java2c=StringBuilderInStack=100, toStringNonPersist. */
729    System.out.println("testStringConcatenationInStack: " + (timeRun * adjustTime) + "us");
730    
731    timeStart = System.nanoTime();
732    testStringConcatenationWithTemps(456, 3.14F);
733    testStringConcatenationWithTemps(456, 3.14F);
734    testStringConcatenationWithTemps(456, 3.14F);
735    testStringConcatenationWithTemps(456, 3.14F);
736    testStringConcatenationWithTemps(456, 3.14F);
737    testStringConcatenationWithTemps(456, 3.14F);
738    testStringConcatenationWithTemps(456, 3.14F);
739    testStringConcatenationWithTemps(456, 3.14F);
740    testStringConcatenationWithTemps(456, 3.14F);
741    testStringConcatenationWithTemps(456, 3.14F);
742    timeEnd = System.nanoTime();
743    timeRun = (int)(timeEnd - timeStart);
744    /**Runtime output @java2c=StringBuilderInStack=100, toStringNonPersist. */
745    System.out.println("testStringConcatenationWithTemps: " + (timeRun * adjustTime) + "us");
746    
747    testFormat(234, 3.14F);
748    
749    testStringConcatenationUsingBuilder(456);
750    testStringParameter();
751    testStringBuffer();
752    testReplace();
753    testNonPersistenceOfStrings();
754    testPersistenceOfStrings();
755    str = testDateString("./", 123);
756    str = testDateStringDynamic("./", 123);
757    testInsertCharArray();
758    String sPath = ".";
759    /**@java2c=StringBuilderInStack:100, toStringNonPersist. */
760    testOutStream(sPath + "/");
761    testSomeSimpleStringMethods();
762    testCharSequence();
763    String s9 = toString(); //calls override-able method
764    return s9;
765  }
766  
767
768}