1   /* Copyright 2002-2025 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.gnss.metric.ntrip;
18  
19  import java.util.ArrayList;
20  import java.util.List;
21  import java.util.regex.Matcher;
22  import java.util.regex.Pattern;
23  import java.util.stream.Collectors;
24  import java.util.stream.Stream;
25  
26  import org.hipparchus.util.FastMath;
27  
28  /** Data stream record in source table.
29   * @author Luc Maisonobe
30   * @since 11.0
31   */
32  public class DataStreamRecord extends Record {
33  
34      /** Pattern for delimiting messages. */
35      private static final Pattern SEPARATOR = Pattern.compile(",");
36  
37      /** Message pattern. */
38      private static final Pattern PATTERN = Pattern.compile("^([^()]+)(?:\\(([0-9]+)\\))?$");
39  
40      /** Data format. */
41      private final DataFormat format;
42  
43      /** Streamed messages. */
44      private final List<StreamedMessage> formatDetails;
45  
46      /** Carrier phase. */
47      private final CarrierPhase carrierPhase;
48  
49      /** Navigation systems. */
50      private final List<NavigationSystem> systems;
51  
52      /** Latitude (rad). */
53      private final double latitude;
54  
55      /** Longitude (rad). */
56      private final double longitude;
57  
58      /** Indicator for required NMEA. */
59      private final boolean nmeaRequired;
60  
61      /** Indicator for networked streams. */
62      private final boolean networked;
63  
64      /** Authentication method. */
65      private final Authentication authentication;
66  
67      /** Indicator for required fees. */
68      private final boolean fees;
69  
70      /** Bit rate. */
71      private int bitRate;
72  
73      /** Build a data stream record by parsing a source table line.
74       * @param line source table line
75       */
76      public DataStreamRecord(final String line) {
77          super(line);
78          this.format         = DataFormat.getDataFormat(getField(3));
79  
80          final String[] detailsFields = SEPARATOR.split(getField(4));
81          this.formatDetails           = new ArrayList<>(detailsFields.length);
82          for (final String field : detailsFields) {
83              if (!field.isEmpty()) {
84                  final Matcher matcher = PATTERN.matcher(field);
85                  if (matcher.matches() && matcher.start(2) >= 0) {
86                      formatDetails.add(new StreamedMessage(matcher.group(1),
87                                                            Integer.parseInt(matcher.group(2))));
88                  } else {
89                      formatDetails.add(new StreamedMessage(field, -1));
90                  }
91              }
92          }
93  
94          this.carrierPhase   = CarrierPhase.getCarrierPhase(getField(5));
95          this.systems        = Stream.
96                                of(getField(6).split("\\+")).
97                                map(NavigationSystem::getNavigationSystem).
98                                collect(Collectors.toList());
99          this.latitude       = FastMath.toRadians(Double.parseDouble(getField(9)));
100         this.longitude      = FastMath.toRadians(Double.parseDouble(getField(10)));
101         this.nmeaRequired   = Integer.parseInt(getField(11)) != 0;
102         this.networked      = Integer.parseInt(getField(12)) != 0;
103         this.authentication = Authentication.getAuthentication(getField(15));
104         this.fees           = getField(16).equals("Y");
105         this.bitRate        = Integer.parseInt(getField(17));
106     }
107 
108     /** {@inheritDoc} */
109     @Override
110     public RecordType getRecordType() {
111         return RecordType.STR;
112     }
113 
114     /** Get the mount point.
115      * @return mount point
116      */
117     public String getMountPoint() {
118         return getField(1);
119     }
120 
121     /** Get the source identifier.
122      * @return source identifier
123      */
124     public String getSourceIdentifier() {
125         return getField(2);
126     }
127 
128     /** Get the data format.
129      * @return data format
130      */
131     public DataFormat getFormat() {
132         return format;
133     }
134 
135     /** Get the format details.
136      * @return format details
137      */
138     public List<StreamedMessage> getFormatDetails() {
139         return formatDetails;
140     }
141 
142     /** Get the carrier phase.
143      * @return carrier phase
144      */
145     public CarrierPhase getCarrierPhase() {
146         return carrierPhase;
147     }
148 
149     /** Get the navigation systems.
150      * @return navigation systems
151      */
152     public List<NavigationSystem> getNavigationSystems() {
153         return systems;
154     }
155 
156     /** Get the network.
157      * @return network
158      */
159     public String getNetwork() {
160         return getField(7);
161     }
162 
163     /** Get the country.
164      * @return country
165      */
166     public String getCountry() {
167         return getField(8);
168     }
169 
170     /** Get the latitude.
171      * @return latitude (rad)
172      */
173     public double getLatitude() {
174         return latitude;
175     }
176 
177     /** Get the longitude.
178      * @return longitude (rad)
179      */
180     public double getLongitude() {
181         return longitude;
182     }
183 
184     /** Check if NMEA message must be sent to caster.
185      * @return true if NMEA message must be sent to caster
186      */
187     public boolean isNMEARequired() {
188         return nmeaRequired;
189     }
190 
191     /** Check if the stream is generated from a network of stations.
192      * @return true if stream  is generated from a network of stations
193      */
194     public boolean isNetworked() {
195         return networked;
196     }
197 
198     /** Get the hardware or software generator.
199      * @return hardware or software generator
200      */
201     public String getGenerator() {
202         return getField(13);
203     }
204 
205     /** Get the compression/encryption algorithm applied.
206      * @return compression/encryption algorithm applied
207      */
208     public String getCompressionEncryption() {
209         return getField(14);
210     }
211 
212     /** Get the authentication method.
213      * @return authentication method
214      */
215     public Authentication getAuthentication() {
216         return authentication;
217     }
218 
219     /** Check if fees are required.
220      * @return true if fees are required
221      */
222     public boolean areFeesRequired() {
223         return fees;
224     }
225 
226     /** Get the bit rate.
227      * @return bit rate
228      */
229     public int getBitRate() {
230         return bitRate;
231     }
232 
233 }