comparison src/ov-struct.cc @ 4750:95661d5713ce

[project @ 2004-02-07 22:30:03 by jwe]
author jwe
date Sat, 07 Feb 2004 22:30:03 +0000
parents 7dcb696159ac
children 7cb3b220d0f8
comparison
equal deleted inserted replaced
4749:a4bc7156bd60 4750:95661d5713ce
37 #include "oct-lvalue.h" 37 #include "oct-lvalue.h"
38 #include "ov-list.h" 38 #include "ov-list.h"
39 #include "ov-struct.h" 39 #include "ov-struct.h"
40 #include "unwind-prot.h" 40 #include "unwind-prot.h"
41 #include "variables.h" 41 #include "variables.h"
42
43 #include "Array-util.h"
42 44
43 #include "byte-swap.h" 45 #include "byte-swap.h"
44 #include "ls-oct-ascii.h" 46 #include "ls-oct-ascii.h"
45 #include "ls-oct-binary.h" 47 #include "ls-oct-binary.h"
46 #include "ls-hdf5.h" 48 #include "ls-hdf5.h"
879 retval = true; 881 retval = true;
880 } 882 }
881 883
882 return retval; 884 return retval;
883 } 885 }
886
887 // Check that the dimensions of the input arguments are correct.
888
889 static bool
890 cell2struct_check_args (const dim_vector& c_dv, const dim_vector& f_dv,
891 bool is_cell, int dim)
892 {
893 bool retval (true);
894
895 if (dim >= 0 && dim < c_dv.length ())
896 {
897 if (is_cell)
898 {
899 int f_el = f_dv.numel ();
900
901 if (f_el != c_dv(dim))
902 {
903 error ("cell2struct: number of fields must match size (CELL, DIM)");
904
905 retval = false;
906 }
907 }
908 else
909 {
910 if (f_dv.length () > 2)
911 {
912 error ("cell2struct: field array must be a 2 dimensional matrix");
913
914 retval = false;
915 }
916 else if (f_dv(0) != c_dv(dim))
917 {
918 error ("cell2struct: number of fields in character array must "
919 "match the number of elements in CELL along the specified "
920 "dimension: size (FIELD, 1) == length (C, DIM)");
921
922 retval = false;
923 }
924 }
925 }
926 else
927 {
928 error ("cell2struct: DIM out of range");
929
930 retval = false;
931 }
932
933 return retval;
934 }
935
936 static void
937 cell2struct_construct_idx (Array<int>& ra_idx1, const Array<int>& ra_idx2,
938 int dim, int fill_value)
939 {
940 int iidx = 0;
941
942 for (int idx = 0; idx < ra_idx1.length (); idx++)
943 {
944 if (idx == dim)
945 ra_idx1.elem (idx) = fill_value;
946 else
947 ra_idx1.elem (idx) = ra_idx2(iidx++);
948 }
949 }
950
951 DEFUN (cell2struct, args, ,
952 "-*- texinfo -*-\n\
953 @deftypefn {Built-in Function} {} cell2struct (@var{CELL}, @var{FIELDS}, @var{DIM})\n\
954 Convert @var{CELL} to a structure. The number of fields in @var{FIELDS}\n\
955 must match the number of elements in @var{CELL} along dimension @var{DIM},\n\
956 that is @code{numel (@var{FIELDS}) == size (@var{CELL}, @var{DIM})}.\n\
957 \n\
958 @example\n\
959 @group\n\
960 A = cell2struct(@{'Peter', 'Hannah', 'Robert'; 185, 170, 168@}, @{'Name','Height'@}, 1);\n\
961 A(1)\n\
962 @result{} ans =\n\
963 @{\n\
964 Height = 185\n\
965 Name = Peter\n\
966 @}\n\
967 \n\
968 @end group\n\
969 @end example\n\
970 @end deftypefn")
971 {
972 octave_value retval;
973
974 if (args.length () != 3)
975 {
976 print_usage ("cell2struct");
977 return retval;
978 }
979
980 Cell c = args(0).cell_value ();
981
982 if (error_state)
983 {
984 error ("cell2struct: expecting first argument to be a cell array");
985 return retval;
986 }
987
988 octave_value field = args(1);
989
990 // Field is either cell or character matrix.
991
992 bool field_is_cell = field.is_cell ();
993
994 Cell field_cell;
995 charMatrix field_char;
996
997 if (field_is_cell)
998 field_cell = field.cell_value ();
999 else
1000 field_char = field.char_matrix_value ();
1001
1002 if (error_state)
1003 {
1004 error ("cell2struct: expecting second argument to be a cell or character array");
1005 return retval;
1006 }
1007
1008 // Retrieve the dimension value.
1009
1010 // XXX FIX ME XXX -- int_value () should print out the conversions
1011 // it does to be Matlab compatible.
1012
1013 int dim = args(2).int_value () - 1;
1014
1015 if (error_state)
1016 {
1017 error ("cell2struct: expecting third argument to be an integer");
1018 return retval;
1019 }
1020
1021 dim_vector c_dv = c.dims ();
1022 dim_vector field_dv = field.dims ();
1023
1024 if (cell2struct_check_args (c_dv, field_dv, field_is_cell, dim))
1025 {
1026 int c_dv_length = c_dv.length ();
1027
1028 // Dimension vector for the Cell arrays to be put into the structure.
1029
1030 dim_vector value_dv;
1031
1032 // Initialize c_value_dv.
1033
1034 if (c_dv_length == 2)
1035 value_dv = dim_vector (1, 1);
1036 else
1037 value_dv.resize (c_dv_length - 1);
1038
1039 int idx_tmp = 0;
1040
1041 for (int i = 0; i < c_dv_length; i++)
1042 {
1043 if (i != dim)
1044 value_dv.elem (idx_tmp++) = c_dv.elem (i);
1045 }
1046
1047 // All initializing is done, we can start moving values.
1048
1049 Octave_map map;
1050
1051 // If field is a cell array then we use all elements in array,
1052 // on the other hand when field is a character array the number
1053 // of elements is equals the number of rows.
1054
1055 int field_numel = field_is_cell ? field_dv.numel (): field_dv(0);
1056
1057 // For matlab compatibility.
1058
1059 if (field_numel == 0)
1060 map.reshape (dim_vector (0, 1));
1061
1062 for (int i = 0; i < field_numel; i++)
1063 {
1064 // Construct cell array which goes into the structure together
1065 // with the appropriate field name.
1066
1067 Cell c_value (value_dv);
1068
1069 Array<int> value_idx (value_dv.length (), 0);
1070 Array<int> c_idx (c_dv_length, 0);
1071
1072 for (int j = 0; j < value_dv.numel (); j++)
1073 {
1074 // Need to do this to construct the appropriate
1075 // idx for getting elements from the original cell array.
1076
1077 cell2struct_construct_idx (c_idx, value_idx, dim, i);
1078
1079 c_value.elem (value_idx) = c.elem (c_idx);
1080
1081 increment_index (value_idx, value_dv);
1082 }
1083
1084 std::string field_str;
1085
1086 if (field_is_cell)
1087 {
1088 // Matlab retrieves the field values column by column.
1089
1090 octave_value field_tmp = field_cell.elem (i);
1091
1092 field_str = field_tmp.string_value ();
1093
1094 if (error_state)
1095 {
1096 error ("cell2struct: fields have to be of type string");
1097 return retval;
1098 }
1099 }
1100 else
1101 {
1102 field_str = field_char.row_as_string (i);
1103
1104 if (error_state)
1105 return retval;
1106 }
1107
1108 map.reshape (value_dv);
1109
1110 map.assign (field_str, c_value);
1111 }
1112
1113 retval = map;
1114 }
1115
1116 return retval;
1117 }
1118
884 #endif 1119 #endif
885 1120
886 /* 1121 /*
887 ;;; Local Variables: *** 1122 ;;; Local Variables: ***
888 ;;; mode: C++ *** 1123 ;;; mode: C++ ***