Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/util/Code.java @ 10501

Last change on this file since 10501 was 6152, checked in by bfarka, 14 years ago

added ecj and custom statistics to communicate with the okb services #1441

File size: 27.4 KB
Line 
1/*
2  Copyright 2006 by Sean Luke
3  Licensed under the Academic Free License version 3.0
4  See the file "LICENSE" for more information
5*/
6
7
8package ec.util;
9import java.io.*;
10import ec.*;
11
12/*
13 * Code.java
14 *
15 * Created: Sat Oct 23 13:45:20 1999
16 * By: Sean Luke
17 */
18
19/**
20 * Code provides some simple wrapper functions for encoding and decoding
21 * basic data types for storage in a pseudo-Java source code strings
22 * format.  This differs from just "printing"
23 * them to string in that the actual precision of the object is maintained.
24 * Code attempts to keep the representations as "Java-like" as possible --
25 * the exceptions being primarily floats and doubles, which are encoded as
26 * ints and longs.  Encoding of objects and arrays is not supported.  You'll
27 * have to handle that yourself.  Strings are supported.
28 *
29 * <p>Everything is case-SENSITIVE.  Here's the breakdown.
30 *
31
32 <p><table>
33 <tr><td><b>Type</b></td><td><b>Format</b></td></tr>
34 <tr><td>boolean</td><td><tt>true</tt> or <tt>false</tt> (old style, case sensitive) or <tt>T</tt> or <tt>F</tt> (new style, case sensitive)</td></tr>
35 <tr><td>byte</td><td><tt>b<i>byte</i>|</tt></td></tr>
36 <tr><td>short</td><td><tt>s<i>short</i>|</tt></td></tr>
37 <tr><td>int</td><td><tt>i<i>int</i>|</tt></td></tr>
38 <tr><td>long</td><td><tt>l<i>long</i>|</tt></td></tr>
39 <tr><td>float</td><td><tt>f<i>floatConvertedToIntForStorage</i>|<i>humanReadableFloat</i>|</tt> or (only for reading in) f|<i>humanReadableFloat</i>|</td></tr>
40 <tr><td>float</td><td><tt>d<i>doubleConvertedToLongForStorage</i>|<i>humanReadableDouble</i>|</tt> or (only for reading in) d|<i>humanReadableDouble</i>|</td></tr>
41 <tr><td>char</td><td>standard Java char, except that the only valid escape sequences are: \0 \t \n \b \' \" \ u <i>unicodeHex</i></td></tr>
42 <tr><td>string</td><td>standard Java string with \ u ...\ u Unicode escapes, except that the only other valid escape sequences are:  \0 \t \n \b \' \" </i></td></tr>
43 </table>
44 *
45 *
46 * @author Sean Luke
47 * @version 1.0
48 */
49
50public class Code
51    {
52    /** Encodes a boolean. */
53    public static String encode(final boolean b)
54    // old style -- no longer used
55    // { return b ? Boolean.TRUE.toString() : Boolean.FALSE.toString(); }
56        { return b ? "T" : "F"; }
57
58    /** Encodes a byte. */
59    public static String encode(final byte b)
60        { return "b" + Byte.toString(b) + "|"; }
61
62    /** Encodes a character. */
63    public static String encode(final char c)
64        {
65        if (c >= 32 && c < 127 && c !='\\' &&
66            c!= '\'') // we can safely print it
67            return "'" + String.valueOf(c) + "'";
68        else
69            {
70            // print it with an escape character
71            if (c=='\b')
72                return "'\\b'";
73            else if (c=='\n')
74                return "'\\n'";
75            else if (c=='\t')
76                return "'\\t'";
77            else if (c=='\'')
78                return "'\\''";
79            else if (c=='\\')
80                return "'\\\\'";
81            else if (c=='\0')
82                return "'\\\\0";
83            else
84                {
85                String s = Integer.toHexString((int)c);
86                // pad with 0's  -- Java's parser freaks out otherwise
87                switch (s.length())
88                    {
89                    case 1:  s = "'\\u000" + s + "'"; break;
90                    case 2:  s = "'\\u00" + s + "'"; break;
91                    case 3:  s = "'\\u0" + s + "'"; break;
92                    case 4:  s = "'\\u" + s + "'"; break;
93                    }
94                return s;
95                }
96            }
97        }
98
99    /** Encodes a short. */
100    public static String encode(final short s)
101        { return "s" + Short.toString(s) + "|"; }
102
103    /** Encodes an int. */
104    public static String encode(final int i)
105        { return "i" + Integer.toString(i) + "|";  }
106   
107    /** Encodes a long. */
108    public static String encode(final long l)
109        { return "l" + Long.toString(l) + "|"; }
110
111    /** Encodes a float. */
112    public static String encode(final float f)
113        { return "f" + Integer.toString(Float.floatToIntBits(f))+ "|" + String.valueOf(f) + "|"; }
114
115    /** Encodes a double. */
116    public static String encode(final double d)
117        { return "d" + Long.toString(Double.doubleToLongBits(d))+ "|" + String.valueOf(d) + "|"; }
118
119    /** Encodes a String. */
120    public static String encode(final String s)
121        {
122        boolean inUnicode = false;
123        int l = s.length();
124        StringBuffer sb = new StringBuffer(l);
125        sb.append("\"");
126        for(int x=0;x<l;x++)
127            {
128            char c = s.charAt(x);
129            if ( c >= 32 && c < 127 && c !='\\' && c!= '"') // we allow spaces
130                // we can safely print it
131                {
132                if (inUnicode) { sb.append("\\u"); inUnicode=false; }
133                sb.append(c);
134                }
135            else
136                {
137                // print it with an escape character
138                if (c=='\b')
139                    {
140                    if (inUnicode) { sb.append("\\u"); inUnicode=false; }
141                    sb.append("\\b");
142                    }
143                else if (c=='\n')
144                    {
145                    if (inUnicode) { sb.append("\\u"); inUnicode=false; }
146                    sb.append("\\n");
147                    }
148                else if (c=='\t')
149                    {
150                    if (inUnicode) { sb.append("\\u"); inUnicode=false; }
151                    sb.append("\\t");
152                    }
153                else if (c=='"')
154                    {
155                    if (inUnicode) { sb.append("\\u"); inUnicode=false; }
156                    sb.append("\\\"");
157                    }
158                else if (c=='\\')
159                    {
160                    if (inUnicode) { sb.append("\\u"); inUnicode=false; }
161                    sb.append("\\\\");
162                    }
163                else if (c=='\0')
164                    {
165                    if (inUnicode) { sb.append("\\u"); inUnicode=false; }
166                    sb.append("\\0");
167                    }
168                else
169                    {
170                    if (!inUnicode) {sb.append("\\u"); inUnicode=true; }
171                    String ss = Integer.toHexString((int)c);
172                    // pad with 0's  -- Java's parser freaks out otherwise
173                    switch (ss.length())
174                        {
175                        case 1:  sb.append("000" + ss); break;
176                        case 2:  sb.append("00" + ss); break;
177                        case 3: sb.append("0" + ss); break;
178                        case 4: sb.append(ss); break;
179                        }
180                    }
181                }
182            }
183        if (inUnicode) sb.append("\\u");
184        sb.append("\"");
185        return sb.toString();
186        }
187
188
189
190
191
192
193
194
195
196    /** Decodes the next item out of a DecodeReturn and modifies the DecodeReturn to hold the results.  See DecodeReturn for more
197        explanations about how to interpret the results. */
198
199    public static void decode(DecodeReturn d)
200        {
201        String dat = d.data;
202        int x = d.pos;
203        int len = d.data.length();
204
205        // look for whitespace or ( or )
206        for ( ; x<len; x++ )
207            if (!Character.isWhitespace(dat.charAt(x))) break;
208
209        // am I at the end of my rope?
210        if (x==len) { d.type = DecodeReturn.T_ERROR; d.s = "Out of tokens"; return; }
211
212        // what type am I?
213        switch(dat.charAt(x))
214            {
215
216            case 't': // boolean (true)
217                if (x+3 < len && /* enough space */
218                    dat.charAt(x+1)=='r' &&
219                    dat.charAt(x+2)=='u' &&
220                    dat.charAt(x+3)=='e')
221                    { d.type = DecodeReturn.T_BOOLEAN; d.l = 1; d.pos = x+4; return; }
222                else { d.type = DecodeReturn.T_ERROR; d.s = "Expected a (true) boolean"; return; }
223                //break;
224
225            case 'T': // boolean (true)
226            { d.type = DecodeReturn.T_BOOLEAN; d.l = 1; d.pos = x+1; return; }
227            //break;
228                   
229            case 'F': // boolean (false)
230            { d.type = DecodeReturn.T_BOOLEAN; d.l = 0; d.pos = x+1; return; }
231            //break;
232                   
233
234
235
236            case 'f': // float or boolean
237                if (x+4 < len && /* enough space */
238                    dat.charAt(x+1)=='a' && dat.charAt(x+2)=='l' && dat.charAt(x+3)=='s' && dat.charAt(x+4)=='e' )
239                    { d.type = DecodeReturn.T_BOOLEAN; d.l = 0; d.pos = x+5; return; }
240                else
241                    {
242                    boolean readHuman = false;
243                    String sf = null;
244                    int initial = x+1;
245                               
246                    // look for next '|'
247                    for ( ; x < len; x++)
248                        if (dat.charAt(x)=='|') break;
249                   
250                    if (x==initial) readHuman=true;
251                               
252                    if ( x >= len )
253                        { d.type = DecodeReturn.T_ERROR; d.s = "Expected a float"; return; }
254
255                    if (!readHuman)
256                        sf = dat.substring(initial,x);
257                    x++;
258                   
259                    // look for next '|'
260                    int initial2 = x;  // x is now just past first |
261                    for ( ; x < len; x++)
262                        if (dat.charAt(x)=='|') break;
263                   
264                    if ( x >= len )
265                        { d.type = DecodeReturn.T_ERROR; d.s = "Expected a float"; return; }
266                    if (readHuman)
267                        sf = dat.substring(initial2,x);
268                   
269                    float f;
270                    try
271                        {
272                        if (readHuman) f = Float.parseFloat(sf);
273                        else f = Float.intBitsToFloat(Integer.parseInt(sf));
274                        }
275                    catch (NumberFormatException e)
276                        { d.type = DecodeReturn.T_ERROR; d.s = "Expected a float"; return; }
277                    d.type = DecodeReturn.T_FLOAT;
278                    d.d = f;
279                    d.pos = x+1;
280                    return;
281                    }
282
283
284
285
286
287
288
289
290            case 'd': // double
291               
292            {
293            boolean readHuman = false;
294            String sf = null;
295            int initial = x+1;
296                       
297            // look for next '|'
298            for ( ; x < len; x++)
299                if (dat.charAt(x)=='|') break;
300           
301            if (x==initial) readHuman=true;
302                       
303            if ( x >= len )
304                { d.type = DecodeReturn.T_ERROR; d.s = "Expected a double"; return; }
305
306            if (!readHuman)
307                sf = dat.substring(initial,x);
308            x++;
309           
310            // look for next '|'
311            int initial2 = x;  // x is now just past first |
312            for ( ; x < len; x++)
313                if (dat.charAt(x)=='|') break;
314           
315            if ( x >= len )
316                { d.type = DecodeReturn.T_ERROR; d.s = "Expected a double"; return; }
317            if (readHuman)
318                sf = dat.substring(initial2,x);
319           
320            double f;
321            try
322                {
323                if (readHuman) f = Double.parseDouble(sf);
324                else f = Double.longBitsToDouble(Long.parseLong(sf));
325                }
326            catch (NumberFormatException e)
327                { d.type = DecodeReturn.T_ERROR; d.s = "Expected a double"; return; }
328            d.type = DecodeReturn.T_DOUBLE;
329            d.d = f;
330            d.pos = x+1;
331            return;
332            }
333            // break;
334                       
335                       
336
337
338
339
340
341
342            case 'b': // byte
343               
344            {
345            int initial = x+1;
346                       
347            // look for next '|'
348            for ( ; x < len; x++)
349                if (dat.charAt(x)=='|') break;
350                       
351            if ( x >= len )
352                { d.type = DecodeReturn.T_ERROR; d.s = "Expected a byte"; return; }
353            String sf = dat.substring(initial,x);
354                                           
355            byte f;
356            try
357                { f = Byte.parseByte(sf); }
358            catch (NumberFormatException e)
359                { d.type = DecodeReturn.T_ERROR; d.s = "Expected a byte"; return; }
360            d.type = DecodeReturn.T_BYTE;
361            d.l = f;
362            d.pos = x+1;
363            return;
364            }
365            // break;
366
367
368
369
370
371
372            case 's': // short
373               
374            {
375            int initial = x+1;
376                       
377            // look for next '|'
378            for ( ; x < len; x++)
379                if (dat.charAt(x)=='|') break;
380                       
381            if ( x >= len )
382                { d.type = DecodeReturn.T_ERROR; d.s = "Expected a short"; return; }
383            String sf = dat.substring(initial,x);
384                                           
385            short f;
386            try
387                { f = Short.parseShort(sf); }
388            catch (NumberFormatException e)
389                { d.type = DecodeReturn.T_ERROR; d.s = "Expected a short"; return; }
390            d.type = DecodeReturn.T_SHORT;
391            d.l = f;
392            d.pos = x+1;
393            return;
394            }
395            // break;
396
397
398
399
400            case 'i': // int
401               
402            {
403            int initial = x+1;
404                       
405            // look for next '|'
406            for ( ; x < len; x++)
407                if (dat.charAt(x)=='|') break;
408                       
409            if ( x >= len )
410                { d.type = DecodeReturn.T_ERROR; d.s = "Expected an int"; return; }
411            String sf = dat.substring(initial,x);
412                                           
413            int f;
414            try
415                { f = Integer.parseInt(sf); }
416            catch (NumberFormatException e)
417                { d.type = DecodeReturn.T_ERROR; d.s = "Expected an int"; return; }
418            d.type = DecodeReturn.T_INT;
419            d.l = f;
420            d.pos = x+1;
421            return;
422            }
423            // break;
424
425
426
427
428
429
430            case 'l': // long
431               
432            {
433            int initial = x+1;
434                       
435            // look for next '|'
436            for ( ; x < len; x++)
437                if (dat.charAt(x)=='|') break;
438                       
439            if ( x >= len )
440                { d.type = DecodeReturn.T_ERROR; d.s = "Expected a long"; return; }
441            String sf = dat.substring(initial,x);
442                                           
443            long f;
444            try
445                { f = Long.parseLong(sf); }
446            catch (NumberFormatException e)
447                { d.type = DecodeReturn.T_ERROR; d.s = "Expected a long"; return; }
448            d.type = DecodeReturn.T_LONG;
449            d.l = f;
450            d.pos = x+1;
451            return;
452            }
453            // break;
454
455
456
457
458
459
460            case '"':  // string
461            {
462            StringBuffer sb = new StringBuffer();
463            boolean inUnicode = false;
464           
465            x++;
466            for ( ; x < len; x++)
467                {
468                char c = dat.charAt(x);
469                if (c=='"')
470                    {
471                    // done with the string
472                    if (inUnicode)  // uh oh
473                        { d.type = DecodeReturn.T_ERROR; d.s = "Forgot to terminate Unicode with a '\\u' in the string"; return; }
474                    d.type = DecodeReturn.T_STRING;
475                    d.s = sb.toString();
476                    d.pos = x+1;
477                    return;
478                    }
479                else if (c=='\\')  // escape
480                    {
481                    x++;
482                    if ( x >= len )
483                        { d.type = DecodeReturn.T_ERROR; d.s = "Unterminated String"; return; }
484                    if (dat.charAt(x)!='u')
485                        { d.type = DecodeReturn.T_ERROR; d.s = "Escape character in Unicode sequence"; return; }
486
487                    switch (dat.charAt(x))
488                        {
489                        case 'u': inUnicode = !inUnicode; break;
490                        case 'b': sb.append('\b'); break;
491                        case 'n': sb.append('\n'); break;
492                        case '"': sb.append('"'); break;
493                        case '\'': sb.append('\''); break;
494                        case 't': sb.append('\t'); break;
495                        case '\\': sb.append('\\'); break;
496                        case '0': sb.append('\0'); break;
497                        default:
498                        { d.type = DecodeReturn.T_ERROR; d.s = "Bad escape char in String"; return; }
499                        }
500                    }
501                else if (inUnicode)
502                    {
503                    if ( x + 3 >= len )
504                        { d.type = DecodeReturn.T_ERROR; d.s = "Unterminated String"; return; }
505                    try
506                        {
507                        sb.append((char)(Integer.decode("0x" + c +
508                                    dat.charAt(x+1) +
509                                    dat.charAt(x+2) +
510                                    dat.charAt(x+3)).intValue()));;
511                        x+=3;
512                        }
513                    catch (NumberFormatException e)
514                        { d.type = DecodeReturn.T_ERROR; d.s = "Bad Unicode in String"; return; }
515                    }
516                else sb.append(c);
517                }
518            d.type = DecodeReturn.T_ERROR; d.s = "Unterminated String"; return;
519            }
520            //break;
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535            case '\'': // char
536            {
537            x++;
538            if ( x >= len )
539                { d.type = DecodeReturn.T_ERROR; d.s = "Unterminated char"; return; }
540            char c = dat.charAt(x);
541            if (c=='\\')
542                {
543                x++;
544                if (x>=len)
545                    { d.type = DecodeReturn.T_ERROR; d.s = "Unterminated char"; return; }
546                switch (dat.charAt(x))
547                    {
548                    case 'u':
549                        if ( x + 4 >= len )
550                            { d.type = DecodeReturn.T_ERROR; d.s = "Unterminated char"; return; }
551                        try
552                            {
553                            c = (char)(Integer.decode("0x" +
554                                    dat.charAt(x+1) +
555                                    dat.charAt(x+2) +
556                                    dat.charAt(x+3) +
557                                    dat.charAt(x+4)).intValue());
558                            }
559                        catch (NumberFormatException e)
560                            { d.type = DecodeReturn.T_ERROR; d.s = "Bad Unicode in char"; return; }
561                        x+=5;
562                        break;
563                   
564                    case 'b': c = '\b'; x++; break;
565                    case 'n': c = '\n'; x++; break;
566                    case '"': c = '"'; x++; break;
567                    case '\'': c = '\''; x++; break;
568                    case 't':  c = '\t'; x++; break;
569                    case '\\': c = '\\'; x++; break;
570                    case '0': c = '\0';  x++; break;
571                    default:
572                    { d.type = DecodeReturn.T_ERROR; d.s = "Bad escape char in char"; return; }
573                    }
574                if (dat.charAt(x)!='\'')
575                    { d.type = DecodeReturn.T_ERROR; d.s = "Bad char"; return; }
576                d.type = DecodeReturn.T_CHAR;
577                d.l = c;
578                d.pos = x+1;
579                return;
580                }
581            else
582                {
583                x++;
584                if ( x >= len )
585                    { d.type = DecodeReturn.T_ERROR; d.s = "Unterminated char"; return; }
586                if (dat.charAt(x)!='\'')
587                    { d.type = DecodeReturn.T_ERROR; d.s = "Bad char"; return; }
588                d.type = DecodeReturn.T_CHAR;
589                d.l = c;
590                d.pos = x + 1;
591                return;
592                }
593
594
595            }
596            //break;
597
598
599
600
601
602
603           
604            default:
605                d.type = DecodeReturn.T_ERROR; d.s = "Unknown token"; return;
606                // break;
607            }
608        }
609
610    /** Finds the next nonblank line, then trims the line and checks the preamble.  Returns a DecodeReturn on the line if successful, else posts a fatal error.
611        Sets the DecodeReturn's line number.  The DecodeReturn has not yet been decoded.  You'll need to do that with Code.decode(...) */
612    public static DecodeReturn checkPreamble(String preamble, final EvolutionState state,
613        final LineNumberReader reader)
614        {
615        int linenumber = 0;  // throw it away later
616        try
617            {
618            // get non-blank line
619            String s = "";
620            while(s != null && s.trim().equals(""))
621                {
622                linenumber = reader.getLineNumber();
623                s = reader.readLine();
624                }
625
626            // check the preamble
627            if (s==null || !(s = s.trim()).startsWith(preamble)) // uh oh
628                state.output.fatal("Line " + linenumber +
629                    " has a bad preamble.Expected '" + preamble + "'\n-->" + s);
630            DecodeReturn d = new DecodeReturn(s, preamble.length());
631            d.lineNumber = linenumber;
632            return d;
633            }
634        catch (IOException e)
635            {
636            state.output.fatal("On line " + linenumber + " an IO error occurred:\n\n" + e);
637            return null;  // never happens
638            }
639        }
640
641    /** Finds the next nonblank line, skips past an expected preamble, and reads in a string if there is one, and returns it.
642        Generates an error otherwise. */
643    public static String readStringWithPreamble(String preamble, final EvolutionState state,
644        final LineNumberReader reader)
645        {
646        DecodeReturn d = checkPreamble(preamble, state, reader);
647        Code.decode(d);
648        if (d.type!=DecodeReturn.T_STRING)
649            state.output.fatal("Line " + d.lineNumber +
650                " has no string after preamble '" + preamble + "'\n-->" + d.data);
651        return (String)(d.s);
652        }
653
654    /** Finds the next nonblank line, skips past an expected preamble, and reads in a character if there is one, and returns it.
655        Generates an error otherwise. */
656    public static char readCharacterWithPreamble(String preamble, final EvolutionState state,
657        final LineNumberReader reader)
658        {
659        DecodeReturn d = checkPreamble(preamble, state, reader);
660        Code.decode(d);
661        if (d.type!=DecodeReturn.T_CHAR)
662            state.output.fatal("Line " + d.lineNumber +
663                " has no character after preamble '" + preamble + "'\n-->" + d.data);
664        return (char)(d.l);
665        }
666
667    /** Finds the next nonblank line, skips past an expected preamble, and reads in a byte if there is one, and returns it.
668        Generates an error otherwise. */
669    public static byte readByteWithPreamble(String preamble, final EvolutionState state,
670        final LineNumberReader reader)
671        {
672        DecodeReturn d = checkPreamble(preamble, state, reader);
673        Code.decode(d);
674        if (d.type!=DecodeReturn.T_BYTE)
675            state.output.fatal("Line " + d.lineNumber +
676                " has no byte after preamble '" + preamble + "'\n-->" + d.data);
677        return (byte)(d.l);
678        }
679
680    /** Finds the next nonblank line, skips past an expected preamble, and reads in a short if there is one, and returns it.
681        Generates an error otherwise. */
682    public static short readShortWithPreamble(String preamble, final EvolutionState state,
683        final LineNumberReader reader)
684        {
685        DecodeReturn d = checkPreamble(preamble, state, reader);
686        Code.decode(d);
687        if (d.type!=DecodeReturn.T_SHORT)
688            state.output.fatal("Line " + d.lineNumber +
689                " has no short after preamble '" + preamble + "'\n-->" + d.data);
690        return (short)(d.l);
691        }
692
693    /** Finds the next nonblank line, skips past an expected preamble, and reads in a long if there is one, and returns it.
694        Generates an error otherwise. */
695    public static long readLongWithPreamble(String preamble, final EvolutionState state,
696        final LineNumberReader reader)
697        {
698        DecodeReturn d = checkPreamble(preamble, state, reader);
699        Code.decode(d);
700        if (d.type!=DecodeReturn.T_LONG)
701            state.output.fatal("Line " + d.lineNumber +
702                " has no long after preamble '" + preamble + "'\n-->" + d.data);
703        return (long)(d.l);
704        }
705       
706    /** Finds the next nonblank line, skips past an expected preamble, and reads in an integer if there is one, and returns it.
707        Generates an error otherwise. */
708    public static int readIntegerWithPreamble(String preamble, final EvolutionState state,
709        final LineNumberReader reader)
710        {
711        DecodeReturn d = checkPreamble(preamble, state, reader);
712        Code.decode(d);
713        if (d.type!=DecodeReturn.T_INT)
714            state.output.fatal("Line " + d.lineNumber +
715                " has no integer after preamble '" + preamble + "'\n-->" + d.data);
716        return (int)(d.l);
717        }
718
719
720    /** Finds the next nonblank line, skips past an expected preamble, and reads in a float if there is one, and returns it.
721        Generates an error otherwise. */
722    public static float readFloatWithPreamble(String preamble, final EvolutionState state,
723        final LineNumberReader reader)
724        {
725        DecodeReturn d = checkPreamble(preamble, state, reader);
726        Code.decode(d);
727        if (d.type!=DecodeReturn.T_FLOAT)
728            state.output.fatal("Line " + d.lineNumber +
729                " has no floating point number after preamble '" + preamble + "'\n-->" + d.data);
730        return (float)(d.d);
731        }
732
733    /** Finds the next nonblank line, skips past an expected preamble, and reads in a double if there is one, and returns it.
734        Generates an error otherwise. */
735    public static double readDoubleWithPreamble(String preamble, final EvolutionState state,
736        final LineNumberReader reader)
737        {
738        DecodeReturn d = checkPreamble(preamble, state, reader);
739        Code.decode(d);
740        if (d.type!=DecodeReturn.T_DOUBLE)
741            state.output.fatal("Line " + d.lineNumber +
742                " has no double floating point number after preamble '" + preamble + "'. -->" + d.data);
743        return d.d;
744        }
745
746    /** Finds the next nonblank line, skips past an expected preamble, and reads in a boolean value ("true" or "false") if there is one, and returns it.
747        Generates an error otherwise. */
748    public static boolean readBooleanWithPreamble(String preamble, final EvolutionState state,
749        final LineNumberReader reader)
750        {
751        DecodeReturn d = checkPreamble(preamble, state, reader);
752        Code.decode(d);
753        if (d.type!=DecodeReturn.T_BOOLEAN)
754            state.output.fatal("Line " + d.lineNumber +
755                " has no boolean value ('true' or 'false') after preamble '" + preamble + "'\n-->" + d.data);
756        return (d.l != 0);
757        }
758
759    }
760
761
762/*
763  (BeanShell testing for decoding)
764
765  s = "      true false s-12| i232342|b22|f234123|3234.1| d234111231|4342.31|"
766
767
768  s = "\"Hello\" true false s-12| i232342|b22|f234123|3234.1| d234111231|4342.31| ' ' '\\'' '\\n' \"Hello\\u0000\\uWorld\""
769  c = new ec.util.Code();
770  r = new ec.util.DecodeReturn(s);
771
772  c.decode(r);
773  System.out.println(r.type);
774  System.out.println(r.l);
775
776  System.out.println(r.d);
777  System.out.println(r.s);
778
779*/
Note: See TracBrowser for help on using the repository browser.