View Javadoc

1   package net.sf.tourviewer.lib.ciclo;
2   
3   import java.io.BufferedReader;
4   import java.io.IOException;
5   import java.io.InputStream;
6   import java.io.InputStreamReader;
7   import java.text.ParseException;
8   import java.text.SimpleDateFormat;
9   import java.util.Calendar;
10  import java.util.Date;
11  import net.sf.tourviewer.lib.Tour;
12  import net.sf.tourviewer.lib.TourRecord;
13  import net.sf.tourviewer.lib.TourSet;
14  import net.sf.tourviewer.lib.Tour.Type;
15  
16  public class CicloTurReader 
17  {
18  
19  	private static final String FILE_SIGNATURE = "HACtronic";
20  	private int currentLine;
21  	BufferedReader in;
22  	
23  	public boolean accept(InputStream in) throws IOException {
24  		byte[] buffer = new byte[FILE_SIGNATURE.length()];
25  		in.mark(buffer.length);
26  		in.read(buffer);
27  		
28  		try {
29  			return FILE_SIGNATURE.equalsIgnoreCase(new String(buffer)); 
30  		}
31  		finally {
32  			in.reset();
33  		}
34  	}
35  	
36  	public TourSet read(InputStream inStream) throws IOException {
37  		in = new BufferedReader(new InputStreamReader(inStream));
38  		
39  		TourSet tourSet = new TourSet();
40  		Tour tour = new Tour();
41  		tour.setAutoStatistics(false);
42  		try {
43  			String signature = readLine();
44  			int version1 = Integer.parseInt(readLine());
45  			int version2 = Integer.parseInt(readLine());
46  			int version3 = Integer.parseInt(readLine());
47  			tour.setTitle(readLine());								//  5
48  			tour.setStartLocation(readLine());
49  			tour.setEndLocation(readLine());
50  			String date = readLine();
51  			String time = readLine();
52  			tour.setStartTime(parseTime(date, time));				// 10
53  			StringBuffer sb = new StringBuffer();
54  			int noteCount = Integer.parseInt(readLine());
55  			for (int i = 0; i < noteCount; i++) {
56  				sb.append(readLine());
57  			}
58  			tour.setNote(sb.toString());
59  			tour.setDistance(Integer.parseInt(readLine()));
60  			// TODO: need to calculate tour.TravelTime();
61  			int tourDurance = Integer.parseInt(readLine());
62  		    readLine();
63  		    tour.setMaxAltitude(Integer.parseInt(readLine()));
64  			int diffAltitude = Integer.parseInt(readLine()); // TODO // 15
65  			tour.setAvgAltitudeInc(Double.parseDouble(readLine()));
66  			tour.setAvgSlope(Double.parseDouble(readLine()));
67  			tour.setAvgSpeed(Double.parseDouble(readLine()));
68  			tour.setAvgTemperature(Double.parseDouble(readLine()));
69  			tour.setAvgPulse(Double.parseDouble(readLine()));		// 20
70  			readLine(); // -1
71  			tour.setType(parseType(Integer.parseInt(readLine()), version2));
72  			readLine(); // Reserved
73  			readLine(); // Reserved
74  			readLine();	// Reserved									// 25
75  			readLine(); // Reserved
76  			readLine(); // Reserved
77  			readLine(); // Reserved
78  			readLine(); // Reserved
79  			readLine();	// Reserved									// 30
80  			tourSet.setPersonName(parseName(readLine(), readLine()));
81  			tourSet.setDateOfBirth(parseDate(readLine().trim()));
82  			String team = readLine();
83  			tourSet.setPersonWeight(Integer.parseInt(readLine()));	// 35
84  			int pulseLow = Integer.parseInt(readLine()); // TODO min
85  			int pulseHigh = Integer.parseInt(readLine()); // TODO max
86  			String material = readLine(); // TODO
87  			int materialWeight = Integer.parseInt(readLine()); // TODO
88  			tourSet.setTotalDistance(Integer.parseInt(readLine()));	// 40
89  			tourSet.setTotalTravelTime(Integer.parseInt(readLine()));
90  			tourSet.setTotalAltitudeUp(Integer.parseInt(readLine()));
91  			tourSet.setTotalAltitudeDown(Integer.parseInt(readLine()));
92  			readLine();
93  			readLine();												// 45
94  			readLine();
95  			readLine();
96  			readLine();
97  			readLine();
98  			readLine();												// 50
99  			readLine();
100 			readLine();
101 			readLine();
102 			int recordCount = Integer.parseInt(readLine());
103 		    TourRecord lastRecord = readRecords(tour, recordCount);							// 55
104 			if (recordCount > 0) {
105 				readLine(); // eat line break
106 				tour.setEndTime(lastRecord.getTime());
107 				tour.setDistance(lastRecord.getDistance());
108 			}
109 			int markerCount = Integer.parseInt(readLine()); currentLine++;
110 		    readMarkers(tour, markerCount);
111 			if (markerCount > 0) {
112 				readLine(); // eat line break
113 			}
114 		}
115 		catch (NumberFormatException e) {
116 			e.printStackTrace();
117 			throw new IOException("Invalid data in line " + currentLine + ", expected number");
118 		}
119 		catch (ParseException e) {
120 			e.printStackTrace();
121 			throw new IOException("Invalid data format in line " + currentLine);
122 		}
123 		
124 		tourSet.addTour(tour);
125 		return tourSet;
126 	}	
127 
128 	private Type parseType(int mode, int version)
129 	{
130 		// TODO add other types
131 		if (version == 1) {
132 			switch (mode) {
133 			case 0:
134 				return Type.JOGGING;
135 			case 2:
136 				return Type.BIKE;
137 			case 3:
138 				return Type.SKI_BIKE;
139 			}
140 		}
141 		else if (version == 2) {
142 			switch (mode) {
143 			case 2:
144 				return Type.BIKE; // bike2
145 			case 3:
146 				return Type.BIKE; // bike1
147 			}
148 		}		
149 		return Type.OTHER;
150 	}
151 
152 	private String parseName(String surname, String firstName)
153 	{
154 		return (firstName.length() == 0) ? surname : (surname.length() == 0) ? firstName 
155 				: surname + ", " + firstName;
156 	}
157 
158 	private Date parseDate(String date) throws ParseException
159 	{
160 		if (date.length() == 0 || date.startsWith(".")) {
161 			return null;
162 		}
163 		SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy"); 
164 		return format.parse(date);
165 	}
166 
167 	private Date parseTime(String date, String time) throws ParseException
168 	{
169 		SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm"); 
170 		return format.parse(date + " " + time);
171 	}
172 
173 	private TourRecord readRecords(Tour tour, int recordCount) throws IOException 
174 	{
175 		if (recordCount <= 0) {
176 			throw new IllegalArgumentException("recordCount must be greater than 0"); 
177 		}
178 		
179 		TourRecord record = null;
180 		for (int i = 0; i < recordCount; i++) {
181 			record = new TourRecord();
182 			Calendar cal = Calendar.getInstance();
183 			long date = (readUnsignedInt() - 86400) * 1000;
184 			cal.setTimeInMillis(date - cal.getTimeZone().getOffset(date));
185 			record.setTime(cal.getTime());
186 			readInt();
187 			record.setDistance(readInt() * 10);
188 			record.setAltitude(readSignedShort());
189 			record.setPulse(readUnsignedByte());
190 			record.setCadence(readSignedByte());
191 			record.setTemperature(readSignedByte());
192 			readSignedByte();
193 			readSignedByte();
194 			readSignedByte();
195 			tour.addRecord(record);
196 		}
197 		return record;
198 	}
199 
200 	int readUnsignedByte() throws IOException
201 	{
202 		char[] buffer = new char[1];
203 		if (in.read(buffer, 0, 1) == 1) {
204 			return (int)buffer[0];
205 		}
206 		else {
207 			throw new IOException("Unexpected end of file");
208 		} 
209 	}
210 
211 	private void readMarkers(Tour tour, int markerCount) 
212 	{
213 		// TODO: add marker
214 	}
215 
216 	int readSignedByte() throws IOException 
217 	{
218 		char[] buffer = new char[1];
219 		if (in.read(buffer, 0, 1) == 1) {
220 			return (byte)buffer[0];
221 		}
222 		else {
223 			throw new IOException("Unexpected end of file");
224 		} 
225 	}
226 
227 	int readSignedShort() throws IOException 
228 	{
229 		char[] buffer = new char[2];
230 		if (in.read(buffer, 0, 2) == 2) {
231 			return (short)(buffer[1] << 8 | buffer[0]);
232 		}
233 		else {
234 			throw new IOException("Unexpected end of file");
235 		} 
236 	}
237 
238 	long readUnsignedInt() throws IOException 
239 	{
240 		char[] buffer = new char[4];
241 		if (in.read(buffer, 0, 4) == 4) {
242 			return buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0];
243 		}
244 		else {
245 			throw new IOException("Unexpected end of file");
246 		} 
247 	}
248 
249 	int readInt() throws IOException 
250 	{
251 		char[] buffer = new char[4];
252 		if (in.read(buffer, 0, 4) == 4) {
253 			return buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0];
254 		}
255 		else {
256 			throw new IOException("Unexpected end of file");
257 		} 
258 	}
259 
260 	String readLine() throws IOException 
261 	{
262 		currentLine++;
263 		String line = in.readLine();
264 		if (line == null)  {
265 			throw new IOException("Unexpected end of file");
266 		}
267 		return line; 
268 	}
269 	
270 }