• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 #include "oscl_mem_basic_functions.h"
19 #include "oscl_snprintf.h"
20 #include "oscl_string_utils.h"
21 #include "oscl_str_ptr_len.h"
22 #include "oscl_string.h"
23 #include "rtsp_time_formats.h"
24 #include "rtsp_range_utils.h"
25 
26 
27 #include "oscl_dll.h"
28 OSCL_DLL_ENTRY_POINT_DEFAULT()
29 
30 
31 // don't make the max int size less than 6 -- it is
32 // used to size certain arrays below that need at least 6 characters
33 static const int  MAX_RANGE_INT_SIZE = 10;
34 
35 // keep the next two constants in sync.  The max range float
36 // size should be the number of digits plus the decimal point
37 static const int  MAX_RANGE_FLOAT_SIZE = 7;
38 static const char RANGE_FLOAT_FORMAT[] = "%0.6f";
39 
parse_range_integer(const char * start,const char * end,int max_digits,char * sep,uint32 & value)40 OSCL_EXPORT_REF const char * parse_range_integer(const char *start, const char *end,
41         int max_digits, char *sep, uint32& value)
42 {
43     const char *sptr, *eptr;
44     const char *endpoint;
45 
46     if (max_digits > 0 && ((end - start) > max_digits))
47     {
48         endpoint = start + max_digits;
49     }
50     else
51     {
52         endpoint = end;
53     }
54 
55     sptr = start;
56 
57     if (sep)
58     {
59         for (eptr = sptr; eptr < endpoint &&
60                 *eptr != *sep ; ++eptr);
61     }
62     else
63     {
64         eptr = endpoint;
65     }
66 
67     // get the hours
68     uint32 tmp;
69     if (PV_atoi(sptr, 'd',  eptr - sptr, tmp) == false)
70     {
71         return NULL;
72     }
73 
74     value = tmp;
75     return eptr;
76 
77 }
78 
parse_smpte_format(const char * start_ptr,const char * end_ptr,RtspRangeType::RtspRangeFormat format,SmpteTimeFormat & smpte_range)79 OSCL_EXPORT_REF bool parse_smpte_format(const char* start_ptr, const char *end_ptr,
80                                         RtspRangeType::RtspRangeFormat format,
81                                         SmpteTimeFormat& smpte_range)
82 {
83 
84     // get required HH:MM:SS values
85     const char *sptr;
86 
87     sptr = start_ptr;
88     uint32 tmp;
89     char sep;
90 
91     sep = ':';
92     sptr = parse_range_integer(sptr, end_ptr,
93                                2, &sep, tmp);
94 
95     if (!sptr || *sptr != ':')
96     {
97         return false;
98     }
99 
100     smpte_range.hours = (uint8)tmp;
101 
102     // get the minutes
103     sptr = parse_range_integer(sptr + 1, end_ptr,
104                                2, &sep, tmp);
105 
106     if (!sptr || *sptr != ':')
107     {
108         return false;
109     }
110 
111     if (tmp > 59)
112     {
113         return false;
114     }
115 
116     smpte_range.minutes = (uint8)tmp;
117 
118     // get the seconds
119     sptr = parse_range_integer(sptr + 1, end_ptr,
120                                2, &sep, tmp);
121 
122     if (!sptr)
123     {
124         return false;
125     }
126 
127     if (tmp > 59)
128     {
129         return false;
130     }
131 
132     smpte_range.seconds = (uint8)tmp;
133 
134     // now see if there there are any optional fields
135     if (*sptr == ':')
136     {
137         // get the number of frames
138         sep = '.';
139         sptr = parse_range_integer(sptr + 1, end_ptr,
140                                    2, &sep, tmp);
141 
142         if (!sptr)
143         {
144             return false;
145         }
146 
147         if (format == RtspRangeType::SMPTE_25_RANGE &&
148                 tmp > 25)
149         {
150             return false;
151         }
152         else if (tmp > 30)
153         {
154             return false;
155         }
156 
157         smpte_range.frames = (uint8)tmp;
158 
159         // now check for optional subframes
160         if (*sptr == '.')
161         {
162             // get the number of subframes
163             sptr = parse_range_integer(sptr + 1, end_ptr,
164                                        2, NULL, tmp);
165 
166             if (!sptr)
167             {
168                 return false;
169             }
170 
171             if (tmp > 99)
172             {
173                 return false;
174             }
175 
176             smpte_range.subframes = (uint8)tmp;
177         }
178         else
179         {
180             smpte_range.subframes = 0;
181         }
182 
183     }
184     else
185     {
186         smpte_range.frames = 0;
187         smpte_range.subframes = 0;
188     }
189 
190     return true;
191 }
192 
parse_npt_format(const char * start_ptr,const char * end_ptr,NptTimeFormat & npt_range)193 OSCL_EXPORT_REF bool parse_npt_format(const char* start_ptr, const char *end_ptr,
194                                       NptTimeFormat& npt_range)
195 {
196 
197     // get required HH:MM:SS values
198     const char *sptr, *eptr;
199     uint32 tmp;
200 
201     sptr = start_ptr;
202 
203     StrPtrLen now_str("now");
204     if (!oscl_strncmp(sptr, now_str.c_str(), now_str.length()))
205     {
206         // this is the "now" keyword
207         npt_range.npt_format = NptTimeFormat::NOW;
208         return true;
209     }
210 
211     // see if the format contains a ':' separator character
212     for (eptr = sptr; eptr < end_ptr && *eptr != ':'; ++eptr);
213 
214     if (*eptr == ':')
215     {
216         // this is the npt-hhmmss format
217 
218         char sep = ':';
219         // get the number of hours
220         sptr = parse_range_integer(sptr, eptr,
221                                    0, &sep, tmp);
222 
223         if (!sptr)
224         {
225             return false;
226         }
227 
228         npt_range.npt_format = NptTimeFormat::NPT_HHMMSS;
229         npt_range.npt_hhmmss.hours = tmp;
230 
231 
232         // get the number of minutes
233         sptr = parse_range_integer(sptr + 1, end_ptr,
234                                    2, &sep, tmp);
235 
236         if (!sptr || *sptr != ':')
237         {
238             return false;
239         }
240 
241         if (tmp > 59)
242         {
243             return false;
244         }
245 
246         npt_range.npt_hhmmss.min = (uint8)tmp;
247 
248 
249         sep = '.';
250         // get the number of seconds
251         sptr = parse_range_integer(sptr + 1, end_ptr,
252                                    2, &sep, tmp);
253 
254         if (!sptr)
255         {
256             return false;
257         }
258 
259         if (tmp > 59)
260         {
261             return false;
262         }
263 
264         npt_range.npt_hhmmss.sec = (uint8)tmp;
265 
266         npt_range.npt_hhmmss.frac_sec = 0;
267         // determine if the fractional seconds exists
268         if (*sptr == '.')
269         {
270             // get the fractional seconds
271             const int MAX_TMP_BUFSIZE = 12;
272             char tmpbuf[MAX_TMP_BUFSIZE];
273             int copy_size;
274 
275             eptr = skip_to_whitespace(sptr, end_ptr);
276 
277             copy_size = eptr - sptr;
278             if (copy_size > MAX_TMP_BUFSIZE - 1)
279             {
280                 copy_size = MAX_TMP_BUFSIZE - 1;
281             }
282 
283             oscl_strncpy(tmpbuf, sptr, copy_size);
284 
285             tmpbuf[copy_size] = '\0';
286 
287             if (!PV_atof(tmpbuf, npt_range.npt_hhmmss.frac_sec))
288                 return false;
289 
290         }
291 
292     } // end if the format is NPT_HHMMSS
293 
294     else
295     {
296 
297         char sep = '.';
298         // this is the NPT_SEC format
299         npt_range.npt_format = NptTimeFormat::NPT_SEC;
300 
301         // get the number of seconds
302         sptr = parse_range_integer(sptr, eptr,
303                                    0, &sep, tmp);
304 
305         if (!sptr)
306         {
307             return false;
308         }
309 
310         npt_range.npt_sec.sec = tmp;
311 
312         npt_range.npt_sec.milli_sec = 0;
313         if (*sptr == '.')
314         {
315             // there is an optional fractional seconds field
316 
317             // get the fractional seconds
318             const int MAX_TMP_BUFSIZE = 12;
319             char tmpbuf[MAX_TMP_BUFSIZE];
320             int copy_size;
321 
322             eptr = skip_to_whitespace(sptr, end_ptr);
323 
324             copy_size = eptr - sptr;
325 
326             if (copy_size > MAX_TMP_BUFSIZE - 1)
327             {
328                 copy_size = MAX_TMP_BUFSIZE - 1;
329             }
330 
331             oscl_strncpy(tmpbuf, sptr, copy_size);
332 
333 
334             tmpbuf[copy_size] = '\0';
335 
336             OsclFloat tmp_fnum;
337             if (!PV_atof(tmpbuf, tmp_fnum))
338                 return false;
339             npt_range.npt_sec.milli_sec = (uint32)(1000.0 * tmp_fnum + 0.5);
340         }
341 
342     } // end if the format is NPT_SEC
343 
344     return true;
345 }
346 
347 
parse_abs_format(const char * start_ptr,const char * end_ptr,AbsTimeFormat & abs_range)348 OSCL_EXPORT_REF bool parse_abs_format(const char* start_ptr, const char *end_ptr,
349                                       AbsTimeFormat& abs_range)
350 {
351 
352     // get format YYYYMMDDT
353     const char *sptr, *eptr;
354     char sep;
355     uint32 tmp;
356 
357     sptr = start_ptr;
358 
359     // check if the ninth character is a "T"
360     eptr = sptr + 8;
361 
362     sep = 'T';
363     if (eptr >= end_ptr || *eptr != sep)
364     {
365         return false;
366     }
367 
368     sptr = parse_range_integer(sptr, eptr,
369                                4, &sep, tmp);
370 
371     if (! sptr || tmp > 9999)
372     {
373         return false;
374     }
375 
376     abs_range.year = (uint16)tmp;
377 
378     // get the month
379     sptr = parse_range_integer(sptr, eptr,
380                                2, &sep, tmp);
381 
382     if (! sptr || tmp == 0 || tmp > 12)
383     {
384         return false;
385     }
386 
387     abs_range.month = (uint8)tmp;
388 
389     // get the day
390     sptr = parse_range_integer(sptr, eptr,
391                                2, &sep, tmp);
392 
393     if (! sptr || tmp == 0 || tmp > 31)
394     {
395         return false;
396     }
397 
398     abs_range.day = (uint8)tmp;
399 
400 
401     sptr = eptr + 1;
402     eptr = sptr + 6;
403 
404     if (eptr >= end_ptr || (*eptr != 'Z' && *eptr != '.'))
405     {
406         return false;
407     }
408 
409     // get the hours
410     sptr = parse_range_integer(sptr, eptr,
411                                2, NULL, tmp);
412 
413     if (! sptr || tmp > 23)
414     {
415         return false;
416     }
417 
418     abs_range.hours = (uint8)tmp;
419 
420     // get the minutes
421     sptr = parse_range_integer(sptr, eptr,
422                                2, NULL, tmp);
423 
424     if (! sptr || tmp > 59)
425     {
426         return false;
427     }
428 
429     abs_range.min = (uint8)tmp;
430 
431     // get the number of seconds
432     sptr = parse_range_integer(sptr, eptr,
433                                2, NULL, tmp);
434 
435     if (! sptr || tmp > 59)
436     {
437         return false;
438     }
439 
440     abs_range.sec = (uint8)tmp;
441 
442     abs_range.frac_sec = 0;
443 
444     if (*eptr == '.')
445     {
446         // get the fractional seconds
447         // get the fractional seconds
448         const int MAX_TMP_BUFSIZE = 12;
449         char tmpbuf[MAX_TMP_BUFSIZE];
450         int copy_size;
451 
452         sptr = eptr;
453 
454         for (eptr = sptr; eptr < end_ptr && *eptr != 'Z';
455                 ++eptr);
456 
457         if (*eptr != 'Z')
458         {
459             return false;
460         }
461 
462         copy_size = eptr - sptr;
463         if (copy_size > MAX_TMP_BUFSIZE - 1)
464         {
465             copy_size = MAX_TMP_BUFSIZE - 1;
466         }
467 
468         oscl_strncpy(tmpbuf, sptr, copy_size);
469 
470         tmpbuf[copy_size] = '\0';
471 
472         if (!PV_atof(tmpbuf, abs_range.frac_sec))
473             return false;
474 
475     }
476 
477     return true;
478 }
479 
480 
parseRtspRange(const char * rangeString,int length,RtspRangeType & range)481 OSCL_EXPORT_REF bool parseRtspRange(const char *rangeString, int length, RtspRangeType& range)
482 {
483     const char *end = rangeString + length;
484 
485     const char* sptr, *eptr;
486 
487     // initialize range to invalid format
488     range.format = RtspRangeType::INVALID_RANGE;
489 
490     // find the first word before the "="
491     sptr = skip_whitespace_and_line_term(rangeString, end);
492     if (sptr >= end)
493     {
494         return false;
495     }
496 
497     for (eptr = sptr; eptr < end &&
498             (*eptr != '=' && *eptr != ':' && *eptr != ' ' && *eptr != '\t');
499             ++eptr);
500 
501 
502     StrPtrLen smpte_type("smpte");
503     StrPtrLen smpte25_type("smpte-25");
504     StrPtrLen smpte30_type("smpte-30-drop");
505     StrPtrLen npt_type("npt");
506     StrPtrLen abs_type("clock");
507 //#ifdef RTSP_PLAYLIST_SUPPORT
508     StrPtrLen playlist_play_time_type("playlist_play_time");
509 //#endif //#ifdef RTSP_PLAYLIST_SUPPORT
510 
511     if (!oscl_strncmp(sptr, smpte_type.c_str(), eptr - sptr) ||
512             !oscl_strncmp(sptr, smpte25_type.c_str(), eptr - sptr) ||
513             !oscl_strncmp(sptr, smpte30_type.c_str(), eptr - sptr))
514     {
515         // Parsing one of the SMPTE time formats
516 
517         // save the exact format temporarily
518         RtspRangeType::RtspRangeFormat tmp_format;
519         if (!oscl_strncmp(sptr, smpte30_type.c_str(), smpte30_type.length()))
520         {
521             tmp_format = RtspRangeType::SMPTE_30_RANGE;
522         }
523         else if (!oscl_strncmp(sptr, smpte25_type.c_str(), smpte25_type.length()))
524         {
525             tmp_format = RtspRangeType::SMPTE_25_RANGE;
526         }
527         else
528         {
529             tmp_format = RtspRangeType::SMPTE_RANGE;
530         }
531 
532         // skip ahead to beyond the "="
533         if (*eptr != '=')
534         {
535             for (; eptr < end && *eptr != '='; ++eptr);
536         }
537 
538         sptr = skip_whitespace(eptr + 1, end);
539         if (sptr >= end)
540         {
541             return false;
542         }
543 
544         // find the start/end separator
545         for (eptr = sptr; eptr < end &&
546                 (*eptr != '-'); ++eptr);
547 
548         if (*eptr != '-')
549         {
550             return false;
551         }
552 
553         range.start_is_set = false;
554         if (eptr > sptr)
555         {
556             // there is a start time
557 
558             if (parse_smpte_format(sptr, eptr, tmp_format, range.smpte_start) == false)
559             {
560                 return false;
561             }
562 
563             // now set the appropriate flags
564             range.start_is_set = true;
565         }
566 
567         // see if there is a stop time
568         sptr = skip_whitespace_and_line_term(eptr + 1, end);
569         range.end_is_set = false;
570         if (sptr < end)
571         {
572             // there is a stop time specification
573             eptr = skip_to_whitespace(sptr, end);
574 
575             if (parse_smpte_format(sptr, eptr, tmp_format, range.smpte_end)
576                     == false)
577             {
578                 return false;
579             }
580 
581             // now set the appropriate flags
582             range.end_is_set = true;
583         }
584 
585         // now set the appropriate range format
586         range.format = tmp_format;
587 
588     } // end if this is an SMPTE time format
589 
590     else if (!oscl_strncmp(sptr, npt_type.c_str(), eptr - sptr))
591     {
592 
593         // skip ahead to beyond the "=" or ":"
594         if (*eptr != '=')
595         {
596             for (; eptr < end && *eptr != '=' && *eptr != ':'; ++eptr);
597         }
598 
599         sptr = skip_whitespace(eptr + 1, end);
600         if (sptr >= end)
601         {
602             return false;
603         }
604 
605         // find the start/end separator
606         for (eptr = sptr; eptr < end &&
607                 (*eptr != '-'); ++eptr);
608 
609         if (*eptr != '-')
610         {
611             return false;
612         }
613 
614         range.start_is_set = false;
615         if (eptr > sptr)
616         {
617             // there is a start time
618             if (parse_npt_format(sptr, eptr, range.npt_start) == false)
619             {
620                 return false;
621             }
622 
623             // now set the appropriate flags
624             range.start_is_set = true;
625 
626         }
627 
628         // see if there is a stop time
629         range.end_is_set = false;
630         sptr = skip_whitespace_and_line_term(eptr + 1, end);
631         if (sptr < end)
632         {
633             // there is a stop time specification
634             eptr = skip_to_whitespace(sptr, end);
635 
636             if (parse_npt_format(sptr, eptr, range.npt_end)
637                     == false)
638             {
639                 return false;
640             }
641 
642             // now set the appropriate flags
643             range.end_is_set = true;
644         }
645 
646         // now set the appropriate range format
647         range.format = RtspRangeType::NPT_RANGE;
648 
649     } // end if this is an NPT time format
650 
651     else if (!oscl_strncmp(sptr, abs_type.c_str(), eptr - sptr))
652     {
653 
654 
655         // skip ahead to beyond the "="
656         if (*eptr != '=')
657         {
658             for (; eptr < end && *eptr != '='; ++eptr);
659         }
660 
661         sptr = skip_whitespace(eptr + 1, end);
662         if (sptr >= end)
663         {
664             return false;
665         }
666 
667         // find the start/end separator
668         for (eptr = sptr; eptr < end &&
669                 (*eptr != '-'); ++eptr);
670 
671         if (*eptr != '-')
672         {
673             return false;
674         }
675 
676         range.start_is_set = false;
677         if (eptr > sptr)
678         {
679             // there is a start time
680             if (parse_abs_format(sptr, eptr, range.abs_start) == false)
681             {
682                 return false;
683             }
684 
685             // now set the appropriate flags
686             range.start_is_set = true;
687 
688         }
689 
690         // see if there is a stop time
691         sptr = skip_whitespace_and_line_term(eptr + 1, end);
692         range.end_is_set = true;
693         if (sptr < end)
694         {
695             // there is a stop time specification
696             eptr = skip_to_whitespace(sptr, end);
697 
698             if (parse_abs_format(sptr, eptr, range.abs_end)
699                     == false)
700             {
701                 return false;
702             }
703 
704             // now set the appropriate flags
705             range.end_is_set = true;
706         }
707 
708         // now set the appropriate range format
709         range.format = RtspRangeType::ABS_RANGE;
710 
711     } // end if this is an ABS time format
712 //#ifdef RTSP_PLAYLIST_SUPPORT
713     // for Range:playlist_play_time=<URN,clipIndex,clipOffset>
714     //playlist_play_time=</public/playlist/va_playlists/test.ply,3,0.0>;npt=194.81542
715     else if (!oscl_strncmp(sptr, playlist_play_time_type.c_str(), eptr - sptr))
716     {
717         // store the whole string since we may not need the parsed version of things
718         //oscl_memcpy(range.iPlaylistPlayStr,rangeString,length);
719         //range.iPlaylistPlayStr[length] = '\0';
720 
721         range.format = RtspRangeType::PLAYLIST_TIME_RANGE;
722         range.start_is_set = range.end_is_set = false;
723 
724         // now set the appropriate flags
725         range.start_is_set = true;
726 
727         // skip ahead to beyond the "="
728         if (*eptr != '=')
729         {
730             for (; eptr < end && *eptr != '='; ++eptr);
731         }
732 
733         sptr = skip_whitespace(eptr + 1, end);
734         if (sptr >= end)
735         {
736             return false;
737         }
738 
739         // next should be the opening "<"
740         // skip ahead to beyond the "<"
741         if (*eptr != '<')
742         {
743             for (; eptr < end && *eptr != '<'; ++eptr);
744         }
745 
746         sptr = skip_whitespace(eptr + 1, end);
747         if (sptr >= end)
748         {
749             return false;
750         }
751 
752         // find the comma separator
753         for (eptr = sptr; eptr < end &&
754                 (*eptr != ','); ++eptr);
755 
756         if (*eptr != ',')
757         {
758             return false;
759         }
760 
761         // first the urn
762         if (eptr > sptr)
763         {
764             // there is a urn
765             if (oscl_memcpy(range.iPlaylistUrl, sptr, eptr - sptr) == false)
766             {
767                 return false;
768             }
769             //range.iUrn[(eptr-sptr)+1] = '\0';
770             range.iPlaylistUrl[eptr-sptr] = '\0';
771         }
772 
773         // now the clipIndex
774         sptr = skip_whitespace(eptr + 1, end);
775         if (sptr >= end)
776         {
777             return false;
778         }
779 
780         // find the next comma separator
781         for (eptr = sptr; eptr < end &&
782                 (*eptr != ','); ++eptr);
783 
784         if (*eptr != ',')
785         {
786             return false;
787         }
788 
789         // now the clipIndex
790         if (eptr > sptr)
791         {
792             // there is a clipIndex
793             uint32 tmp;
794             if (PV_atoi(sptr, 'd', eptr - sptr, tmp) == false)
795             {
796                 return false;
797             }
798             range.playlist_start.iClipIndex = (int32)tmp;
799         }
800 
801         // now the clipOffset
802         sptr = skip_whitespace(eptr + 1, end);
803         if (sptr >= end)
804         {
805             return false;
806         }
807 
808         // find the final '>' separator or the final possible '.' in offset
809         //<sec>.<frac>
810         for (eptr = sptr; eptr < end &&
811                 (*eptr != '>') && (*eptr != '.'); ++eptr);
812 
813         if (eptr >= end)
814         {
815             return false;
816         }
817 
818         // @todo ignore the factional part for now
819         // now the clipOffset
820         if (eptr > sptr)
821         {
822             // there is a clipOffset
823             uint32 tmp;
824             if (PV_atoi(sptr, 'd', eptr - sptr, tmp) == false)
825             {
826                 return false;
827             }
828             range.playlist_start.sec = (int32)tmp;
829 
830             {
831                 range.playlist_start.milli_sec = 0;
832                 if (*eptr == '.')
833                 {
834                     // there is an optional fractional seconds field
835 
836                     // get the fractional seconds
837                     const int MAX_TMP_BUFSIZE = 12;
838                     char tmpbuf[MAX_TMP_BUFSIZE];
839                     int copy_size;
840 
841                     eptr = skip_to_whitespace(sptr, end);
842 
843                     copy_size = eptr - sptr;
844 
845                     if (copy_size > MAX_TMP_BUFSIZE - 1)
846                     {
847                         copy_size = MAX_TMP_BUFSIZE - 1;
848                     }
849 
850                     oscl_strncpy(tmpbuf, sptr, copy_size);
851 
852 
853                     tmpbuf[copy_size] = '\0';
854 
855                     OsclFloat tmp_fnum;
856                     if (!PV_atof(tmpbuf, tmp_fnum))
857                         return false;
858                     range.playlist_start.milli_sec = (uint32)(1000.0 * tmp_fnum + 0.5);
859                 }
860             }
861         }
862     }  // end if this is a playlist_play_time format, for response to playlist_play commands
863 //#endif //#ifdef RTSP_PLAYLIST_SUPPORT
864     else
865     {
866         /*Unsupported time format*/
867         range.format = RtspRangeType::UNKNOWN_RANGE;
868         range.start_is_set = false;
869         range.end_is_set = false;
870         return false;
871     }
872 
873     return true;
874 }
875 
estimate_SDP_string_len(const NptTimeFormat & npt_range)876 OSCL_EXPORT_REF int estimate_SDP_string_len(const NptTimeFormat& npt_range)
877 {
878     int total_len = 0;
879 
880 
881     switch (npt_range.npt_format)
882     {
883         case NptTimeFormat::NOW:
884             total_len += 3; // enough for "now"
885             break;
886 
887         case NptTimeFormat::NPT_SEC:
888             // compute the size for the sec field
889             if (npt_range.npt_sec.sec < 1000)
890             {
891                 total_len += 3; // enough for at most 3 digits
892             }
893             else if (npt_range.npt_sec.sec < 1000000)
894             {
895                 total_len += 6; // enough for 6 digits
896             }
897             else
898             {
899                 total_len += 10; // enough for MAX_INT of uint32
900             }
901 
902             if (npt_range.npt_sec.milli_sec > 0.0)
903             {
904                 total_len += MAX_RANGE_FLOAT_SIZE; // includes "." and all digits
905             }
906             break;
907 
908         case NptTimeFormat::NPT_HHMMSS:
909             if (npt_range.npt_hhmmss.hours < 1000)
910             {
911                 total_len += 3; // enough for at most 3 digits
912             }
913             else if (npt_range.npt_hhmmss.hours < 1000000)
914             {
915                 total_len += 6; // enough for 6 digits
916             }
917             else
918             {
919                 total_len += 10; // enough for MAX_INT of uint32
920             }
921 
922             total_len += 6; // enough for ":MM:SS"
923 
924             if (npt_range.npt_hhmmss.frac_sec > 0.0)
925             {
926                 total_len += MAX_RANGE_FLOAT_SIZE; // includes "." and all digits
927             }
928             break;
929     }
930 
931     return total_len;
932 }
933 
934 
estimate_SDP_string_len(const RtspRangeType & range)935 OSCL_EXPORT_REF int estimate_SDP_string_len(const RtspRangeType& range)
936 {
937     // this function computes the string size necessary for
938     // holding the SDP string representation of the range
939 
940     int total_len = 0;
941 
942     total_len += 8 ; // this the length of the "a=range:" string
943 
944     switch (range.format)
945     {
946 
947         case RtspRangeType::NPT_RANGE:
948             total_len += 4; // this is the length of the "npt=" string
949 
950             if (range.start_is_set)
951             {
952                 total_len += estimate_SDP_string_len(range.npt_start);
953             }
954             else if (!range.end_is_set)
955             {
956                 // return 0 in this case
957                 return 0;
958             }
959 
960             total_len += 1; // enough for "-"
961 
962             if (range.end_is_set)
963             {
964                 total_len += estimate_SDP_string_len(range.npt_end);
965             }
966 
967             total_len += 2; // enough for CRLF at the end of the line
968 
969             break;
970 
971 
972         case RtspRangeType::SMPTE_RANGE:
973         case RtspRangeType::SMPTE_25_RANGE:
974         case RtspRangeType::SMPTE_30_RANGE:
975             if (range.format == RtspRangeType::SMPTE_30_RANGE)
976             {
977                 total_len += 14; // this is the length of the "smpte-30-drop=" string
978             }
979             else if (range.format == RtspRangeType::SMPTE_25_RANGE)
980             {
981                 total_len += 9; // this is the length of the "smpte-25=" string
982             }
983             else
984             {
985                 total_len += 6; // this is enough for "smpte="
986             }
987 
988             if (range.start_is_set)
989             {
990                 total_len += 8; // enough for "XX:YY:ZZ"
991                 if (range.smpte_start.frames || range.smpte_start.subframes)
992                 {
993                     total_len += 3; // enough for ":FF"
994                     if (range.smpte_start.subframes)
995                     {
996                         total_len += 3; // enough for ".SS"
997                     }
998                 }
999             }
1000             else if (!range.end_is_set)
1001             {
1002                 // return 0 in this case
1003                 return 0;
1004             }
1005 
1006             total_len += 1; // enough for "-"
1007 
1008             if (range.end_is_set)
1009             {
1010                 total_len += 8; // enough for "XX:YY:ZZ"
1011                 if (range.smpte_end.frames || range.smpte_end.subframes)
1012                 {
1013                     total_len += 3; // enough for ":FF"
1014                     if (range.smpte_end.subframes)
1015                     {
1016                         total_len += 3; // enough for ".SS"
1017                     }
1018                 }
1019             }
1020 
1021             total_len += 2; // enough for CRLF at the end of the line
1022 
1023             break;
1024 
1025         case RtspRangeType::ABS_RANGE:
1026 
1027             total_len += 6; // this is the length of the "clock=" string
1028 
1029             if (range.start_is_set)
1030             {
1031                 total_len += 15; // enough for "YYYYMMDDTHHMMSS"
1032                 if (range.abs_start.frac_sec > 0.0)
1033                 {
1034                     total_len += MAX_RANGE_FLOAT_SIZE; // includes "." and all digits
1035                 }
1036                 total_len += 1; // enough for the "Z"
1037             }
1038             else if (!range.end_is_set)
1039             {
1040                 // return 0 in this case
1041                 return 0;
1042             }
1043 
1044             total_len += 1; // enough for "-"
1045 
1046             if (range.end_is_set)
1047             {
1048                 total_len += 15; // enough for "YYYYMMDDTHHMMSS"
1049                 if (range.abs_end.frac_sec > 0.0)
1050                 {
1051                     total_len += MAX_RANGE_FLOAT_SIZE; // includes "." and all digits
1052                 }
1053                 total_len += 1; // enough for the "Z"
1054             }
1055 
1056             total_len += 2; // enough for CRLF at the end of the line
1057 
1058             break;
1059 
1060 
1061         default:
1062             return 0;
1063             break;
1064     }
1065 
1066     return total_len;
1067 }
1068 
1069 
1070 
compose_range_string(char * str,unsigned int max_len,const NptTimeFormat & npt_range,int & len_used)1071 OSCL_EXPORT_REF bool compose_range_string(char *str, unsigned int max_len,
1072         const NptTimeFormat& npt_range,
1073         int& len_used)
1074 {
1075     len_used = 0;
1076     int length;
1077 
1078 
1079     switch (npt_range.npt_format)
1080     {
1081         case NptTimeFormat::NOW:
1082         {
1083             StrPtrLen now_str("now");
1084             if ((int)max_len < now_str.length())
1085             {
1086                 return false;
1087             }
1088             oscl_memcpy(str, now_str.c_str(), now_str.length());
1089             str += now_str.length();
1090             len_used += now_str.length();
1091             max_len -= now_str.length();
1092             break;
1093         }
1094 
1095         case NptTimeFormat::NPT_SEC:
1096         {
1097             char tmpstr[MAX_RANGE_INT_SIZE + 1];
1098             length = oscl_snprintf(tmpstr, MAX_RANGE_INT_SIZE + 1, "%d",
1099                                    npt_range.npt_sec.sec);
1100             if (length < 0 || length > MAX_RANGE_INT_SIZE)
1101             {
1102                 return false;
1103             }
1104             if (length > (int) max_len)
1105             {
1106                 return false;
1107             }
1108             oscl_memcpy(str, tmpstr, length);
1109             str += length;
1110             len_used += length;
1111             max_len -= length;
1112             if (npt_range.npt_sec.milli_sec > 0.0)
1113             {
1114                 if (npt_range.npt_sec.milli_sec >= 1.0)
1115                 {
1116                     return false;
1117                 }
1118                 char tmp[MAX_RANGE_FLOAT_SIZE + 2];
1119                 length = oscl_snprintf(tmp, MAX_RANGE_FLOAT_SIZE + 2, RANGE_FLOAT_FORMAT,
1120                                        npt_range.npt_sec.milli_sec);
1121                 if (length < 0 || length > MAX_RANGE_FLOAT_SIZE + 1)
1122                 {
1123                     return false;
1124                 }
1125                 if (length > (int)max_len || tmp[1] != '.')
1126                 {
1127                     return false;
1128                 }
1129 
1130                 oscl_memcpy(str, tmp + 1, length - 1);
1131                 str += length - 1;
1132                 len_used += length - 1;
1133                 max_len -= (length - 1);
1134             }
1135 
1136             break;
1137         }
1138 
1139         case NptTimeFormat::NPT_HHMMSS:
1140         {
1141             char tmpstr[MAX_RANGE_INT_SIZE + 1];
1142             length = oscl_snprintf(tmpstr, MAX_RANGE_INT_SIZE + 1, "%d",
1143                                    npt_range.npt_hhmmss.hours);
1144             if (length < 0 || length >= MAX_RANGE_INT_SIZE)
1145             {
1146                 return false;
1147             }
1148             if (length > (int) max_len)
1149             {
1150                 return false;
1151             }
1152             oscl_memcpy(str, tmpstr, length);
1153             str += length;
1154             len_used += length;
1155             max_len -= length;
1156 
1157             if (max_len < 6)
1158             {
1159                 return false;
1160             }
1161 
1162             length = oscl_snprintf(tmpstr, MAX_RANGE_INT_SIZE + 1, ":%02d:%02d",
1163                                    npt_range.npt_hhmmss.min, npt_range.npt_hhmmss.sec);
1164             if (length != 6)
1165             {
1166                 return false;
1167             }
1168 
1169             oscl_memcpy(str, tmpstr, length);
1170             str += length;
1171             len_used += length;
1172             max_len -= length;
1173 
1174 
1175             if (npt_range.npt_hhmmss.frac_sec > 0.0)
1176             {
1177                 if (npt_range.npt_hhmmss.frac_sec >= 1.0)
1178                 {
1179                     return false;
1180                 }
1181                 char tmp[MAX_RANGE_FLOAT_SIZE + 2];
1182                 length = oscl_snprintf(tmp, MAX_RANGE_FLOAT_SIZE + 2, RANGE_FLOAT_FORMAT,
1183                                        npt_range.npt_hhmmss.frac_sec);
1184                 if (length < 0 || length > MAX_RANGE_FLOAT_SIZE + 1)
1185                 {
1186                     return false;
1187                 }
1188                 if (length > (int) max_len || tmp[1] != '.')
1189                 {
1190                     return false;
1191                 }
1192 
1193                 oscl_memcpy(str, tmp + 1, length - 1);
1194                 str += length - 1;
1195                 len_used += length - 1;
1196                 max_len -= (length - 1);
1197             }
1198 
1199             break;
1200         }
1201 
1202     }
1203 
1204     return true;
1205 
1206 }
1207 
1208 
compose_range_string(char * str,unsigned int max_len,const SmpteTimeFormat & smpte_range,int & len_used)1209 OSCL_EXPORT_REF bool compose_range_string(char *str, unsigned int max_len,
1210         const SmpteTimeFormat& smpte_range,
1211         int& len_used)
1212 {
1213     len_used = 0;
1214     int length;
1215 
1216 
1217     char tmp[10];
1218 
1219     if (max_len < 8)
1220     {
1221         return false;
1222     }
1223 
1224     length = oscl_snprintf(tmp, 9, "%02d:%02d:%02d", smpte_range.hours,
1225                            smpte_range.minutes, smpte_range.seconds);
1226 
1227     if (length != 8)
1228     {
1229         return false;
1230     }
1231 
1232     oscl_memcpy(str, tmp , length);
1233     str += length;
1234     len_used += length;
1235     max_len -= length;
1236 
1237     if (smpte_range.frames)
1238     {
1239         if (max_len < 3)
1240         {
1241             return 0;
1242         }
1243         length = oscl_snprintf(tmp, 4, ":%02d", smpte_range.frames);
1244         if (length != 3)
1245         {
1246             return false;
1247         }
1248 
1249         oscl_memcpy(str, tmp , length);
1250         str += length;
1251         len_used += length;
1252         max_len -= length;
1253     }
1254 
1255     if (smpte_range.subframes)
1256     {
1257         if (max_len < 3)
1258         {
1259             return 0;
1260         }
1261         length = oscl_snprintf(tmp, 4, ".%02d", smpte_range.subframes);
1262         if (length != 3)
1263         {
1264             return false;
1265         }
1266 
1267         oscl_memcpy(str, tmp , length);
1268         str += length;
1269         len_used += length;
1270         max_len -= length;
1271     }
1272 
1273     return true;
1274 
1275 }
1276 
1277 
compose_range_string(char * str,unsigned int max_len,const AbsTimeFormat & abs_range,int & len_used)1278 OSCL_EXPORT_REF bool compose_range_string(char *str, unsigned int max_len,
1279         const AbsTimeFormat& abs_range,
1280         int& len_used)
1281 {
1282     len_used = 0;
1283     int length;
1284 
1285 
1286     char tmp[17];
1287 
1288     if (max_len < 16)
1289     {
1290         return false;
1291     }
1292 
1293     length = oscl_snprintf(tmp, 17, "%04d%02d%02dT%02d%02d%02d",
1294                            abs_range.year, abs_range.month, abs_range.day,
1295                            abs_range.hours, abs_range.min, abs_range.sec);
1296 
1297     if (length != 15)
1298     {
1299         return false;
1300     }
1301 
1302     oscl_memcpy(str, tmp , length);
1303     str += length;
1304     len_used += length;
1305     max_len -= length;
1306 
1307     if (abs_range.frac_sec > 0.0)
1308     {
1309         if (abs_range.frac_sec >= 1.0)
1310         {
1311             return false;
1312         }
1313         char tmpstr[MAX_RANGE_FLOAT_SIZE + 2];
1314         length = oscl_snprintf(tmpstr, MAX_RANGE_FLOAT_SIZE + 2, RANGE_FLOAT_FORMAT,
1315                                abs_range.frac_sec);
1316         if (length < 0 || length > MAX_RANGE_FLOAT_SIZE + 1)
1317         {
1318             return false;
1319         }
1320         if (length > (int)max_len || tmp[1] != '.')
1321         {
1322             return false;
1323         }
1324 
1325         oscl_memcpy(str, tmp + 1, length - 1);
1326         str += length - 1;
1327         len_used += length - 1;
1328         max_len -= (length - 1);
1329     }
1330 
1331     if (max_len < 1)
1332     {
1333         return false;
1334     }
1335 
1336     *str = 'Z';
1337     len_used++;
1338 
1339     return true;
1340 
1341 }
1342 
1343 
compose_range_string(char * str,unsigned int max_len,const RtspRangeType & range,int & len_used)1344 OSCL_EXPORT_REF bool compose_range_string(char *str, unsigned int max_len, const RtspRangeType& range,
1345         int& len_used)
1346 {
1347     len_used = 0;
1348     int length;
1349 
1350     if (!range.start_is_set && !range.end_is_set)
1351     {
1352         return false;
1353     }
1354 
1355     switch (range.format)
1356     {
1357         case RtspRangeType::NPT_RANGE:
1358         {
1359             StrPtrLen npt_str("npt=");
1360 
1361             if (max_len < (unsigned int)npt_str.length())
1362             {
1363                 return false;
1364             }
1365 
1366             oscl_memcpy(str, npt_str.c_str(), npt_str.length());
1367 
1368             str += npt_str.length();
1369             max_len -= npt_str.length();
1370             len_used += npt_str.length();
1371 
1372             if (range.start_is_set)
1373             {
1374                 if (compose_range_string(str, max_len, range.npt_start,
1375                                          length) != true)
1376                 {
1377                     return false;
1378                 }
1379 
1380                 len_used += length;
1381                 max_len -= length;
1382                 str += length;
1383             }
1384 
1385             if (max_len < 1)
1386             {
1387                 return false;
1388             }
1389 
1390             *str++ = '-';
1391             --max_len;
1392             ++len_used;
1393 
1394             if (range.end_is_set)
1395             {
1396                 if (compose_range_string(str, max_len, range.npt_end,
1397                                          length) != true)
1398                 {
1399                     return false;
1400                 }
1401 
1402                 len_used += length;
1403                 max_len -= length;
1404                 str += length;
1405             }
1406 
1407             break;
1408         }
1409 
1410         case RtspRangeType::SMPTE_RANGE:
1411         case RtspRangeType::SMPTE_25_RANGE:
1412         case RtspRangeType::SMPTE_30_RANGE:
1413         {
1414             StrPtrLen smpte30_str("smpte-30-drop=");
1415             StrPtrLen smpte25_str("smpte-25=");
1416             StrPtrLen smpte_str("smpte=");
1417 
1418             if (range.format == RtspRangeType::SMPTE_30_RANGE)
1419             {
1420                 if (max_len < (unsigned int)smpte30_str.length())
1421                 {
1422                     return false;
1423                 }
1424                 oscl_memcpy(str, smpte30_str.c_str(), smpte30_str.length());
1425 
1426                 str += smpte30_str.length();
1427                 max_len -= smpte30_str.length();
1428                 len_used += smpte30_str.length();
1429 
1430             }
1431             else if (range.format == RtspRangeType::SMPTE_25_RANGE)
1432             {
1433                 if (max_len < (unsigned int)smpte25_str.length())
1434                 {
1435                     return false;
1436                 }
1437 
1438                 oscl_memcpy(str, smpte25_str.c_str(), smpte25_str.length());
1439 
1440                 str += smpte25_str.length();
1441                 max_len -= smpte25_str.length();
1442                 len_used += smpte25_str.length();
1443             }
1444             else
1445             {
1446                 if (max_len < (unsigned int)smpte_str.length())
1447                 {
1448                     return false;
1449                 }
1450 
1451                 oscl_memcpy(str, smpte_str.c_str(), smpte_str.length());
1452                 str += smpte_str.length();
1453                 max_len -= smpte_str.length();
1454                 len_used += smpte_str.length();
1455 
1456             }
1457 
1458             if (range.start_is_set)
1459             {
1460                 if (compose_range_string(str, max_len, range.smpte_start,
1461                                          length) != true)
1462                 {
1463                     return false;
1464                 }
1465 
1466                 len_used += length;
1467                 max_len -= length;
1468                 str += length;
1469             }
1470 
1471             if (max_len < 1)
1472             {
1473                 return false;
1474             }
1475 
1476             *str++ = '-';
1477             --max_len;
1478             ++len_used;
1479 
1480 
1481             if (range.end_is_set)
1482             {
1483                 if (compose_range_string(str, max_len, range.smpte_end,
1484                                          length) != true)
1485                 {
1486                     return false;
1487                 }
1488 
1489                 len_used += length;
1490                 max_len -= length;
1491                 str += length;
1492             }
1493 
1494             break;
1495         }
1496 
1497         case RtspRangeType::ABS_RANGE:
1498         {
1499             StrPtrLen abs_str("clock=");
1500 
1501             if (max_len < (unsigned int)abs_str.length())
1502             {
1503                 return false;
1504             }
1505 
1506             oscl_memcpy(str, abs_str.c_str(), abs_str.length());
1507 
1508             str += abs_str.length();
1509             max_len -= abs_str.length();
1510             len_used += abs_str.length();
1511 
1512             if (range.start_is_set)
1513             {
1514                 if (compose_range_string(str, max_len, range.abs_start,
1515                                          length) != true)
1516                 {
1517                     return false;
1518                 }
1519 
1520                 len_used += length;
1521                 max_len -= length;
1522                 str += length;
1523             }
1524 
1525             if (max_len < 1)
1526             {
1527                 return false;
1528             }
1529 
1530             *str++ = '-';
1531             --max_len;
1532             ++len_used;
1533 
1534 
1535             if (range.end_is_set)
1536             {
1537                 if (compose_range_string(str, max_len, range.abs_end,
1538                                          length) != true)
1539                 {
1540                     return false;
1541                 }
1542 
1543                 len_used += length;
1544                 max_len -= length;
1545                 str += length;
1546             }
1547 
1548             break;
1549         }
1550 
1551         default:
1552             return false;
1553     }
1554 
1555     if (max_len < 2)
1556     {
1557         // can't add line terminator
1558         return false;
1559     }
1560 
1561     // add the line terminator
1562     *str++ = '\r';
1563     *str++ = '\n';
1564     len_used += 2;
1565 
1566 
1567     return true;
1568 
1569 }
1570 
1571 
1572 
1573 
compose_SDP_string(char * str,unsigned int max_len,const RtspRangeType & range,int & len_used)1574 OSCL_EXPORT_REF bool compose_SDP_string(char *str, unsigned int max_len,
1575                                         const RtspRangeType& range,
1576                                         int& len_used)
1577 {
1578     len_used = 0;
1579 
1580     // first verify that there is something to do
1581     if (range.format == RtspRangeType::UNKNOWN_RANGE ||
1582             range.format == RtspRangeType::INVALID_RANGE)
1583     {
1584         // nothing to output but it is not an error
1585         return true;
1586     }
1587 
1588     const char *range_str = "a=range:";
1589     int length = oscl_strlen(range_str);
1590     // output the "a=range:" string
1591     if ((int)max_len < length)
1592     {
1593         return false;
1594     }
1595 
1596     oscl_memcpy(str, range_str, length);
1597 
1598     str += length;
1599     len_used += length;
1600     max_len -= length;
1601 
1602     if (compose_range_string(str, max_len, range, length) != true)
1603     {
1604         len_used += length;
1605         return false;
1606     }
1607 
1608     len_used += length;
1609 
1610     return true;
1611 }
1612 
1613 
1614 
compose_RTSP_string(char * str,unsigned int max_len,const RtspRangeType & range,int & len_used)1615 OSCL_EXPORT_REF bool compose_RTSP_string(char *str, unsigned int max_len,
1616         const RtspRangeType& range,
1617         int& len_used)
1618 {
1619     len_used = 0;
1620 
1621     // first verify that there is something to do
1622     if (range.format == RtspRangeType::UNKNOWN_RANGE ||
1623             range.format == RtspRangeType::INVALID_RANGE)
1624     {
1625         // nothing to output but it is not an error
1626         return true;
1627     }
1628 
1629     const char *range_str = "Range: ";
1630     int length = oscl_strlen(range_str);
1631     // output the "Range: " string
1632     if ((int)max_len < length)
1633     {
1634         return false;
1635     }
1636 
1637     oscl_memcpy(str, range_str, length);
1638 
1639     str += length;
1640     len_used += length;
1641     max_len -= length;
1642 
1643     if (compose_range_string(str, max_len, range, length) != true)
1644     {
1645         len_used += length;
1646         return false;
1647     }
1648 
1649     len_used += length;
1650 
1651     return true;
1652 }
1653 
1654 
1655 
1656 
1657