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