/* * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.traccar.helper; import java.util.Date; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Parser { private int position; private final Matcher matcher; public Parser(Pattern pattern, String input) { matcher = pattern.matcher(input); } public boolean matches() { position = 1; return matcher.matches(); } public boolean find() { position = 1; return matcher.find(); } public void skip(int number) { position += number; } public boolean hasNext() { return hasNext(1); } public boolean hasNext(int number) { String value = matcher.group(position); if (value != null && !value.isEmpty()) { return true; } else { position += number; return false; } } public String next() { return matcher.group(position++); } public Integer nextInt() { if (hasNext()) { return Integer.parseInt(next()); } else { return null; } } public int nextInt(int defaultValue) { if (hasNext()) { return Integer.parseInt(next()); } else { return defaultValue; } } public Integer nextHexInt() { if (hasNext()) { return Integer.parseInt(next(), 16); } else { return null; } } public int nextHexInt(int defaultValue) { if (hasNext()) { return Integer.parseInt(next(), 16); } else { return defaultValue; } } public Integer nextBinInt() { if (hasNext()) { return Integer.parseInt(next(), 2); } else { return null; } } public int nextBinInt(int defaultValue) { if (hasNext()) { return Integer.parseInt(next(), 2); } else { return defaultValue; } } public long nextLong(long defaultValue) { return nextLong(10, defaultValue); } public long nextLong(int radix, long defaultValue) { if (hasNext()) { return Long.parseLong(next(), radix); } else { return defaultValue; } } public Double nextDouble() { if (hasNext()) { return Double.parseDouble(next()); } else { return null; } } public double nextDouble(double defaultValue) { if (hasNext()) { return Double.parseDouble(next()); } else { return defaultValue; } } public enum CoordinateFormat { DEG_DEG, DEG_HEM, DEG_MIN_MIN, DEG_MIN_HEM, DEG_MIN_MIN_HEM, HEM_DEG_MIN_MIN, HEM_DEG, HEM_DEG_MIN, HEM_DEG_MIN_HEM } public double nextCoordinate(CoordinateFormat format) { double coordinate; String hemisphere = null; switch (format) { case DEG_DEG: coordinate = Double.parseDouble(next() + '.' + next()); break; case DEG_HEM: coordinate = nextDouble(0); hemisphere = next(); break; case DEG_MIN_MIN: coordinate = nextInt(0); coordinate += Double.parseDouble(next() + '.' + next()) / 60; break; case DEG_MIN_MIN_HEM: coordinate = nextInt(0); coordinate += Double.parseDouble(next() + '.' + next()) / 60; hemisphere = next(); break; case HEM_DEG: hemisphere = next(); coordinate = nextDouble(0); break; case HEM_DEG_MIN: hemisphere = next(); coordinate = nextInt(0); coordinate += nextDouble(0) / 60; break; case HEM_DEG_MIN_HEM: hemisphere = next(); coordinate = nextInt(0); coordinate += nextDouble(0) / 60; if (hasNext()) { hemisphere = next(); } break; case HEM_DEG_MIN_MIN: hemisphere = next(); coordinate = nextInt(0); coordinate += Double.parseDouble(next() + '.' + next()) / 60; break; case DEG_MIN_HEM: default: coordinate = nextInt(0); coordinate += nextDouble(0) / 60; hemisphere = next(); break; } if (hemisphere != null && (hemisphere.equals("S") || hemisphere.equals("W") || hemisphere.equals("-"))) { coordinate = -Math.abs(coordinate); } return coordinate; } public double nextCoordinate() { return nextCoordinate(CoordinateFormat.DEG_MIN_HEM); } public enum DateTimeFormat { HMS, SMH, HMS_YMD, HMS_DMY, SMH_YMD, SMH_DMY, DMY_HMS, DMY_HMSS, YMD_HMS, YMD_HMSS, } public Date nextDateTime(DateTimeFormat format, String timeZone) { int year = 0, month = 0, day = 0; int hour = 0, minute = 0, second = 0, millisecond = 0; switch (format) { case HMS: hour = nextInt(0); minute = nextInt(0); second = nextInt(0); break; case SMH: second = nextInt(0); minute = nextInt(0); hour = nextInt(0); break; case HMS_YMD: hour = nextInt(0); minute = nextInt(0); second = nextInt(0); year = nextInt(0); month = nextInt(0); day = nextInt(0); break; case HMS_DMY: hour = nextInt(0); minute = nextInt(0); second = nextInt(0); day = nextInt(0); month = nextInt(0); year = nextInt(0); break; case SMH_YMD: second = nextInt(0); minute = nextInt(0); hour = nextInt(0); year = nextInt(0); month = nextInt(0); day = nextInt(0); break; case SMH_DMY: second = nextInt(0); minute = nextInt(0); hour = nextInt(0); day = nextInt(0); month = nextInt(0); year = nextInt(0); break; case DMY_HMS: case DMY_HMSS: day = nextInt(0); month = nextInt(0); year = nextInt(0); hour = nextInt(0); minute = nextInt(0); second = nextInt(0); break; case YMD_HMS: case YMD_HMSS: default: year = nextInt(0); month = nextInt(0); day = nextInt(0); hour = nextInt(0); minute = nextInt(0); second = nextInt(0); break; } if (format == DateTimeFormat.YMD_HMSS || format == DateTimeFormat.DMY_HMSS) { millisecond = nextInt(0); // (ddd) } if (year >= 0 && year < 100) { year += 2000; } DateBuilder dateBuilder; if (format != DateTimeFormat.HMS && format != DateTimeFormat.SMH) { if (timeZone != null) { dateBuilder = new DateBuilder(TimeZone.getTimeZone(timeZone)); } else { dateBuilder = new DateBuilder(); } dateBuilder.setDate(year, month, day); } else { if (timeZone != null) { dateBuilder = new DateBuilder(new Date(), TimeZone.getTimeZone(timeZone)); } else { dateBuilder = new DateBuilder(new Date()); } } dateBuilder.setTime(hour, minute, second, millisecond); return dateBuilder.getDate(); } public Date nextDateTime(DateTimeFormat format) { return nextDateTime(format, null); } public Date nextDateTime() { return nextDateTime(DateTimeFormat.YMD_HMS, null); } }