32 #define BKG_TITLE_TOKEN "t" 33 #define BKG_BOOKING_TOKEN "b" 34 #define BKG_CRIDTYPE_TOKEN "ct" 35 #define BKG_SYNOPSIS_TOKEN "s" 36 #define BKG_LOCATION_TOKEN "l" 37 #define BKG_DVB_TOKEN "dvb://" 39 #define BKG_CRID_TTL_STRING "{\"ct\":\"49\",\"t\":\"" 40 #define BKG_SYNOPSIS_STRING "\",\"s\":\"" 41 #define BKG_BOOKING_PREFIX "\",\"b\":[" 42 #define BKG_LOCATION_PREFIX "\"l\":\"dvb://" 43 #define BKG_DURATION_PREFIX "--PT" 44 #define BKG_BOOKING_ENDFIX "]}" 46 #define MAX_INT_LENGTH 32 47 #define MIN_DATA_BLOCK 32 50 static MHEG5Bool EncodeOctetString(MHEG5Byte **
buffer, MHEG5Int *used,
51 MHEG5Int *allocated, MHEG5Byte *data,
53 static MHEG5Bool EncodeChar(MHEG5Byte **
buffer, MHEG5Int *used,
54 MHEG5Int *allocated, MHEG5Byte ch);
55 static MHEG5Bool AppendString(MHEG5Byte **
buffer, MHEG5Int *used,
56 MHEG5Int *allocated, MHEG5Byte *data,
58 static MHEG5Bool AppendInteger(MHEG5Byte **
buffer, MHEG5Int *used,
59 MHEG5Int *allocated, MHEG5Int value);
60 static MHEG5Bool AppendChar(MHEG5Byte **
buffer, MHEG5Int *used,
61 MHEG5Int *allocated, MHEG5Byte ch);
64 static MHEG5Bool AddOctetString(MHEG5Byte **
buffer, MHEG5Int *used,
65 MHEG5Int *allocated, MHEG5Byte *data,
67 static MHEG5Bool AddEncodedChar(MHEG5Byte **
buffer, MHEG5Int *used,
68 MHEG5Int *allocated, MHEG5Byte ch);
75 static void* NewLocation(
unsigned int val,
void *array,
void *cptr );
76 static void* BookingArray(
unsigned int val,
void *array,
void *cptr );
77 static void* DoneLocation(
unsigned int val,
void *array,
void *cptr );
85 DECLARE_OBJECT( DoneLocation ),
86 DECLARE_MEMBER( BKG_LOCATION_TOKEN, JST_CBF_STRING, NewLocation, NULL ),
91 DECLARE_MEMBER( BKG_CRIDTYPE_TOKEN, JST_PTR_STRING, &ctype_str, NULL ),
92 DECLARE_MEMBER( BKG_TITLE_TOKEN, JST_PTR_ASTRING, &title_str, NULL ),
93 DECLARE_MEMBER( BKG_SYNOPSIS_TOKEN, JST_PTR_ASTRING, &synop_str, NULL ),
94 DECLARE_MEMBER( BKG_BOOKING_TOKEN, JST_CBF_ARRAY_OBJ, BookingArray, booking_members ),
108 static MHEG5Bool MHEG5IsDigit(U32BIT ch, U32BIT base, U32BIT *value)
110 MHEG5Bool rc = MHEG5FALSE;
112 if (ch >=
'0' && ch <=
'9')
120 else if (ch >=
'a' && ch <=
'z')
122 if (base > 10 && ch -
'a' < base - 10)
124 *value = ch -
'a' + 10;
128 else if (ch >=
'A' && ch <=
'Z')
130 if (base > 10 && ch -
'A' < base - 10)
132 *value = ch -
'A' + 10;
155 U32BIT originalNetworkId = 0;
156 U32BIT transportStreamId = 0;
157 U32BIT serviceId = 0;
158 U32BIT value, ndx = 0;
159 MHEG5Bool rtn_val = MHEG5TRUE;
160 enum {ST_FIRST_DIGIT, ST_FIRST_NUMBER, ST_FIRST_DOT,
161 ST_SECOND_NUMBER, ST_SECOND_DOT,
162 ST_THIRD_NUMBER, ST_END, ST_ERROR} state = ST_FIRST_DIGIT;
166 while (ndx != length && state != ST_ERROR)
171 if (!MHEG5IsDigit(buffer[ndx], 16, &value))
177 originalNetworkId = value;
178 state = ST_FIRST_NUMBER;
181 case ST_FIRST_NUMBER:
182 if (buffer[ndx] ==
'.')
184 state = ST_FIRST_DOT;
186 else if (!MHEG5IsDigit(buffer[ndx], 16, &value))
192 originalNetworkId *= 16;
193 originalNetworkId += value;
197 if (buffer[ndx] ==
'.')
199 state = ST_SECOND_DOT;
201 else if (!MHEG5IsDigit(buffer[ndx], 16, &value))
207 transportStreamId = value;
208 state = ST_SECOND_NUMBER;
211 case ST_SECOND_NUMBER:
212 if (buffer[ndx] ==
'.')
214 state = ST_SECOND_DOT;
216 else if (!MHEG5IsDigit(buffer[ndx], 16, &value))
222 transportStreamId *= 16;
223 transportStreamId += value;
227 if (!MHEG5IsDigit(buffer[ndx], 16, &value))
234 state = ST_THIRD_NUMBER;
237 case ST_THIRD_NUMBER:
238 if (!MHEG5IsDigit(buffer[ndx], 16, &value))
254 if (state == ST_THIRD_NUMBER)
256 dvb_loc->original_network_id = (U16BIT)originalNetworkId;
257 dvb_loc->transport_stream_id = (U16BIT)transportStreamId;
258 dvb_loc->service_id = (U16BIT)serviceId;
262 rtn_val = MHEG5FALSE;
267 int MHEG5parseLcn( U8BIT *buf, U8BIT *end )
273 for (p = buf; p != end; p++)
275 if (MHEG5IsDigit(*p, 10, &value))
277 lcn = (lcn * 10) + value;
291 #ifdef INCLUDE_PVR_AU 293 static int ParseLocation(
char *in_data,
int chrs_left,
S_LOCATION *p_loc )
297 while (posn != chrs_left && in_data[posn] !=
'@')
300 if (posn == chrs_left ||
301 strncmp((
char *)in_data, (
char *)
"dvb://", 6) != 0 ||
311 while (posn < chrs_left && in_data[posn] !=
'\"')
313 if (in_data[posn] >=
'0' && in_data[posn] <=
'9')
318 case 0: value = (int)(in_data[posn] -
'0');
break;
320 value = (value * 10) + (
int)(in_data[posn] -
'0');
323 p_loc->date.year = (value * 10) + (
int)(in_data[posn] -
'0');
326 case 4: value = (int)(in_data[posn] -
'0');
break;
328 p_loc->date.month = (value * 10) + (
int)(in_data[posn] -
'0');
331 case 6: value = (int)(in_data[posn] -
'0');
break;
333 p_loc->date.day = (value * 10) + (
int)(in_data[posn] -
'0');
336 case 9: value = (int)(in_data[posn] -
'0');
break;
338 p_loc->time.hour = (value * 10) + (
int)(in_data[posn] -
'0');
341 case 12: value = (int)(in_data[posn] -
'0');
break;
343 p_loc->time.minute = (value * 10) + (
int)(in_data[posn] -
'0');
346 case 17: value = (int)(in_data[posn] -
'0');
break;
348 p_loc->duration.hour = (value * 10) + (
int)(in_data[posn] -
'0');
351 case 20: value = (int)(in_data[posn] -
'0');
break;
353 p_loc->duration.minute = (value * 10) + (
int)(in_data[posn] -
'0');
356 TRACE(TERROR, (
"%c count=%d", in_data[posn], count))
366 if (in_data[posn] !=
'T')
368 TRACE(TERROR, (
"%c %d", in_data[posn], in_data[posn]))
374 if (in_data[posn] !=
':')
376 TRACE(TERROR, (
"%c %d", in_data[posn], in_data[posn]))
381 if (in_data[posn] !=
'-')
383 TRACE(TERROR, (
"%c %d", in_data[posn], in_data[posn]))
388 if (in_data[posn] !=
'P')
390 TRACE(TERROR, (
"%c %d", in_data[posn], in_data[posn]))
395 if (in_data[posn] !=
'T')
397 TRACE(TERROR, (
"%c %d", in_data[posn], in_data[posn]))
402 if (in_data[posn] !=
'H')
404 TRACE(TERROR, (
"%c %d", in_data[posn], in_data[posn]))
409 if (in_data[posn] !=
'M')
411 TRACE(TERROR, (
"%c %d", in_data[posn], in_data[posn]))
416 TRACE(TERROR, (
"%c count=%d", in_data[posn], count))
433 static void* NewLocation(
unsigned int val,
void *array,
void *cptr )
438 if (ParseLocation((
char *)array, val, pLoc ) == -1)
445 static void* DoneLocation(
unsigned int val,
void *array,
void *cptr )
448 return (
void *)(pLoc + 1);
451 static void* BookingArray(
unsigned int val,
void *array,
void *cptr )
462 *p_booking_ptr = pBook;
463 p_booking_ptr = &(pBook->next);
465 pBook->num_locs = val;
467 return pBook->p_locs;
470 case JSON_VALUE_FINISH:
471 TRACE(TERROR, (
"Array FINISH"))
474 case JSON_VALUE_ERROR:
475 TRACE(TERROR, (
"Array ERROR"))
486 p_booking_ptr = &(pDetails->bookings);
488 if (
JSON_Parse( bookingString.data, bookingString.len, crid_members, pDetails ) == JSON_OKAY)
490 if (ctype_str.zlen == 2 && ctype_str.zptr != NULL &&
491 title_str.zptr != NULL && synop_str.zptr != NULL)
493 if (ctype_str.zptr[0] ==
'4' && ctype_str.zptr[1] ==
'9')
498 else if (ctype_str.zptr[0] ==
'5' && ctype_str.zptr[1] ==
'0')
505 ctype_str.zptr = NULL;
507 pDetails->title = title_str;
508 title_str.zptr = NULL;
510 pDetails->description = synop_str;
511 synop_str.zptr = NULL;
515 MHEG5freeDecodeBookings( pDetails );
522 if (pDetails->title.zptr != NULL)
526 if (pDetails->description.zptr != NULL)
530 if (pDetails->bookings != NULL)
532 S_BOOKING *pNext, *pBook = pDetails->bookings;
536 MHEG5freeMem( pBook );
539 while (pBook != NULL);
543 char* ParseCatHexNum(
char *p_os, U16BIT num )
545 const char ch[16] =
"0123456789abcdef";
554 *p_os = ch[(num >> 12) & 0xf];
557 *p_os = ch[(num >> 8) & 0xf];
560 *p_os = ch[(num >> 4) & 0xf];
563 *p_os = ch[(num >> 0) & 0xf];
569 char* ParseCatDecNum(
char *p_os, U16BIT num )
571 U16BIT n = num, c = 0;
575 ch[c++] = (char)(n % 10) +
'0';
595 assert( pDetails->bookings );
597 n_locs = pDetails->bookings->num_locs;
600 if (n_locs != 0 && n_locs < 16)
604 len =
sizeof(BKG_CRID_TTL_STRING);
605 len += pDetails->title.zlen;
606 len +=
sizeof(BKG_SYNOPSIS_STRING);
607 len += pDetails->description.zlen;
608 len +=
sizeof(BKG_BOOKING_PREFIX);
611 len +=
sizeof(BKG_BOOKING_ENDFIX);
613 out_str.data = (MHEG5Byte *)MHEG5getMem( len );
615 if (out_str.data != NULL)
617 S_LOCATION *p_loc = pDetails->bookings->p_locs;
618 char *os_data = (
char *)out_str.data;
620 len =
sizeof(BKG_CRID_TTL_STRING);
621 memcpy(os_data, BKG_CRID_TTL_STRING, len);
622 if (pDetails->type == 50)
624 while (*os_data !=
'4')
629 os_data = (
char *)&out_str.data[len];
635 memcpy(os_data, pDetails->title.zptr, pDetails->title.zlen);
636 os_data += pDetails->title.zlen;
638 memcpy(os_data, BKG_SYNOPSIS_STRING,
sizeof(BKG_SYNOPSIS_STRING));
639 os_data +=
sizeof(BKG_SYNOPSIS_STRING);
641 memcpy(os_data, pDetails->description.zptr, pDetails->description.zlen);
642 os_data += pDetails->description.zlen;
644 memcpy(os_data, BKG_BOOKING_PREFIX,
sizeof(BKG_BOOKING_PREFIX));
645 os_data +=
sizeof(BKG_BOOKING_PREFIX);
649 assert( p_loc->dvb_loc.original_network_id != 0 && p_loc->dvb_loc.service_id != 0 );
651 memcpy(os_data, BKG_LOCATION_PREFIX,
sizeof(BKG_LOCATION_PREFIX));
652 os_data +=
sizeof(BKG_LOCATION_PREFIX);
655 os_data = ParseCatHexNum( os_data, p_loc->dvb_loc.original_network_id );
658 os_data = ParseCatHexNum( os_data, p_loc->dvb_loc.transport_stream_id );
661 os_data = ParseCatHexNum( os_data, p_loc->dvb_loc.service_id );
664 os_data = ParseCatDecNum( os_data, p_loc->date.year );
665 os_data = ParseCatDecNum( os_data, p_loc->date.month );
666 os_data = ParseCatDecNum( os_data, p_loc->date.day );
669 os_data = ParseCatDecNum( os_data, p_loc->time.hour );
672 os_data = ParseCatDecNum( os_data, p_loc->time.minute );
675 os_data = ParseCatDecNum( os_data, p_loc->offset.hour );
678 os_data = ParseCatDecNum( os_data, p_loc->offset.minute );
680 memcpy(os_data, BKG_DURATION_PREFIX,
sizeof(BKG_DURATION_PREFIX));
681 os_data +=
sizeof(BKG_DURATION_PREFIX);
683 os_data = ParseCatDecNum( os_data, p_loc->duration.hour );
686 os_data = ParseCatDecNum( os_data, p_loc->duration.minute );
700 memcpy(os_data, BKG_BOOKING_ENDFIX,
sizeof(BKG_BOOKING_ENDFIX));
701 os_data +=
sizeof(BKG_BOOKING_ENDFIX);
704 out_str.len = (int)os_data - (
int)out_str.data;
709 TRACE(TERROR, (
"Invalid number of locations %d", n_locs))
739 success = AppendInteger(buffer, used, allocated, value->value.i);
745 success = AppendString(buffer, used, allocated,
746 (MHEG5Byte *)
"True", 4);
750 success = AppendString(buffer, used, allocated,
751 (MHEG5Byte *)
"False", 5);
755 case MHEG5OCTETSTRING:
756 success = EncodeOctetString(buffer, used, allocated,
761 case MHEG5CONTENTREF:
762 success = EncodeOctetString(buffer, used, allocated,
768 if (value->value.o.gref.len == 0)
770 data = value->value.o.gref.ptr.group->groupName.data;
771 len = value->value.o.gref.ptr.group->groupName.len;
775 data = value->value.o.gref.ptr.name;
776 len = value->value.o.gref.len;
778 success = AppendChar(buffer, used, allocated,
'(');
781 success = EncodeOctetString(buffer, used, allocated, data, len);
785 success = AppendChar(buffer, used, allocated,
' ');
789 success = AppendInteger(buffer, used, allocated, value->value.o.id);
793 success = AppendChar(buffer, used, allocated,
')');
798 success = MHEG5FALSE;
814 static MHEG5Bool EncodeOctetString(MHEG5Byte **
buffer, MHEG5Int *used,
815 MHEG5Int *allocated, MHEG5Byte *data,
822 for (i = 0; success && i < len; ++i)
824 success = EncodeChar(buffer, used, allocated, data[i]);
839 static MHEG5Bool EncodeChar(MHEG5Byte **buffer, MHEG5Int *used,
840 MHEG5Int *allocated, MHEG5Byte ch)
848 success = AppendChar(buffer, used, allocated,
'\n');
853 success = AppendChar(buffer, used, allocated,
'\t');
855 else if (ch >= 0x20 && ch < 0x7f && ch !=
'=' && ch !=
'\'')
858 success = AppendChar(buffer, used, allocated, ch);
863 success = AppendChar(buffer, used, allocated,
'=');
873 digit =
'A' + digit - 10;
875 success = AppendChar(buffer, used, allocated, digit);
886 digit =
'A' + digit - 10;
888 success = AppendChar(buffer, used, allocated, digit);
904 static MHEG5Bool AppendString(MHEG5Byte **buffer, MHEG5Int *used,
905 MHEG5Int *allocated, MHEG5Byte *data,
912 for (i = 0; success && i < len; ++i)
914 success = AppendChar(buffer, used, allocated, data[i]);
928 static MHEG5Bool AppendInteger(MHEG5Byte **buffer, MHEG5Int *used,
929 MHEG5Int *allocated, MHEG5Int value)
931 char decimal[MAX_INT_LENGTH];
935 nbytes = sprintf(decimal,
"%ld", value);
937 for (i = 0; success && i < nbytes; ++i)
939 success = AppendChar(buffer, used, allocated, decimal[i]);
953 static MHEG5Bool AppendChar(MHEG5Byte **buffer, MHEG5Int *used,
954 MHEG5Int *allocated, MHEG5Byte ch)
957 MHEG5Byte *new_block;
960 success = MHEG5FALSE;
962 if (*buffer != NULL && *used + 1 < *allocated)
964 (*buffer)[*used] = ch;
966 (*buffer)[*used] =
'\0';
969 else if (*buffer == NULL)
971 *buffer = MHEG5getMem(MIN_DATA_BLOCK);
977 *allocated = MIN_DATA_BLOCK;
983 new_size = *allocated * 2;
984 new_block = MHEG5getMem(new_size);
985 if (new_block != NULL)
987 memcpy(new_block, *buffer, *used);
988 MHEG5freeMem(*buffer);
990 *allocated = new_size;
991 (*buffer)[*used] = ch;
993 (*buffer)[*used] =
'\0';
998 MHEG5freeMem(*buffer);
1019 MHEG5Bool MHEG5parseEncodeField(MHEG5Byte **buffer, MHEG5Int *used,
1027 success = MHEG5TRUE;
1029 if (*buffer != NULL && *used > 0)
1031 success = AppendChar(buffer, used, allocated,
'&');
1035 success = AddOctetString(buffer, used, allocated,
1036 name->data, name->len);
1040 success = AppendChar(buffer, used, allocated,
'=');
1044 switch (value->type)
1047 success = AppendInteger(buffer, used, allocated, value->value.i);
1052 success = AddOctetString(buffer, used, allocated,
1053 (MHEG5Byte *)
"true", 4);
1057 success = AddOctetString(buffer, used, allocated,
1058 (MHEG5Byte *)
"false", 5);
1061 case MHEG5OCTETSTRING:
1062 success = AddOctetString(buffer, used, allocated,
1063 value->value.s.data,
1064 value->value.s.len);
1066 case MHEG5CONTENTREF:
1067 success = AddOctetString(buffer, used, allocated,
1068 value->value.s.data,
1069 value->value.s.len);
1071 case MHEG5OBJECTREF:
1072 if (value->value.o.gref.len == 0)
1074 data = value->value.o.gref.ptr.group->groupName.data;
1075 len = value->value.o.gref.ptr.group->groupName.len;
1079 data = value->value.o.gref.ptr.name;
1080 len = value->value.o.gref.len;
1082 success = AddOctetString(buffer, used, allocated, data, len);
1085 success = AddEncodedChar(buffer, used, allocated,
',');
1089 success = AppendInteger(buffer, used, allocated,
1094 success = MHEG5FALSE;
1110 static MHEG5Bool AddOctetString(MHEG5Byte **buffer, MHEG5Int *used,
1111 MHEG5Int *allocated, MHEG5Byte *data,
1117 success = MHEG5TRUE;
1118 for (i = 0; success && i < len; ++i)
1120 success = AddEncodedChar(buffer, used, allocated, data[i]);
1134 static MHEG5Bool AddEncodedChar(MHEG5Byte **buffer, MHEG5Int *used,
1135 MHEG5Int *allocated, MHEG5Byte ch)
1138 static MHEG5Byte hex[] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
1139 '8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
1141 if ((ch >=
'0' && ch <=
'9') ||
1142 (ch >=
'A' && ch <=
'Z') ||
1143 (ch >=
'a' && ch <=
'z') ||
1144 (ch ==
'-' || ch ==
'.' || ch ==
'_' || ch ==
'~'))
1146 success = AppendChar(buffer, used, allocated, ch);
1151 success = AppendChar(buffer, used, allocated,
'+');
1156 success = AppendChar(buffer, used, allocated,
'%');
1159 success = AppendChar(buffer, used, allocated, hex[ch >> 4]);
1163 success = AppendChar(buffer, used, allocated, hex[ch & 0xf]);
E_JSON_STATE JSON_Parse(U8BIT *data, U32BIT size, const S_JSON_MEMBERS *members, void *usr)
Implementation of the Group class Description Defines the structure and behaviour of objects used as ...
string parsing utility functions for MHEG5
MHEG5Bool MHEG5parseEncodeQPrintable(MHEG5Byte **buffer, MHEG5Int *used, MHEG5Int *allocated, MHEG5Generic *value)
Add a value to the buffer. The value is QPrintable-encoded, which means that printable characters are...
MHEG5Bool MHEG5parseDvbUrl(U8BIT *buffer, U32BIT length, S_DVB_LOCATOR *dvb_loc)
Parse a DAVIC style multiplex reference or UK-DTT inherritance format URL. This can be one of the fol...
string parsing utility functions described by the [JSON] schema
void JSON_FreeAstring(S_STRING *p_str)