static PyObject * create_types_func(PyObject *self, PyObject *args) { int rval; avro_schema_t schema; PyObject *schema_json; ConvertInfo info; PyObject *schema_json_bytes; if (!PyArg_ParseTuple(args, "O", &schema_json)) { return NULL; } schema_json_bytes = pystring_to_pybytes(schema_json); rval = avro_schema_from_json(pybytes_to_chars(schema_json_bytes), 0, &schema, NULL); Py_DECREF(schema_json_bytes); if (rval != 0 || schema == NULL) { PyErr_Format(PyExc_IOError, "Error reading schema: %s", avro_strerror()); return NULL; } info.types = PyObject_CallFunctionObjArgs((PyObject *)get_avro_types_type(), NULL); if (info.types == NULL) { /* XXX: is the exception already set? */ return NULL; } declare_types(&info, schema); return info.types; }
static int AvroDeserializer_init(AvroDeserializer *self, PyObject *args, PyObject *kwds) { int rval; PyObject *types = NULL; const char *schema_json; static char *kwlist[] = {"schema", "types", NULL}; self->flags = 0; self->iface = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|O", kwlist, &schema_json, &types)) { return -1; } rval = avro_schema_from_json(schema_json, 0, &self->schema, NULL); if (rval != 0 || self->schema == NULL) { PyErr_Format(PyExc_IOError, "Error reading schema: %s", avro_strerror()); return -1; } self->flags |= DESERIALIZER_SCHEMA_OK; self->iface = avro_generic_class_from_schema(self->schema); if (self->iface == NULL) { PyErr_SetString(PyExc_IOError, "Error creating generic class interface"); return -1; } self->datum_reader = avro_reader_memory(0, 0); if (!self->datum_reader) { PyErr_NoMemory(); return -1; } self->flags |= DESERIALIZER_READER_OK; /* copied verbatim from filereader */ if (types != NULL && PyObject_IsTrue(types)) { /* we still haven't incref'ed types here */ if (Py_TYPE(types) == get_avro_types_type()) { Py_INCREF(types); self->info.types = types; } else { self->info.types = PyObject_CallFunctionObjArgs( (PyObject *) get_avro_types_type(), NULL); if (self->info.types == NULL) { return -1; } declare_types(&self->info, self->schema); } } else { self->info.types = NULL; } return 0; }
PyObject * declare_types(ConvertInfo *info, avro_schema_t schema) { avro_type_t type = schema->type; switch (type) { case AVRO_NULL: /* PyNone_Type is not publicly visible */ return (PyObject *)Py_TYPE(Py_None); case AVRO_BOOLEAN: return (PyObject *)&PyBool_Type; case AVRO_BYTES: case AVRO_STRING: case AVRO_FIXED: return (PyObject *)&PyString_Type; case AVRO_DOUBLE: case AVRO_FLOAT: return (PyObject *)&PyFloat_Type; case AVRO_INT32: return (PyObject *)&PyInt_Type; case AVRO_ENUM: return get_python_enum_type(info->types, schema); case AVRO_INT64: return (PyObject *)&PyLong_Type; case AVRO_ARRAY: declare_types(info, avro_schema_array_items(schema)); return (PyObject *)&PyList_Type; case AVRO_MAP: declare_types(info, avro_schema_map_values(schema)); return (PyObject *)&PyDict_Type; case AVRO_UNION: { size_t union_size = avro_schema_union_size(schema); size_t i; for (i = 0; i < union_size; i++) { declare_types(info, avro_schema_union_branch(schema, i)); } } return (PyObject *)&PyBaseObject_Type; /* XXX list of types might be better */ case AVRO_RECORD: { size_t field_count = avro_schema_record_size(schema); size_t i; const char *record_name = avro_schema_name(schema); PyObject *record_type = PyObject_GetAttrString(info->types, record_name); PyObject *field_types; if (record_type != NULL) { /* already declared this record type */ Py_DECREF(record_type); return record_type; } /* create the Python type for this schema */ record_type = get_python_obj_type(info->types, schema); field_types = PyObject_GetAttrString(record_type, "_fieldtypes"); for (i = 0; i < field_count; i++) { PyObject *field_type = declare_types(info, avro_schema_record_field_get_by_index(schema, i)); /* this will INCREF, so takes hold of the object */ PyMapping_SetItemString(field_types, (char*)avro_schema_record_field_name(schema, i), field_type); } Py_DECREF(field_types); return record_type; } case AVRO_LINK: return declare_types(info, avro_schema_link_target(schema)); default: /* other types don't hold records */ break; } return NULL; }
static int AvroFileReader_init(AvroFileReader *self, PyObject *args, PyObject *kwds) { int rval; PyObject *pyfile; PyObject *types = NULL; FILE *file; char *schema_json; avro_writer_t schema_json_writer; size_t len; static char *kwlist[] = {"file", "types", NULL}; self->pyfile = NULL; self->flags = 0; self->iface = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, &pyfile, &types)) { return -1; } file = PyFile_AsFile(pyfile); if (file == NULL) { return -1; } self->pyfile = pyfile; Py_INCREF(pyfile); if (avro_file_reader_fp(file, "pyfile", 0, &self->reader)) { PyErr_Format(PyExc_IOError, "Error opening file: %s", avro_strerror()); return -1; } self->flags |= AVROFILE_READER_OK; self->schema = avro_file_reader_get_writer_schema(self->reader); if (self->schema == NULL) { PyErr_Format(PyExc_IOError, "Error reading schema: %s", avro_strerror()); return -1; } len = 256; do { /* XXX horrible loop to get a big enough buffer for schema. */ len *= 2; schema_json = (char *)PyMem_Malloc(len); schema_json_writer = avro_writer_memory(schema_json, len); rval = avro_schema_to_json(self->schema, schema_json_writer); if (!rval) { rval = avro_write(schema_json_writer, (void *)"", 1); /* zero terminate */ if (!rval) { self->schema_json = PyString_FromString(schema_json); } } avro_writer_free(schema_json_writer); PyMem_Free(schema_json); } while (rval == ENOSPC); if (rval) { PyErr_Format(PyExc_IOError, "Error saving schema: %s", avro_strerror()); return -1; } self->flags |= AVROFILE_SCHEMA_OK; self->iface = avro_generic_class_from_schema(self->schema); if (self->iface == NULL) { PyErr_SetString(PyExc_IOError, "Error creating generic class interface"); return -1; } if (types != NULL && PyObject_IsTrue(types)) { /* we still haven't incref'ed types here */ if (Py_TYPE(types) == get_avro_types_type()) { Py_INCREF(types); self->info.types = types; } else { self->info.types = PyObject_CallFunctionObjArgs((PyObject *)get_avro_types_type(), NULL); if (self->info.types == NULL) { return -1; } declare_types(&self->info, self->schema); } } else { self->info.types = NULL; } return 0; }