VALUE rb_IStream_read_string(VALUE self){ struct fs_input_stream* is = NULL; Data_Get_Struct(self, struct fs_input_stream, is); if(fs_input_stream_get_pos(is) + sizeof(uint16_t) > fs_input_stream_get_len(is)){ rb_raise(rb_eEOFError, "input stream eof"); } size_t len = fs_stream_read_uint16(is); if(fs_input_stream_get_pos(is) + len > fs_input_stream_get_len(is)){ rb_raise(rb_eEOFError, "input stream eof"); } char out[len]; fs_stream_read_data(is, out, len); return rb_str_new(out, len); }
void FSParams::init_from_stream(struct fs_input_stream* is, fs_bool check_head){ fs_bool inval = true; if(check_head){ params_type type = (params_type)fs_stream_read_byte(is); inval = (type == PARAMS_TYPE_DOUCMENT || type == PARAMS_TYPE_ARRAY); } if(inval){ uint16_t size = fs_stream_read_uint16(is); for(int i = 0 ; i < size ; i++){ char* key = NULL; if(type_hash){ fs_stream_read_string(is, &key); }else{ key = (char*)fs_malloc(12); sprintf(key, "%d", i); } params_type child_type = (params_type)fs_stream_read_byte(is); switch (child_type) { case PARAMS_TYPE_INT: set(key, fs_stream_read_int32(is)); break; case PARAMS_TYPE_INT64: set(key, fs_stream_read_int64(is)); break; case PARAMS_TYPE_BOOL: set(key, fs_stream_read_byte(is) == 1); break; case PARAMS_TYPE_DOUBLE: set(key, fs_stream_read_double(is)); break; case PARAMS_TYPE_ARRAY: { FSParamsArray* array = new FSParamsArray; array->init_from_stream(is, false); set(key, array, PARAMS_TYPE_ARRAY); break; } case PARAMS_TYPE_DOUCMENT:{ FSParamsHash* hash = new FSParamsHash; hash->init_from_stream(is, false); set(key, hash, PARAMS_TYPE_DOUCMENT); break; } case PARAMS_TYPE_UTF8:{ char* value; size_t len = fs_stream_read_string(is, &value); set(key, (void*)value, (uint32_t)len); break; } case PARAMS_TYPE_NULL: set(key, NULL, 0, PARAMS_TYPE_NULL); break; default: break; } if(key){ fs_free(key); } } } }