Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Energy, onHostDestruction: ensured ptr existence
[simgrid.git] / contrib / psg / src / peersim / rangesim / TaggedOutputStream.java
1 /*
2  * Copyright (c) 2003-2005 The BISON Project
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  */
18
19 package peersim.rangesim;
20
21 import java.io.*;
22 import java.util.*;
23
24 import peersim.config.*;
25 import peersim.core.*;
26
27 /**
28  * This OutputStream uses an underlying stream to output
29  * data. Each line (terminated with `\n`) is augmented
30  * with a tag character. This is used to discriminate
31  * among standard error and standard output. This 
32  * feature is needed for launching new JVMs; it should
33  * not be used for other purposes. 
34  * 
35  * @author Alberto Montresor
36  * @version $Revision: 1.5 $
37  */
38 public class TaggedOutputStream extends PrintStream
39 {
40
41 //--------------------------------------------------------------------------
42 //Constants
43 //--------------------------------------------------------------------------
44
45 /** 
46  * This character is appended at the end of each line. 
47  */
48 public static final int TAG = 1;
49
50 //--------------------------------------------------------------------------
51 //Parameters
52 //--------------------------------------------------------------------------
53
54 /**
55  * This parameter contains the string that should be printed on each 
56  * line, containing the values of the range parameters for the experiment
57  * which is being run. The full name of this configuration string is
58  * prefixed by {@value peersim.Simulator#PAR_REDIRECT}.
59  * @config
60  */
61 public static final String PAR_RANGES = "ranges";
62
63 /**
64  * This parameter contains the list of observers for which the string
65  * contained in parameter {@value #PAR_RANGES} should be augmented with 
66  * a "TIME <t>" specification regarding current time. Observers are 
67  * separated by one of this characters: ' ' - ',' - ';'.
68  * @config
69  */
70 public static final String PAR_TIME = "simulation.timed-observers";
71
72
73 //--------------------------------------------------------------------------
74 //Fields
75 //--------------------------------------------------------------------------
76
77 /** Variable used to save the original System.out to simplify printing */
78 private PrintStream stdout;
79
80 /** Buffer used to store a single line; it can grow */
81 private byte[] buffer = new byte[1024];
82
83 /** Current size of the buffer */
84 private int size;
85
86 /** The value of the PAR_RANGES parameter */
87 private final String ranges;
88
89 /** The value of the PAR_TIME parameter */
90 private final ArrayList<String> obstime;
91
92 //--------------------------------------------------------------------------
93 //Initialization
94 //--------------------------------------------------------------------------
95
96
97 /**
98  * Creates a tagged output stream that prints the tagged
99  * output on the specified stream.
100  */
101 public TaggedOutputStream(String prefix)
102 {
103         super(System.out);
104         
105         obstime = new ArrayList<String>();
106         String[] obs = Configuration.getString(PAR_TIME, "").split("[ :,]");
107         for (int i=0; i < obs.length; i++) {
108                 obstime.add("control." + obs[i]);
109         }
110         ranges = Configuration.getString(prefix + "." + PAR_RANGES, "");
111         stdout = System.out;
112         size = 0;
113 }
114
115 //--------------------------------------------------------------------------
116 //Methods
117 //--------------------------------------------------------------------------
118
119 // Comment inherited from interface
120 @Override
121 public synchronized void write(byte[] b, int off, int len)
122 {
123         if (size+len > buffer.length) {
124                 byte[] tmp = new byte[Math.max(buffer.length*2, size+len)];
125                 System.arraycopy(buffer, 0, tmp, 0, size);
126                 buffer = tmp;
127         }
128         int last = off+len;
129         for (int i=off; i < last; i++) {
130                 if (b[i] == '\n') {
131                         buffer[size++] = TAG;
132                         buffer[size++] = b[i];
133                         printLine();
134                 }  else {
135                         buffer[size++] = b[i];
136                 }
137         }
138 }
139
140 // Comment inherited from interface
141 @Override
142 public synchronized void write(int b)
143 {
144         if (size == buffer.length) {
145                 byte[] tmp = new byte[buffer.length*2];
146                 System.arraycopy(buffer, 0, tmp, 0, size);
147                 buffer = tmp;
148         }
149         if (b == '\n') {
150                 buffer[size++] = TAG;
151                 buffer[size++] = (byte) b;
152                 printLine();
153         }  else {
154                 buffer[size++] = (byte) b;
155         }
156 }
157
158 /** 
159  * Actually prints a line, inserting ranges and time
160  * when needed.
161  */
162 private void printLine()
163 {
164         String line = new String(buffer, 0, size);
165         String[] parts = line.split(":");
166         if (parts.length == 2) {
167                 stdout.print(parts[0]);
168                 stdout.print(": ");
169                 stdout.print(ranges);
170                 if (obstime.contains(parts[0]))
171                         stdout.print(" TIME " + CommonState.getTime() + " ");
172                 stdout.print(parts[1]);
173         } else {
174                 stdout.print(line);
175         }
176         size = 0;
177 }
178
179 }