Example #1
0
File: Doc.c Project: gitpan/Lucy
static HV*
S_thaw_fields(lucy_InStream *instream) {
    // Read frozen data into an SV buffer.
    size_t len = (size_t)LUCY_InStream_Read_C64(instream);
    SV *buf_sv = newSV(len + 1);
    SvPOK_on(buf_sv);
    SvCUR_set(buf_sv, len);
    char *buf = SvPVX(buf_sv);
    LUCY_InStream_Read_Bytes(instream, buf, len);

    // Call back to Storable to thaw the frozen hash.
    dSP;
    ENTER;
    SAVETMPS;
    EXTEND(SP, 1);
    PUSHMARK(SP);
    mPUSHs(buf_sv);
    PUTBACK;
    call_pv("Storable::thaw", G_SCALAR);
    SPAGAIN;
    SV *frozen = POPs;
    if (frozen && !SvROK(frozen)) {
        CFISH_THROW(CFISH_ERR, "thaw failed");
    }
    HV *fields = (HV*)SvRV(frozen);
    (void)SvREFCNT_inc((SV*)fields);
    PUTBACK;
    FREETMPS;
    LEAVE;

    return fields;
}
Example #2
0
lucy_HitDoc*
LUCY_DefDocReader_Fetch_Doc_IMP(lucy_DefaultDocReader *self, int32_t doc_id) {
    dTHX;
    lucy_DefaultDocReaderIVARS *const ivars = lucy_DefDocReader_IVARS(self);
    lucy_Schema   *const schema = ivars->schema;
    lucy_InStream *const dat_in = ivars->dat_in;
    lucy_InStream *const ix_in  = ivars->ix_in;
    HV *fields = newHV();
    int64_t start;
    uint32_t num_fields;
    SV *field_name_sv = newSV(1);

    // Get data file pointer from index, read number of fields.
    LUCY_InStream_Seek(ix_in, (int64_t)doc_id * 8);
    start = LUCY_InStream_Read_U64(ix_in);
    LUCY_InStream_Seek(dat_in, start);
    num_fields = LUCY_InStream_Read_CU32(dat_in);

    // Decode stored data and build up the doc field by field.
    while (num_fields--) {
        STRLEN  field_name_len;
        char   *field_name_ptr;
        SV     *value_sv;
        lucy_FieldType *type;

        // Read field name.
        field_name_len = LUCY_InStream_Read_CU32(dat_in);
        field_name_ptr = SvGROW(field_name_sv, field_name_len + 1);
        LUCY_InStream_Read_Bytes(dat_in, field_name_ptr, field_name_len);
        SvPOK_on(field_name_sv);
        SvCUR_set(field_name_sv, field_name_len);
        SvUTF8_on(field_name_sv);
        *SvEND(field_name_sv) = '\0';

        // Find the Field's FieldType.
        cfish_String *field_name_str
            = CFISH_SSTR_WRAP_UTF8(field_name_ptr, field_name_len);
        type = LUCY_Schema_Fetch_Type(schema, field_name_str);

        // Read the field value.
        switch (LUCY_FType_Primitive_ID(type) & lucy_FType_PRIMITIVE_ID_MASK) {
            case lucy_FType_TEXT: {
                    STRLEN value_len = LUCY_InStream_Read_CU32(dat_in);
                    value_sv = newSV((value_len ? value_len : 1));
                    LUCY_InStream_Read_Bytes(dat_in, SvPVX(value_sv), value_len);
                    SvCUR_set(value_sv, value_len);
                    *SvEND(value_sv) = '\0';
                    SvPOK_on(value_sv);
                    SvUTF8_on(value_sv);
                    break;
                }
            case lucy_FType_BLOB: {
                    STRLEN value_len = LUCY_InStream_Read_CU32(dat_in);
                    value_sv = newSV((value_len ? value_len : 1));
                    LUCY_InStream_Read_Bytes(dat_in, SvPVX(value_sv), value_len);
                    SvCUR_set(value_sv, value_len);
                    *SvEND(value_sv) = '\0';
                    SvPOK_on(value_sv);
                    break;
                }
            case lucy_FType_FLOAT32:
                value_sv = newSVnv(LUCY_InStream_Read_F32(dat_in));
                break;
            case lucy_FType_FLOAT64:
                value_sv = newSVnv(LUCY_InStream_Read_F64(dat_in));
                break;
            case lucy_FType_INT32:
                value_sv = newSViv(LUCY_InStream_Read_CI32(dat_in));
                break;
            case lucy_FType_INT64:
                if (sizeof(IV) == 8) {
                    int64_t val = LUCY_InStream_Read_CI64(dat_in);
                    value_sv = newSViv((IV)val);
                }
                else { // (lossy)
                    int64_t val = LUCY_InStream_Read_CI64(dat_in);
                    value_sv = newSVnv((double)val);
                }
                break;
            default:
                value_sv = NULL;
                CFISH_THROW(CFISH_ERR, "Unrecognized type: %o", type);
        }

        // Store the value.
        (void)hv_store_ent(fields, field_name_sv, value_sv, 0);
    }
    SvREFCNT_dec(field_name_sv);

    lucy_HitDoc *retval = lucy_HitDoc_new(fields, doc_id, 0.0);
    SvREFCNT_dec((SV*)fields);
    return retval;
}