1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
 herr_t
 ss_val_dump(void *val,                  /* Value to be printed */
             hid_t type,                 /* Datatype of VAL */
             void *_parent,              /* Optional persistent object into which VAL points */
             FILE *out,                  /* Stream to which output should be sent */
             const char *html_tag        /* Optional HTML tag to use in output; NULL means output plain text */
             )
 {
     SS_ENTER(ss_val_dump, herr_t);
     char        tmp[128], name[64];
     hsize_t     nelmts, i;
     hid_t       elmttype;
     size_t      elmtsize;

     assert(H5Tget_size(type)<=sizeof tmp);
     memcpy(tmp, val, H5Tget_size(type));
     if (html_tag) fprintf(out, "<%s>", html_tag);

     if (H5Tequal(type, ss_string_tm)) {
         const char *quote = html_tag ? "" : "\"";
         fprintf(out, "%s%s%s", quote, ss_string_ptr(val), quote);
     } else if (H5Tequal(type, ss_pers_tm)) {
         ss_scope_t      parent_scope=SS_SCOPE_NULL;
         size_t          gfile_idx, file_idx, scope_idx, obj_idx;
         ss_file_t       file=SS_FILE_NULL;
         ss_pers_class_t *pc=NULL;
         hbool_t         is_indirect;

         if (SS_PERS_ISNULL(val)) {
             fprintf(out, "(ss_pers_t*)NULL");
         } else {
             pc = SS_PERS_CLASS(SS_MAGIC_SEQUENCE(SS_MAGIC_OF(val)));
             assert(pc);

             /* Find the index of the file to which VAL belongs by consulting the "file" table in the scope to which the parent
              * object (_parent) belongs. */
             if (NULL==ss_pers_scope(_parent, &parent_scope)) {
                 fprintf(out, "ERROR(scope)");
                 SS_ERROR(FAILED);
             }
             gfile_idx = ss_pers_link_gfileidx(val);
             for (file_idx=0; /*void*/; file_idx++) {
                 if (NULL==ss_pers_refer_c(&parent_scope, SS_MAGIC(ss_file_t), file_idx, (ss_pers_t*)&file)) {
                     fprintf(out, "ERROR(link)");
                     SS_ERROR(FAILED);
                 }
                 if (NULL==SS_FILE(&file)) {
                     /* This can happen if the VAL link points to a file that hasn't yet been entered into the file table of
                      * the _PARENT object. */
                     file_idx = SS_NOSIZE;
                     break;
                 }
                 if (SS_FILE(&file)->m.gfileidx==gfile_idx) {
                     break;
                 }
             }

             /* The scope index within that file */
             scope_idx = ss_pers_link_scopeidx(val);

             /* The object index within that scope */
             obj_idx = ss_pers_link_objidx(val);
             if (obj_idx & SS_TABLE_INDIRECT) {
                 is_indirect = TRUE;
                 obj_idx &= ~SS_TABLE_INDIRECT;
             } else {
                 is_indirect = FALSE;
             }

             /* Now print the info. If the file index is zero then omit it since it's the same file to which VAL belongs. If
              * the scope index is the same as that of the object then omit it also. */
             if (html_tag) fprintf(out, "<a href=\"XXX\">");
             fprintf(out, "(ss_%s_t*)", pc->name);
             if (SS_NOSIZE==file_idx) {
                 ss_gfile_t *gfile = SS_GFILE_IDX(gfile_idx);
                 fprintf(out, "{S%08lx,%lu,%s%lu}", (unsigned long)gfile->serial, (unsigned long)scope_idx,
                         is_indirect?"I":"", (unsigned long)obj_idx);
             } else if (file_idx>0) {
                 fprintf(out, "{%lu,%lu,%s%lu}", (unsigned long)file_idx, (unsigned long)scope_idx,
                         is_indirect?"I":"", (unsigned long)obj_idx);
             } else if (scope_idx!=ss_pers_link_scopeidx(_parent)) {
                 fprintf(out, "{%lu,%s%lu}", (unsigned long)scope_idx, is_indirect?"I":"", (unsigned long)obj_idx);
             } else {
                 fprintf(out, "%s%lu", is_indirect?"I":"", (unsigned long)obj_idx);
             }
             if (html_tag) fprintf(out, "</a>");
         }
     } else if (H5Tequal(type, ss_array_tm)) {
         nelmts = ss_array_nelmts(val);
         elmttype = ss_array_targeted(val);
         if (H5Tequal(elmttype, ss_pers_tf)) {
             H5Tclose(elmttype);
             elmttype = H5Tcopy(ss_pers_tm);
         }
         if (html_tag) fprintf(out, "<table><tr>");
         else fprintf(out, "[");
         for (i=0; i<nelmts; i++) {
             if (!html_tag && i) fprintf(out, ", ");
             ss_array_get(val, elmttype, (size_t)i, (size_t)1, &tmp);
             ss_val_dump(tmp, elmttype, _parent, out, html_tag);
         }
         if (html_tag) fprintf(out, "</tr></table>");
         else fprintf(out, "]");
         H5Tclose(elmttype);
     } else {
         switch (H5Tget_class(type)) {
         case H5T_ARRAY:
             assert(1==H5Tget_array_ndims(type));
             H5Tget_array_dims(type, &nelmts, NULL);
             elmttype = H5Tget_super(type);
             elmtsize = H5Tget_size(elmttype);
             if (html_tag) fprintf(out, "<table><tr>");
             else fprintf(out, "[");
             for (i=0; i<nelmts; i++) {
                 if (i && !html_tag) fprintf(out, ", ");
                 ss_val_dump((char*)val+i*elmtsize, elmttype, _parent, out, html_tag);
             }
             if (html_tag) fprintf(out, "</tr></table>");
             else fprintf(out, "]");
             H5Tclose(elmttype);
             break;
         case H5T_INTEGER:
             H5Tconvert(type, H5T_NATIVE_LLONG, 1, tmp, NULL, H5P_DEFAULT);
             fprintf(out, "%lld", *(long_long*)tmp);
             break;
         case H5T_FLOAT:
             H5Tconvert(type, H5T_NATIVE_DOUBLE, 1, tmp, NULL, H5P_DEFAULT);
             fprintf(out, "%g", *(double*)tmp);
             break;
         case H5T_ENUM:
             H5Tenum_nameof(type, val, name, sizeof name);
             fprintf(out, "%s", name);
             break;
         case H5T_STRING:
             elmtsize = H5Tget_size(type);
             if (H5T_CSET_ASCII!=H5Tget_cset(type) || H5T_STR_NULLTERM!=H5Tget_strpad(type)) {
                 fprintf(out, "%sSTRING%s", html_tag?"&lt;":"<", html_tag?"&gt;":">");
             } else {
                 fprintf(out, "\"%s\"", (char*)val);
             }
             break;
         case H5T_COMPOUND:
             fprintf(out, "%sCOMPOUND%s", html_tag?"&lt;":"<", html_tag?"&gt;":">");
             break;
         default:
             fprintf(out, "%sUNKNOWN%s", html_tag?"&lt;":"<", html_tag?"&gt;":">");
             break;
         }
     }

     if (html_tag) fprintf(out, "</%s>", html_tag);
 SS_CLEANUP:
     SS_LEAVE(0);
 }