MHEG5  18.9.0
MHEG5 Documentation
mh5variable.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2004 Ocean Blue Software Ltd
4  * Copyright © 2000 Koninklijke Philips Electronics N.V
5  *
6  * This file is part of a DTVKit Software Component
7  * You are permitted to copy, modify or distribute this file subject to the terms
8  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
9  *
10  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
11  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
12  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * If you or your organisation is not a member of DTVKit then you have access
15  * to this source code outside of the terms of the licence agreement
16  * and you are expected to delete this and any associated files immediately.
17  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
18  *******************************************************************************/
32 /*---includes for this file--------------------------------------------------*/
33 #include "mh5variable.h"
34 #include "mh5object.h" /* for actions */
35 #include "mh5gate.h"
36 #include "mh5memory.h" /* for constructor/destructor */
37 #include "mh5queue.h" /* Events */
38 #include "mh5application.h" /* For QuitApp Event by division by zero */
39 #include "mh5debug.h"
40 #include "mh5profile.h"
41 #include "mh5scene.h"
42 
43 /*
44  Debug
45  */
46 #ifdef MH5PRINTOUT
47 #include <string.h>
48 #endif
49 /*---constant definitions for this file--------------------------------------*/
50 
51 
52 /*---local typedef structs for this file-------------------------------------*/
53 
54 /*---local (static) variable declarations for this file----------------------*/
55 
56 /*---local function definitions----------------------------------------------*/
57 
58 /*---global function definitions---------------------------------------------*/
59 
60 static MHEG5Bool MHEG5variableIs(MHEG5Root *variable);
61 static MHEG5Int MHEG5storeBool(MHEG5Bool b, char *buf, MHEG5Int bufLen);
62 static MHEG5Int MHEG5storeString(MHEG5String s, char *buf, MHEG5Int bufLen);
63 static MHEG5Int MHEG5storeInt(MHEG5Int i, char *buf, MHEG5Int bufLen);
64 static MHEG5Int MHEG5readBool(MHEG5Bool *b, char *buf);
65 static MHEG5Int MHEG5readInt(MHEG5Int *i, char *buf);
66 
72 /* Documentation of the SubClasses of Variable */
73 
176 /*
177  Debug
178  */
179 #ifdef MH5PRINTOUT
180 
187 void MHEG5booleanVariablePrint(MHEG5BooleanVariable *v, char *out)
188 {
189  MHEG5ingredientPrint(&v->ingredient, out);
190  MHEG5indent(out);
191  MHEG_PRINT(out, ":OrigValue ");
192  MHEG5boolPrint(v->originalValue, out);
193  MHEG5newLine(out);
194 /*
195  if ( v->value ) {
196  MHEG5indent(out);
197  MHEG_PRINT(out,"// Value:\ttrue");
198  MHEG5newLine(out);
199  }
200  */
201 }
202 
210 void MHEG5integerVariablePrint(MHEG5IntegerVariable *v, char *out)
211 {
212  MHEG5ingredientPrint(&v->ingredient, out);
213  MHEG5indent(out);
214  MHEG_PRINT(out, ":OrigValue ");
215  MHEG5intPrint(v->originalValue, out);
216  MHEG5newLine(out);
217 /*
218  if ( v->value ) {
219  MHEG5indent(out);
220  MHEG_PRINT(out,"// Value:\t");
221  MHEG5intPrint(v->value,out);
222  MHEG5newLine(out);
223  }
224  */
225 }
226 
234 void MHEG5stringVariablePrint(MHEG5OctetStringVariable *v, char *out)
235 {
236  MHEG5ingredientPrint(&v->ingredient, out);
237  MHEG5indent(out);
238  MHEG_PRINT(out, ":OrigValue ");
239  MHEG5stringPrint(v->originalValue, out);
240  MHEG5newLine(out);
241 /*
242  if (v->value.len) {
243  MHEG5indent(out);
244  MHEG_PRINT(out,"// Value:\t");
245  MHEG5stringPrint(v->value,out);
246  MHEG5newLine(out);
247  }
248  */
249 }
250 
258 void MHEG5oRefVariablePrint(MHEG5ObjectRefVariable *v, char *out)
259 {
260  MHEG5ingredientPrint(&v->ingredient, out);
261  MHEG5indent(out);
262  MHEG_PRINT(out, ":OrigValue :ObjectRef");
263  if (v->originalValueGid.len)
264  {
265  MHEG_PRINT(out, " ");
266  MHEG5stringPrint(*((MHEG5String *)&v->originalValueGid), out);
267  }
268  MHEG_PRINT(out, " ");
269  MHEG5intPrint(v->originalValueId, out);
270  //MHEG_PRINT(out,")");
271  MHEG5newLine(out);
272 /*
273  if (v->valueGrp.len) {
274  MHEG5indent(out);
275  MHEG_PRINT(out,"// Value:\t(");
276  MHEG5stringPrint( v->valueGrp, out );
277  MHEG_PRINT(out," ");
278  MHEG5intPrint(v->valueId,out);
279  MHEG_PRINT(out,")");
280  MHEG5newLine(out);
281  }
282  */
283 }
284 
292 void MHEG5cRefVariablePrint(MHEG5ContentVariable *v, char *out)
293 {
294  MHEG5ingredientPrint(&v->ingredient, out);
295  MHEG5indent(out);
296  MHEG_PRINT(out, ":OrigValue ");
297  if (v->originalContentData.data)
298  {
299  MHEG_PRINT(out, ":ContentRef ");
300  MHEG5stringPrint(v->originalContentData, out);
301  MHEG5newLine(out);
302  }
303  if (v->contentData.data)
304  {
305  MHEG5indent(out);
306  MHEG_PRINT(out, "// Value:\t");
307  MHEG_PRINT(out, ":ContentRef ");
308  MHEG5stringPrint(v->contentData, out);
309  MHEG5newLine(out);
310  }
311 }
312 
319 void MHEG5variablePrint(MHEG5Ingredient *variable, char *out)
320 {
321  if (((MHEG5Root *)variable)->clazz == MHEG5BOOLEANVARIABLE)
322  MHEG5booleanVariablePrint((MHEG5BooleanVariable *)variable, out);
323  if (((MHEG5Root *)variable)->clazz == MHEG5INTEGERVARIABLE)
324  MHEG5integerVariablePrint((MHEG5IntegerVariable *)variable, out);
325  if (((MHEG5Root *)variable)->clazz == MHEG5OCTETSTRINGVARIABLE)
326  MHEG5stringVariablePrint((MHEG5OctetStringVariable *)variable, out);
327  if (((MHEG5Root *)variable)->clazz == MHEG5OBJECTREFVARIABLE)
328  MHEG5oRefVariablePrint((MHEG5ObjectRefVariable *)variable, out);
329  if (((MHEG5Root *)variable)->clazz == MHEG5CONTENTREFVARIABLE)
330  MHEG5cRefVariablePrint((MHEG5ContentVariable *)variable, out);
331 }
332 
333 #endif
334 
335 
344 static MHEG5Bool MHEG5variableIs(MHEG5Root *variable)
345 {
346  if ((variable->clazz == MHEG5BOOLEANVARIABLE) ||
347  (variable->clazz == MHEG5INTEGERVARIABLE) ||
348  (variable->clazz == MHEG5OCTETSTRINGVARIABLE) ||
349  (variable->clazz == MHEG5OBJECTREFVARIABLE) ||
350  (variable->clazz == MHEG5CONTENTREFVARIABLE))
351  return MHEG5TRUE;
352  return MHEG5FALSE;
353 }
354 
355 /*
356  Constructors
357  */
364 {
365  assert(variable);
366 
367  MHEG5ingredientInit(&variable->ingredient);
368 }
369 
377 {
378  assert(variable);
379 
380  variable->value = variable->originalValue;
381 
383 }
384 
393 {
394  assert(variable);
395 
396  MHEG5ingredientFree(&variable->ingredient);
397 }
398 
405 {
406  assert(variable);
407 
408  MHEG5ingredientInit(&variable->ingredient);
409 }
410 
418 {
419  assert(variable);
420 
421  variable->value = variable->originalValue;
422 
424 }
425 
434 {
435  assert(variable);
436 
437  MHEG5ingredientFree(&variable->ingredient);
438 }
439 
446 {
447  assert(variable);
448 
449  MHEG5ingredientInit(&variable->ingredient);
450 }
451 
459 {
460  assert(variable);
461 
462  variable->value = MHEG5stringCopy(variable->originalValue);
463 
465 }
466 
475 {
476  assert(variable);
477 
478  MHEG5ingredientFree(&variable->ingredient);
479 
481 }
482 
484 {
485  assert(variable);
487 
488  MHEG5stringDestruct(&variable->value);
489 }
490 
497 {
498  assert(variable);
499 
500  MHEG5ingredientInit(&variable->ingredient);
501 }
502 
504 {
505  MHEG5stringDestruct(&objRef->valueGrp);
506  if (ref.len == 0)
507  {
510  {
511  /*assert( g.value.o.gref.ptr.group->magic == GROUP_MAGIC_NUM );*/
512  ref.len = ref.ptr.group->groupName.len;
513  ref.ptr.name = ref.ptr.group->groupName.data;
514  }
515  }
516  objRef->valueGrp.len = ref.len;
517  objRef->valueGrp.data = STR_DataAlloc( ref.len );
518  if (objRef->valueGrp.data != NULL)
519  {
520  memcpy( objRef->valueGrp.data, ref.ptr.name, ref.len );
521  }
522  else
523  {
524  TRACE(TERROR, ("failed to get memory"))
525  }
526  objRef->valueId = id;
527 }
528 
530 {
531  MHEG5stringDestruct(&objRef->valueGrp);
532  if (ref.len)
533  {
534  objRef->valueGrp.len = ref.len;
535  objRef->valueGrp.data = STR_DataAlloc( ref.len );
536  if (objRef->valueGrp.data != NULL)
537  {
538  memcpy( objRef->valueGrp.data, ref.data, ref.len );
539  }
540  else
541  {
542  TRACE(TERROR, ("failed to get memory"))
543  objRef->valueGrp.len = 0;
544  }
545  }
546  else
547  {
548  objRef->valueGrp.len = 0;
549  objRef->valueGrp.data = NULL;
550  }
551  objRef->valueId = id;
552 }
553 
561 {
562  assert(variable);
563 
564  MHEG5objRefStoreValue( variable, variable->originalValueGid, variable->originalValueId );
565 
567 }
568 
577 {
578  assert(variable);
579 
580  MHEG5ingredientFree(&variable->ingredient);
581 
582  if (variable->originalValueGid.len)
584  if (variable->valueGrp.len)
585  MHEG5stringDestruct((MHEG5String *)&variable->valueGrp );
586 }
587 
594 {
595  assert(variable);
596 
597  MHEG5ingredientInit(&variable->ingredient);
598 }
599 
607 {
608  assert(variable);
609 
610  variable->contentData = MHEG5stringCopy(variable->originalContentData);
611 
613 }
614 
623 {
624  assert(variable);
625 
626  MHEG5ingredientFree(&variable->ingredient);
627 
629 }
630 
632 {
633  assert(variable);
635 
636  MHEG5stringDestruct(&variable->contentData);
637 }
638 
639 /*
640  Internal behaviours
641  */
642 
643 
654 {
655  MHEG5ingredientPrepare(variable);
656 }
657 
666 {
667  assert(variable);
668  if (!variable->root.runningStatus)
669  {
670  if (!variable->root.availabilityStatus)
671  {
672  switch (variable->root.clazz)
673  {
676  break;
679  break;
682  break;
685  break;
688  break;
689  default:;
690  }
691  }
692  /* Could call the base class activation behaviour, but */
693  /* MHEG5ingredientActivate(variable); <- does nothing, so don't bother */
694 
695  variable->root.runningStatus = MHEG5TRUE;
696  MHEG5sendSync((MHEG5Root *) variable, MHEG5ISRUNNING, 0);
697  }
698 }
699 
709 {
710  assert(variable);
711  MHEG5ingredientDeactivate(variable);
712 }
713 
721 {
722  assert(variable);
723  MHEG5ingredientDestruct(variable);
724  if (((MHEG5Root *) variable)->clazz == MHEG5OCTETSTRINGVARIABLE)
725  {
726  MHEG5stringDestruct(&((MHEG5OctetStringVariable *) variable)->value);
727  }
728  if (((MHEG5Root *) variable)->clazz == MHEG5CONTENTREFVARIABLE)
729  {
730  MHEG5stringDestruct(&((MHEG5ContentVariable *) variable)->contentData);
731  }
732 }
733 
734 /*
735  Actions
736  */
737 /*
738  SetVariable (NewVariableValue)
739  Set the Value attribute of the Target object to NewVariableValue.
740 
741  Provisions of use:
742  The Target object shall be an active object of one of the following classes:
743  BooleanVariable, IntegerVariable, OctetStringVariable, ObjectRefVariable or
744  ContentRefVariable.
745  NewVariableValue shall be set or refer to a value that is not necessarily of the
746  same type as the current Value attribute of the target Variable. When
747  NewVariableValue and the Target object are of two different types,
748  NewVariableValue is automatically converted into the class type of Target.
749  NOTE - More details on conversions are given in subclauses relevant to each
750  Variable subclasses.
751  */
762 {
763  MHEG5GList *thirdParam = 0, *fourthParam = 0;
764  MHEG5String cdata;
765  MHEG5Bool cref = MHEG5FALSE;
766  MHEG5Bool valid = MHEG5FALSE;
767  MHEG5Generic g;
768 
769  assert(target);
770 
771  if (!params)
773 
774  switch (target->clazz)
775  {
777  MHEG5resolveGenericCRef(params, &cdata, &cref, &valid);
778  if (!cref)
779  {
780  TRACE(TERROR, ("Application error: ISO/IEC 13522-5 sec 26.4 - Provision of use!"))
781  }
782  else
783  {
784  MHEG5stringDestruct(&((MHEG5ContentVariable *) target)->contentData);
785  ((MHEG5ContentVariable *) target)->contentData = MHEG5stringCopy(cdata);
786  #ifdef TRACING
787  if (mheg_trace_debug & TACTIONS)
788  {
789  char buff[288];
790  strcpy(buff, " = ");
791  MHEG5stringTrace(((MHEG5ContentVariable *) target)->contentData, buff, 0, 120 );
792  DBG_PRINTF(buff);
793  }
794  #endif
795  }
796  break;
797 
799  (void) MHEG5resolveGenericGeneric(params, &g);
800  if (g.type == MHEG5BOOL)
801  {
802  ((MHEG5BooleanVariable *) target)->value = g.value.b;
803  }
804  break;
805 
807  (void) MHEG5resolveGenericGeneric(params, &g);
808  if (g.type == MHEG5INT)
809  {
810  ((MHEG5IntegerVariable *) target)->value = g.value.i;
811  }
812  if (g.type == MHEG5OCTETSTRING)
813  {
814  ((MHEG5IntegerVariable *) target)->value = MHEG5strToInt(g.value.s);
815  }
816  #ifdef TRACING
817  if (mheg_trace_debug & TACTIONS)
818  {
819  DBG_PRINTF(" = %ld", ((MHEG5IntegerVariable *) target)->value);
820  }
821  #endif
822  break;
823 
825  (void) MHEG5resolveGenericGeneric(params, &g);
826  switch (g.type )
827  {
828  case MHEG5INT:
829  cdata = MHEG5intToStr(g.value.i);
830  break;
831  case MHEG5OCTETSTRING:
832  cdata = MHEG5stringCopy(g.value.s);
833  break;
834  default:
835  cdata.len = 0;
836  cdata.data= NULL;
837  }
838  MHEG5stringDestruct(&((MHEG5OctetStringVariable *) target)->value);
839  ((MHEG5OctetStringVariable *) target)->value = cdata;
840  #ifdef TRACING
841  if (mheg_trace_debug & TACTIONS)
842  {
843  char buff[288];
844  strcpy(buff, " <- ");
845  MHEG5stringTrace(((MHEG5OctetStringVariable *) target)->value, buff, 0, 120 );
846  DBG_PRINTF(buff);
847  DBG_PRINTF(" len: %ld", ((MHEG5OctetStringVariable *) target)->value.len);
848  }
849  #endif
850  break;
851 
853  {
855  thirdParam = MHEG5resolveGenericGeneric(params, &g);
856  if (g.type == MHEG5OBJECTREF)
857  {
858  MHEG5objRefStoreValue( objRef, g.value.o.gref, g.value.o.id );
859  }
860  else
861  {
862  if (thirdParam)
863  {
864  fourthParam = MHEG5resolveGenericGeneric(thirdParam, &g);
865  }
866  if (g.type == MHEG5OCTETSTRING)
867  {
868  MHEG5objRefStoreString( objRef, g.value.s, 0 );
869  if (fourthParam)
870  {
871  MHEG5resolveGenericGeneric(fourthParam, &g);
872  if (g.type == MHEG5INT)
873  {
874  objRef->valueId = g.value.i;
875  }
876  }
877  }
878  }
879  }
880  break;
881  default:
882  ERROR_PRINT(("ERROR: MHEG5setVariable: Invalid object class for setting variable value\n"));
883  return MHEG5ERR_WRONGTARGET;
884  }
885  return MHEG5ERR_NOERROR;
886 }
887 
888 /*
889  TestVariable (Target, Operator, ComparisonValue)
890  Execute the following sequence of actions:
891  1. Compare the Value of the variable to the ComparisonValue parameter. The
892  Variable value is the first operand, the ComparisonValue parameter is the
893  second operand of the comparison.
894  2. Generate the corresponding TestEvent.
895  source: Target of TestVariable,
896  Associated data: Boolean.
897  Provisions of use:
898  The Target object shall be an active object of one of the following classes:
899  BooleanVariable, IntegerVariable, OctetStringVariable, ObjectRefVariable or
900  ContentRefVariable.
901  The ComparisonValue shall be of corresponding type (GenericBoolean,
902  GenericInteger, GenericOctetString, GenericObjectReference and
903  GenericContentReference respectively). No implicit type conversion is allowed.
904  When values are Integer, the Operator shall be an integer in the range 1 to 6
905  with the following meaning:
906  1 means equal, 2 not equal,
907  3 strictly less than, 4 less than or equal to,
908  5 strictly greater than, 6 greater than or equal to.
909  When values are Boolean, OctetString, ObjectReference or ContentReference,
910  the Operator shall be an integer in the range 1 to 2 with the following meaning:
911  1 means equal, 2 not equal.
912  */
924 {
925  #ifdef TRACING
926  static const char opstr[6][3] = {"==", "!=", "< ", "<=", "> ", ">="};
927  #endif
928  MHEG5GList *thirdParam = 0;
929  MHEG5String cdata;
930  MHEG5Int csize = 0;
931  MHEG5Bool cref = MHEG5FALSE;
932  MHEG5Bool eq = MHEG5FALSE;
933  int eventData;
934  MHEG5Int op = 0;
935  MHEG5Bool invalidString;
936 
937  assert(target);
938 
939  if (!MHEG5variableIs(target))
940  {
941  return MHEG5ERR_WRONGTARGET;
942  }
943 
944  /* Parse the operator parameter */
945  if (!params)
946  {
948  }
949  thirdParam = MHEG5resolveGenericInteger(params, &op);
950  if (!thirdParam)
951  {
953  }
954 
955  if ((op < 1) || (op > (target->clazz == MHEG5INTEGERVARIABLE ? 6 : 2)))
956  {
957  ERROR_PRINT(("MHEG5testVariable invalid Operator %ld\n", op));
958  return MHEG5ERR_WRONGPARAM;
959  }
960 
961  /* Set the default TestEvent data */
962  eventData = MHEG5FALSE;
963 
964  //TRACE(TEVNTS,(" TestVar %d op=%ld",target->clazz,op))
965 
966  switch (target->clazz)
967  {
969  /* Parse the ComparisonValue parameter */
970  MHEG5resolveGenericCRef(thirdParam, &cdata, &cref, &invalidString);
971  if (op == 1 && cref &&
972  MHEG5stringEqual(&((MHEG5ContentVariable *) target)->contentData, &cdata))
973  {
974  eventData = MHEG5TRUE;
975  }
976  else if (op == 2 && !MHEG5stringEqual(&((MHEG5ContentVariable *) target)->contentData, &cdata))
977  {
978  eventData = MHEG5TRUE;
979  }
980  break;
982  /* Parse the ComparisonValue parameter */
983  MHEG5resolveGenericInteger(thirdParam, &csize);
984  switch (op)
985  {
986  case 1:
987  if (((MHEG5IntegerVariable *) target)->value == csize)
988  {
989  eventData = MHEG5TRUE;
990  }
991  break;
992  case 2:
993  if (((MHEG5IntegerVariable *) target)->value != csize)
994  {
995  eventData = MHEG5TRUE;
996  }
997  break;
998  case 3:
999  if (((MHEG5IntegerVariable *) target)->value < csize)
1000  {
1001  eventData = MHEG5TRUE;
1002  }
1003  break;
1004  case 4:
1005  if (((MHEG5IntegerVariable *) target)->value <= csize)
1006  {
1007  eventData = MHEG5TRUE;
1008  }
1009  break;
1010  case 5:
1011  if (((MHEG5IntegerVariable *) target)->value > csize)
1012  {
1013  eventData = MHEG5TRUE;
1014  }
1015  break;
1016  case 6:
1017  if (((MHEG5IntegerVariable *) target)->value >= csize)
1018  {
1019  eventData = MHEG5TRUE;
1020  }
1021  break;
1022  }
1023  #ifdef TRACING
1024  if (mheg_trace_debug & TACTIONS)
1025  {
1026  DBG_PRINTF(" %ld %s %ld", ((MHEG5IntegerVariable *) target)->value, opstr[op - 1], csize);
1027  }
1028  #endif
1029  break;
1030  case MHEG5BOOLEANVARIABLE:
1031  /* Parse the ComparisonValue parameter */
1032  MHEG5resolveGenericBoolean(thirdParam, &cref);
1033  if (((op == 1) && (((MHEG5BooleanVariable *) target)->value == cref)) ||
1034  ((op == 2) && (((MHEG5BooleanVariable *) target)->value != cref)))
1035  {
1036  eventData = MHEG5TRUE;
1037  }
1038  break;
1040  /* Parse the ComparisonValue parameter */
1041  MHEG5resolveGenericOctetString(thirdParam, &cdata, &invalidString);
1042  if (invalidString)
1043  {
1044  /* Parameter was not an octet string */
1045  return MHEG5ERR_WRONGPARAM;
1046  }
1047 
1048  if (((op == 1) && MHEG5stringEqual(&((MHEG5OctetStringVariable *) target)->value, &cdata)) ||
1049  ((op == 2) && !MHEG5stringEqual(&((MHEG5OctetStringVariable *) target)->value, &cdata)))
1050  {
1051  eventData = MHEG5TRUE;
1052  }
1053  break;
1055  {
1056  MHEG5ObjectRefVariable *objref = (MHEG5ObjectRefVariable *) target;
1057  MH5GroupRef gref;
1058  MH5GroupRef vRef;
1059  MHEG5Int id;
1060 
1061  /* Parse the ComparisonValue parameter */
1062  MHEG5resolveGenericORefProper(thirdParam, &gref, &id);
1063 
1064  vRef.len = objref->valueGrp.len;
1065  vRef.ptr.name = objref->valueGrp.data;
1066 
1067  /* Find out whether the variable is equal to the comparison value */
1068 
1069  eq = (objref->valueId == id) && MHEG5sameGroups( vRef, gref );
1070 
1071  /* Check eq and operation to determine TestEvent result */
1072  if ((eq && (op == 1)) || (!eq && (op == 2)))
1073  {
1074  eventData = MHEG5TRUE;
1075  }
1076  break;
1077  }
1078  default:
1079  ERROR_PRINT(("MHEG5testVariable internal error - target->clazz = %d\n", target->clazz));
1080  }
1081 
1082  MHEG5sendSync( target, MHEG5TESTEVENT, eventData );
1083 
1084  return MHEG5ERR_NOERROR;
1085 }
1086 
1087 /*
1088  IntegerVariable Actions
1089  */
1090 /*
1091  Add (Value)
1092  Add Target Variable to Value. Target variable is the first operand of the infix
1093  operation. Result is stored in Target Variable.
1094 
1095  Provision of use:
1096  The Target object shall be an active IntegerVariable object.
1097  */
1108 {
1109  MHEG5Int value = 0;
1110 
1111  assert(target);
1112 
1113  if (!params)
1115  if (target->clazz != MHEG5INTEGERVARIABLE)
1116  return MHEG5ERR_WRONGTARGET;
1117  MHEG5resolveGenericInteger(params, &value);
1118  #ifdef TRACING
1119  if (mheg_trace_debug & TACTIONS)
1120  {
1121  DBG_PRINTF(" %ld += %ld", ((MHEG5IntegerVariable *) target)->value, value);
1122  }
1123  #endif
1124  ((MHEG5IntegerVariable *) target)->value += value;
1125  return MHEG5ERR_NOERROR;
1126 }
1127 
1128 /*
1129  Subtract (Value)
1130  Subtract Value from Target Variable. Target variable is the first operand of the infix
1131  operation. Result is stored in Target Variable.
1132 
1133  Provision of use:
1134  The Target object shall be an active IntegerVariable object.
1135  */
1146 {
1147  MHEG5Int value = 0;
1148 
1149  assert(target);
1150 
1151  if (!params)
1153  if (target->clazz != MHEG5INTEGERVARIABLE)
1154  return MHEG5ERR_WRONGTARGET;
1155  MHEG5resolveGenericInteger(params, &value);
1156  #ifdef TRACING
1157  if (mheg_trace_debug & TACTIONS)
1158  {
1159  DBG_PRINTF(" %ld -= %ld", ((MHEG5IntegerVariable *) target)->value, value);
1160  }
1161  #endif
1162  ((MHEG5IntegerVariable *) target)->value -= value;
1163  return MHEG5ERR_NOERROR;
1164 }
1165 
1166 /*
1167  Multiply (Value)
1168  Multiplies Target Variable by Value. Target variable is the first operand of the infix
1169  operation. Result is stored in Target Variable.
1170 
1171  Provision of use:
1172  The Target object shall be an active IntegerVariable object.
1173  */
1184 {
1185  MHEG5Int value = 0;
1187 
1188  assert(target);
1189 
1190  if (!params)
1192  if (target->clazz != MHEG5INTEGERVARIABLE)
1193  return MHEG5ERR_WRONGTARGET;
1194  MHEG5resolveGenericInteger(params, &value);
1195  i = (MHEG5IntegerVariable *) target;
1196  i->value *= value;
1197  return MHEG5ERR_NOERROR;
1198 }
1199 
1200 /*
1201  Divide (Value)
1202  Divides Target Variable by Value. Target variable is the first operand of the infix
1203  operation. Result is stored in Target Variable. When the result is not an integer
1204  value, rounding is made towards 0.
1205 
1206  Provision of use:
1207  The Target object shall be an active IntegerVariable object.
1208  */
1219 {
1220  MHEG5Int value = 0;
1221 
1222  assert(target);
1223 
1224  if (!params)
1226  if (target->clazz != MHEG5INTEGERVARIABLE)
1227  return MHEG5ERR_WRONGTARGET;
1228  MHEG5resolveGenericInteger(params, &value);
1229  if (value != 0)
1230  ((MHEG5IntegerVariable *) target)->value /= value;
1231  else
1232  {
1233  /* What should we do here? */
1234 #ifdef MHEG5LOG
1235  MHEG5LogPrintf(MHEG5WARNING, "Division by zero\n");
1236 #endif
1237  }
1238  return MHEG5ERR_NOERROR;
1239 }
1240 
1241 /*
1242  Modulo (Value)
1243  Returns the remainder modulo Value of Target - as defined by usual integer
1244  arithmetic rules, that is to say that for any integers a and b the following equality is
1245  satisfied:
1246  (a DIV b) *b + (a MOD b) = a.
1247  Target variable is the first operand of the infix operation. Result is stored in Target
1248  Variable.
1249 
1250  Provision of use:
1251  The Target object shall be an active IntegerVariable object.
1252  */
1263 {
1264  MHEG5Int value = 0;
1265 
1266  assert(target);
1267 
1268  if (!params)
1270  if (target->clazz != MHEG5INTEGERVARIABLE)
1271  return MHEG5ERR_WRONGTARGET;
1272  MHEG5resolveGenericInteger(params, &value);
1273  if (value != 0)
1274  ((MHEG5IntegerVariable *) target)->value %= value;
1275  else
1276  {
1277  /* What should we do here? */
1278 #ifdef MHEG5LOG
1279  MHEG5LogPrintf(MHEG5WARNING, "Modulo division by zero\n");
1280 #endif
1281  }
1282  return MHEG5ERR_NOERROR;
1283 }
1284 
1285 /*
1286  OctetStringVariable Actions
1287  */
1288 /*
1289  Append (AppendValue)
1290  Appends AppendValue to Target Variable. Target variable is the first operand of the
1291  infix operation. Result is stored in Target Variable.
1292 
1293  Provision of use:
1294  The Target object shall be an active OctetStringVariable object.
1295  */
1307 {
1308  MHEG5String value, buf;
1310  MHEG5Bool invalidString;
1311 
1312  assert(target);
1313 
1314  if (!params)
1315  {
1317  }
1318  if (target->clazz != MHEG5OCTETSTRINGVARIABLE)
1319  {
1320  return MHEG5ERR_WRONGTARGET;
1321  }
1322 
1323  MHEG5resolveGenericOctetString(params, &value, &invalidString);
1324  if (invalidString)
1325  {
1326  /* Parameter was not an octet string */
1327  return MHEG5ERR_WRONGPARAM;
1328  }
1329  if (!value.len)
1330  {
1331  /* String to append is empty - nothing to do */
1332  return MHEG5ERR_NOERROR;
1333  }
1334 
1335  os = (MHEG5OctetStringVariable *) target;
1336  #ifdef TRACING
1337  if (mheg_trace_debug & TACTIONS)
1338  {
1339  DBG_PRINTF(" lens: %ld += %ld", os->value.len, value.len);
1340  }
1341  #endif
1342  buf = MHEG5stringCat(os->value, value);
1343  if (buf.len > 0)
1344  {
1345  MHEG5stringDestruct(&os->value);
1346  os->value = buf;
1347  #ifdef TRACING
1348  if (mheg_trace_debug & TACTIONS)
1349  {
1350  char buff[288];
1351  strcpy(buff, " rst: ");
1352  MHEG5stringTrace( os->value, buff, 0, 120 );
1353  DBG_PRINTF(buff);
1354  }
1355  #endif
1356  }
1357 
1358  return MHEG5ERR_NOERROR;
1359 }
1360 
1361 /*
1362  Store the value of the Variable in the Buffer and Return number of Bytes used.
1363  Return -1 for failure
1364  */
1365 static MHEG5Int MHEG5storeBool(MHEG5Bool b, char *buf, MHEG5Int bufLen)
1366 {
1367  if (bufLen < 1)
1368  return -1;
1369  if (b)
1370  buf[0] = 'T';
1371  else
1372  buf[0] = 'F';
1373  return 1;
1374 }
1375 
1376 static MHEG5Int MHEG5storeString(MHEG5String s, char *buf, MHEG5Int bufLen)
1377 {
1378  if (bufLen < (MHEG5Int)sizeof(s.len))
1379  return -1;
1380  memcpy(buf, &s.len, sizeof(s.len));
1381  if (s.len + (MHEG5Int)sizeof(s.len) > bufLen)
1382  return -1;
1383  if (s.len > 0)
1384  memcpy(&buf[sizeof(s.len)], s.data, s.len);
1385  return s.len + sizeof(s.len);
1386 }
1387 
1388 static MHEG5Int MHEG5storeInt(MHEG5Int i, char *buf, MHEG5Int bufLen)
1389 {
1390  if (bufLen < (MHEG5Int)sizeof(i))
1391  return -1;
1392  memcpy(buf, &i, sizeof(i));
1393  return sizeof(i);
1394 }
1395 
1396 static MHEG5Int MHEG5readBool(MHEG5Bool *b, char *buf)
1397 {
1398  if (buf[0] == 'T')
1399  *b = MHEG5TRUE;
1400  else
1401  *b = MHEG5FALSE;
1402  return 1;
1403 }
1404 
1405 static MHEG5Int MHEG5readString(MHEG5String *s, char *buf, MHEG5Int max_size)
1406 {
1407  memcpy(&s->len, buf, sizeof(s->len));
1408 
1409  /* Check that the length looks sensible */
1410  if (s->len > max_size)
1411  {
1412  s->len = 0;
1413  }
1414 
1415  if (s->len == 0)
1416  {
1417  return sizeof(s->len);
1418  }
1419 
1420  s->data = STR_DataAlloc( s->len );
1421  memcpy(s->data, &buf[sizeof(s->len)], s->len);
1422  return s->len + sizeof(s->len);
1423 }
1424 
1425 static MHEG5Int MHEG5readInt(MHEG5Int *i, char *buf)
1426 {
1427  memcpy(i, buf, sizeof(*i));
1428  return sizeof(*i);
1429 }
1430 
1438 {
1439  MHEG5Int len = 0, rc;
1440 
1441  if (!v)
1442  return -1;
1443  if (!buf)
1444  return -1;
1445  if (!bufLen)
1446  return -1;
1447  switch (((MHEG5Root *)v)->clazz)
1448  {
1450 /* local[len++]='C';
1451  */
1452  rc = MHEG5storeString(((MHEG5ContentVariable *) v)->contentData, buf, bufLen);
1453  if (rc < 0)
1454  return -1;
1455  len = rc;
1456  break;
1457  case MHEG5INTEGERVARIABLE:
1458 /* local[len++]='I';
1459  */
1460  rc = MHEG5storeInt(((MHEG5IntegerVariable *) v)->value, buf, bufLen);
1461  if (rc < 0)
1462  return -1;
1463  len = rc;
1464  break;
1465  case MHEG5BOOLEANVARIABLE:
1466 /* local[len++]='B';
1467  */
1468  rc = MHEG5storeBool(((MHEG5BooleanVariable *) v)->value, buf, bufLen);
1469  if (rc < 0)
1470  return -1;
1471  len = rc;
1472  break;
1474 /* local[len++]='S';
1475  */
1476  rc = MHEG5storeString(((MHEG5OctetStringVariable *) v)->value, buf, bufLen);
1477  if (rc < 0)
1478  return -1;
1479  len = rc;
1480  break;
1482 /* local[len++]='O';
1483  */
1484  rc = MHEG5storeInt(((MHEG5ObjectRefVariable *) v)->valueId, buf, bufLen);
1485  if (rc < 0)
1486  return -1;
1487  len = rc;
1488  rc = MHEG5storeString(((MHEG5ObjectRefVariable *) v)->valueGrp, (char *)buf + len, bufLen - len);
1489  if (rc < 0)
1490  return -1;
1491  len += rc;
1492  break;
1493  default:
1494  return -1;
1495  }
1496  return len;
1497 }
1498 
1499 /*
1500  Set the Variable to the Buffer values and Return the Number of Bytes read.
1501  Return -1 for failure
1502  */
1510 {
1511  MHEG5Int pos = 0, rc, id;
1512  if (!v)
1513  {
1514  return -1;
1515  }
1516 
1517  if (!buf)
1518  {
1519  return -1;
1520  }
1521 
1522  switch (((MHEG5Root *)v)->clazz)
1523  {
1525  MHEG5stringDestruct( &((MHEG5ContentVariable *) v)->contentData );
1526  rc = MHEG5readString(&((MHEG5ContentVariable *) v)->contentData, &buf[pos], max_size);
1527  pos += rc;
1528  break;
1529 
1530  case MHEG5INTEGERVARIABLE:
1531  rc = MHEG5readInt(&((MHEG5IntegerVariable *) v)->value, &buf[pos]);
1532  pos += rc;
1533  break;
1534 
1535  case MHEG5BOOLEANVARIABLE:
1536  rc = MHEG5readBool(&((MHEG5BooleanVariable *) v)->value, &buf[pos]);
1537  pos += rc;
1538  break;
1539 
1541  MHEG5stringDestruct( &((MHEG5OctetStringVariable *) v)->value );
1542  rc = MHEG5readString(&((MHEG5OctetStringVariable *) v)->value, &buf[pos], max_size);
1543  pos += rc;
1544  break;
1545 
1547  {
1549 
1550  rc = MHEG5readInt( &id, &buf[pos] );
1551  pos += rc;
1552  rc = MHEG5readString(&objRef->valueGrp, &buf[pos], max_size);
1553  objRef->valueId = id;
1554  pos += rc;
1555  }
1556  break;
1557 
1558  default:
1559  return -1;
1560  }
1561  return pos;
1562 }
1563 
MHEG5Bool availabilityStatus
Definition: mh5root.h:52
MHEG5Ingredient ingredient
Definition: mh5variable.h:85
void MHEG5ingredientInit(MHEG5Ingredient *ingredient)
Initialise a ingredient object with default values.
MH5GroupRef gref
Definition: mh5base.h:110
void MHEG5octetStringVariableDestruct(MHEG5OctetStringVariable *variable)
Definition: mh5variable.c:483
MHEG5Ingredient ingredient
Definition: mh5variable.h:100
MHEG5Int MHEG5variableStore(MHEG5Ingredient *v, void *buf, MHEG5Int bufLen)
This functions stores the value of a variable in the persistant storage. Implementation of the StoreP...
Definition: mh5variable.c:1437
MHEG5Ingredient ingredient
Definition: mh5variable.h:59
void MHEG5booleanVariablePrepare(MHEG5BooleanVariable *variable)
Sets all internal attributes for the specified object to their default values.
Definition: mh5variable.c:376
#define DBG_PRINTF(...)
Definition: glue_debug.h:127
MHEG5Bool MHEG5stringEqual(MHEG5String *s1, MHEG5String *s2)
Compare two Strings (case sensitive!)
Definition: mh5base.c:710
MHEG5Int i
Definition: mh5base.h:154
MHEG5String s
Definition: mh5base.h:156
void MHEG5objectRefVariableInit(MHEG5ObjectRefVariable *variable)
Initialise an objectRefVariable object with default values.
Definition: mh5variable.c:496
MHEG5String contentData
Definition: mh5variable.h:106
MHEG5ObjectReference o
Definition: mh5base.h:159
U16BIT type
Definition: mh5base.h:151
void MHEG5octetStringVariablePrepare(MHEG5OctetStringVariable *variable)
Sets all internal attributes for the specified object to their default values.
Definition: mh5variable.c:458
void MHEG5objectRefVariableFree(MHEG5ObjectRefVariable *variable)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
Definition: mh5variable.c:576
unsigned char * STR_DataAlloc(unsigned int size)
Definition: glue_memory.c:596
MHEG5GList * MHEG5resolveGenericInteger(MHEG5GList *params, MHEG5Int *value)
Definition: mh5object.c:510
void MHEG5booleanVariableFree(MHEG5BooleanVariable *variable)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
Definition: mh5variable.c:392
MHEG5Final clazz
Definition: mh5root.h:55
MHEG5Bool b
Definition: mh5base.h:155
void MHEG5ingredientDestruct(MHEG5Ingredient *ingredient)
Implementation of the Destruction behaviour Execute the following sequence of actions: ...
void MHEG5contentVariableFree(MHEG5ContentVariable *variable)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
Definition: mh5variable.c:622
union sMH5GroupRef::@5 ptr
MHEG5Bool originalValue
Definition: mh5variable.h:49
MHEG5Int MHEG5strToInt(MHEG5String string)
Convert a MHEG5String to a MHEG5Integer.
Definition: mh5base.c:739
union MHEG5Generic::@6 value
void MHEG5contentVariableInit(MHEG5ContentVariable *variable)
Initialise a contentVariable object with default values.
Definition: mh5variable.c:593
void MHEG5octetStringVariableFree(MHEG5OctetStringVariable *variable)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
Definition: mh5variable.c:474
MHEG5String MHEG5stringCopy(MHEG5String source)
<Function description>="">
Definition: mh5base.c:574
MHEG5String originalContentData
Definition: mh5variable.h:103
Implement the MHEG5 Variable Class 21 Variable Class Defines a variable within the context of a Group...
void MHEG5stringDestruct(MHEG5String *item)
Destruct a MHEG5String.
Definition: mh5base.c:686
void MHEG5objectRefVariablePrepare(MHEG5ObjectRefVariable *variable)
Sets all internal attributes for the specified object to their default values.
Definition: mh5variable.c:560
void MHEG5integerVariablePrepare(MHEG5IntegerVariable *variable)
Sets all internal attributes for the specified object to their default values.
Definition: mh5variable.c:417
void MHEG5variableDeactivate(MHEG5Ingredient *variable)
Apply the deactivation behaviour of the variable class. As this class has no own deactivation behavio...
Definition: mh5variable.c:708
long MHEG5Int
Definition: mh5base.h:73
MHEG5Int MHEG5variableRead(MHEG5Ingredient *v, char *buf, MHEG5Int max_size)
This functions reads the value of a variable from the persistant storage. Implementation of the ReadP...
Definition: mh5variable.c:1509
void MHEG5objRefStoreValue(MHEG5ObjectRefVariable *objRef, MH5GroupRef ref, MHEG5Int id)
Definition: mh5variable.c:503
MHEG5ErrorCode MHEG5append(MHEG5Root *target, MHEG5GList *params)
Appends AppendValue to Target Variable. Target variable is the first operand of the infix operation...
Definition: mh5variable.c:1306
MHEG5ErrorCode MHEG5divide(MHEG5Root *target, MHEG5GList *params)
Divides Target Variable by Value. Target variable is the first operand of the infix operation...
Definition: mh5variable.c:1218
MHEG5ErrorCode MHEG5add(MHEG5Root *target, MHEG5GList *params)
Add Target Variable to Value. Target variable is the first operand of the infix operation. Result is stored in Target Variable. Implementation of the Add (Value) action of the IntegerVariable class.
Definition: mh5variable.c:1107
MHEG5Bool MHEG5sameGroups(MH5GroupRef gref1, MH5GroupRef gref2)
Compares two group ID strings to see whether they both reference the same group. Relative group ID st...
Definition: mh5gate.c:533
MHEG5GList * MHEG5resolveGenericCRef(MHEG5GList *params, MHEG5String *data, MHEG5Bool *referenced, MHEG5Bool *valid)
Definition: mh5object.c:299
MHEG5ErrorCode MHEG5subtract(MHEG5Root *target, MHEG5GList *params)
Subtract Value from Target Variable. Target variable is the first operand of the infix operation...
Definition: mh5variable.c:1145
MHEG5ErrorCode MHEG5testVariable(MHEG5Root *target, MHEG5GList *params)
This action tests variables agains each other or against values Implementation of the TestVariable (T...
Definition: mh5variable.c:923
This file defines the profile for the MHEG engine.
MHEG5GList * MHEG5resolveGenericOctetString(MHEG5GList *params, MHEG5String *value, MHEG5Bool *invalidString)
Resolve a parameter reference to a generic octet string. The reference can be either direct or indire...
Definition: mh5object.c:478
Implement Functions to support Service Gateways. Functions for standarizing several GroupIDs like +DS...
void MHEG5booleanVariableInit(MHEG5BooleanVariable *variable)
Initialise a booleanVariable object with default values.
Definition: mh5variable.c:363
short MHEG5Bool
Definition: mh5base.h:71
void MHEG5variableActivate(MHEG5Ingredient *variable)
Apply the activation behaviour of the Variable class. Apply the activation behaviour of the variable ...
Definition: mh5variable.c:665
MHEG5ErrorCode
Definition: mh5base.h:222
void MHEG5contentVariablePrepare(MHEG5ContentVariable *variable)
Sets all internal attributes for the specified object to their default values.
Definition: mh5variable.c:606
Event handling. Implementation of a combined queue for events and actions. This is the eventsystem wh...
MHEG5String MHEG5stringCat(MHEG5String string1, MHEG5String string2)
Concatenate two MHEG5Strings.
Definition: mh5base.c:648
MHEG5Byte * data
Definition: mh5base.h:85
int len
Definition: mh5gate.c:57
MHEG5String MHEG5intToStr(MHEG5Int i)
Convert MHEG5Int to MHEG5String.
Definition: mh5base.c:787
MHEG5String originalValue
Definition: mh5variable.h:75
#define MHEG5TRUE
Definition: mh5base.h:49
MH5GroupRef originalValueGid
Definition: mh5variable.h:88
MHEG5ErrorCode MHEG5setVariable(MHEG5Root *target, MHEG5GList *params)
Set the Value attribute of the Target object to NewVariableValue. Implementation of the SetVariable (...
Definition: mh5variable.c:761
void MHEG5integerVariableFree(MHEG5IntegerVariable *variable)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
Definition: mh5variable.c:433
void MHEG5ingredientDeactivate(MHEG5Ingredient *ingredient)
Implementation of Deactivate behaviour Inherrited from Root class.
void MHEG5objRefStoreString(MHEG5ObjectRefVariable *objRef, MHEG5String ref, MHEG5Int id)
Definition: mh5variable.c:529
MHEG5ErrorCode MHEG5modulo(MHEG5Root *target, MHEG5GList *params)
Returns the remainder modulo Value of Target - as defined by usual integer arithmetic rules...
Definition: mh5variable.c:1262
Implement functions to retrieve MHEG5objects by GroupID and ID.
void MHEG5ingredientPrepare(MHEG5Ingredient *ingredient)
Implementation of the Preparation behaviour Inherrited from Root class.
Implementation of the MHEG5 Application Class Defines a set of Ingredient objects, which are shared within an application scope. Base class: Group Subclasses: None Status: Concrete class.
Implementation of the MHEG5 Scene Class Scene Class Defines a set of Ingredient objects to be activat...
Mheg5 logging and debug printing.
MHEG5Int len
Definition: mh5base.h:99
MHEG5Bool runningStatus
Definition: mh5root.h:51
MHEG5Ingredient ingredient
Definition: mh5variable.h:46
MHEG5Byte * name
Definition: mh5base.h:102
MHEG5String groupName
Definition: mh5group.h:53
MHEG5Int originalValue
Definition: mh5variable.h:62
redirection include
MHEG5ErrorCode MHEG5multiply(MHEG5Root *target, MHEG5GList *params)
Multiplies Target Variable by Value. Target variable is the first operand of the infix operation...
Definition: mh5variable.c:1183
void MHEG5contentVariableDestruct(MHEG5ContentVariable *variable)
Definition: mh5variable.c:631
#define ERROR_PRINT(x)
Definition: mh5debug.h:76
void MHEG5variableDestruct(MHEG5Ingredient *variable)
Destruct a variable object.
Definition: mh5variable.c:720
MHEG5Scene * MHEG5getCurrentScene(void)
<Function description>="">
Definition: mh5scene.c:207
MH5GroupPtr group
Definition: mh5base.h:103
MHEG5GList * MHEG5resolveGenericBoolean(MHEG5GList *params, MHEG5Bool *value)
Definition: mh5object.c:454
MHEG5Int len
Definition: mh5base.h:84
MHEG5String valueGrp
Definition: mh5variable.h:93
void MHEG5integerVariableInit(MHEG5IntegerVariable *variable)
Initialise a integerVariable object with default values.
Definition: mh5variable.c:404
MHEG5GList * MHEG5resolveGenericGeneric(MHEG5GList *params, MHEG5Generic *value)
Definition: mh5object.c:364
void MHEG5ingredientFree(MHEG5Ingredient *ingredient)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
void MHEG5octetStringVariableInit(MHEG5OctetStringVariable *variable)
Initialise an octetStringVariable object with default values.
Definition: mh5variable.c:445
#define MHEG5FALSE
Definition: mh5base.h:48
void MHEG5sendSync(MHEG5Root *source, MHEG5EventType event, MHEG5Int data)
Store an event in the synchronous event queue.
Definition: mh5queue.c:1651
void MHEG5variablePrepare(MHEG5Ingredient *variable)
Apply the preparation behaviour of the variable class Apply the preparation behaviour of the variable...
Definition: mh5variable.c:653
MHEG5GList * MHEG5resolveGenericORefProper(MHEG5GList *params, MH5GroupRef *pgroupRef, MHEG5Int *id)
Resolve a generic object reference, returning the object reference. The reference can be direct or in...
Definition: mh5object.c:177
MHEG5Application * MHEG5getCurrentApplication(void)
<Function description>="">
#define TRACE(t, x)
Definition: glue_debug.h:118
MHEG5Ingredient ingredient
Definition: mh5variable.h:72