END_TEST START_TEST(Callback_must_be_specified_for_nonempty_dicts) { Streader* sr = init_with_cstr("{ \"key\": 0 }"); int dummy = 0; fail_if(Streader_read_dict(sr, NULL, &dummy), "Reading of non-empty dict succeeded without callback"); }
bool read_default_manifest(Streader* sr) { rassert(sr != NULL); if (Streader_is_error_set(sr)) return false; if (!Streader_has_data(sr)) return false; return Streader_read_dict(sr, read_manifest_entry, NULL); }
Au_expressions* new_Au_expressions(Streader* sr) { rassert(sr != NULL); if (Streader_is_error_set(sr)) return NULL; Au_expressions* ae = memory_alloc_item(Au_expressions); if (ae == NULL) { Streader_set_memory_error( sr, "Could not allocate memory for audio unit expressions"); return NULL; } memset(ae->default_note_expr, '\0', KQT_VAR_NAME_MAX); ae->entries = new_AAtree( (AAtree_item_cmp*)strcmp, (AAtree_item_destroy*)del_Entry); if (ae->entries == NULL) { Streader_set_memory_error( sr, "Could not allocate memory for audio unit expressions"); del_Au_expressions(ae); return NULL; } if (!Streader_read_dict(sr, read_expressions_def, ae)) { rassert(Streader_is_error_set(sr)); del_Au_expressions(ae); return NULL; } if (ae->default_note_expr[0] != '\0' && !Au_expressions_get_proc_filter(ae, ae->default_note_expr)) { Streader_set_error( sr, "Audio unit expressions do not contain the default expression %s", ae->default_note_expr); del_Au_expressions(ae); return NULL; } return ae; }
Tuning_table* new_Tuning_table_from_string(Streader* sr) { rassert(sr != NULL); if (Streader_is_error_set(sr)) return NULL; Tuning_table* tt = new_Tuning_table( TUNING_TABLE_DEFAULT_REF_PITCH, TUNING_TABLE_DEFAULT_OCTAVE_WIDTH); if (tt == NULL) { Streader_set_memory_error( sr, "Couldn't allocate memory for tuning table"); return NULL; } if (Streader_has_data(sr)) { if (!Streader_read_dict(sr, read_tuning_table_item, tt)) { del_Tuning_table(tt); return NULL; } if (tt->ref_note >= tt->note_count) { Streader_set_error(sr, "Reference note doesn't exist: %d", tt->ref_note); del_Tuning_table(tt); return NULL; } } if (!Tuning_table_build_pitch_map(tt)) { Streader_set_memory_error(sr, "Couldn't allocate memory for tuning table"); del_Tuning_table(tt); return NULL; } return tt; }
static bool read_expressions_def(Streader* sr, const char* key, void* userdata) { rassert(sr != NULL); rassert(key != NULL); rassert(userdata != NULL); Au_expressions* ae = userdata; if (string_eq(key, "default_note_expr")) { char expr[KQT_VAR_NAME_MAX + 1] = ""; if (!Streader_read_string(sr, KQT_VAR_NAME_MAX + 1, expr)) return false; if ((expr[0] != '\0') && !is_valid_var_name(expr)) { Streader_set_error(sr, "Invalid default note expression: %s", expr); return false; } strcpy(ae->default_note_expr, expr); } else if (string_eq(key, "expressions")) { if (!Streader_read_dict(sr, read_expressions, ae)) { rassert(Streader_is_error_set(sr)); return false; } } else { Streader_set_error(sr, "Unexpected key in expression specification: %s", key); return false; } return true; }
END_TEST START_TEST(Read_empty_dict) { static const char* dicts[] = { "{} x", "{ }x", "{ } x", }; for (size_t i = 0; i < arr_size(dicts); ++i) { Streader* sr = init_with_cstr(dicts[i]); fail_if(!Streader_read_dict(sr, NULL, NULL), "Could not read empty dictionary from `%s`: %s", dicts[i], Streader_get_error_desc(sr)); fail_if(!Streader_match_char(sr, 'x'), "Streader did not consume empty dictionary from `%s` correctly", dicts[i]); } }
bool Streader_readf(Streader* sr, const char* format, ...) { rassert(sr != NULL); rassert(format != NULL); va_list args; va_start(args, format); while (!Streader_is_error_set(sr) && *format != '\0') { if (*format == '%') { // Conversion characters ++format; switch (*format) { case 'n': { Streader_read_null(sr); } break; case 'b': { bool* dest = va_arg(args, bool*); Streader_read_bool(sr, dest); } break; case 'i': { int64_t* dest = va_arg(args, int64_t*); Streader_read_int(sr, dest); } break; case 'f': { double* dest = va_arg(args, double*); Streader_read_float(sr, dest); } break; case 's': { Streader_readf_str_info info = va_arg(args, Streader_readf_str_info); rassert(info.guard == Streader_readf_str_guard); const int64_t max_bytes = info.max_bytes; char* dest = info.dest; Streader_read_string(sr, max_bytes, dest); } break; case 't': { Tstamp* dest = va_arg(args, Tstamp*); Streader_read_tstamp(sr, dest); } break; case 'p': { Pat_inst_ref* dest = va_arg(args, Pat_inst_ref*); Streader_read_piref(sr, dest); } break; case 'l': { List_item_reader* ir = va_arg(args, List_item_reader*); void* userdata = va_arg(args, void*); Streader_read_list(sr, ir, userdata); } break; case 'd': { Dict_item_reader* ir = va_arg(args, Dict_item_reader*); void* userdata = va_arg(args, void*); Streader_read_dict(sr, ir, userdata); } break; case '%': { Streader_match_char(sr, '%'); } break; default: rassert(false); } } else { // Characters to be matched if (!isspace(*format))