String* Method_lower_snake_alias(cfish_Method *method) { cfish_String *host_alias = CFISH_Method_Get_Host_Alias(method); if (host_alias) { return (cfish_String*)CFISH_INCREF(host_alias); } // Convert to lowercase. cfish_String *name = CFISH_Method_Get_Name(method); cfish_CharBuf *buf = cfish_CB_new(CFISH_Str_Get_Size(name)); cfish_StringIterator *iter = CFISH_Str_Top(name); int32_t code_point; while (CFISH_STR_OOB != (code_point = CFISH_StrIter_Next(iter))) { if (code_point > 127) { THROW(CFISH_ERR, "Can't lowercase '%o'", name); } else { CFISH_CB_Cat_Char(buf, tolower(code_point)); } } cfish_String *retval = CFISH_CB_Yield_String(buf); CFISH_DECREF(iter); CFISH_DECREF(buf); return retval; }
cfish_Obj* LUCY_Doc_Extract_IMP(lucy_Doc *self, cfish_String *field) { lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self); cfish_Obj *retval = NULL; SV **sv_ptr = hv_fetch((HV*)ivars->fields, CFISH_Str_Get_Ptr8(field), CFISH_Str_Get_Size(field), 0); if (sv_ptr && XSBind_sv_defined(*sv_ptr)) { SV *const sv = *sv_ptr; if (sv_isobject(sv) && sv_derived_from(sv, "Clownfish::Obj")) { IV tmp = SvIV(SvRV(sv)); retval = CFISH_INCREF(INT2PTR(cfish_Obj*, tmp)); }
void LUCY_Doc_Store_IMP(lucy_Doc *self, cfish_String *field, cfish_Obj *value) { dTHX; lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self); const char *key = CFISH_Str_Get_Ptr8(field); size_t key_size = CFISH_Str_Get_Size(field); SV *key_sv = newSVpvn(key, key_size); SV *val_sv = XSBind_cfish_to_perl(aTHX_ value); SvUTF8_on(key_sv); (void)hv_store_ent((HV*)ivars->fields, key_sv, val_sv, 0); // TODO: make this a thread-local instead of creating it every time? SvREFCNT_dec(key_sv); }
cfish_Obj* LUCY_Doc_Extract_IMP(lucy_Doc *self, cfish_String *field) { dTHX; lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self); cfish_Obj *retval = NULL; SV **sv_ptr = hv_fetch((HV*)ivars->fields, CFISH_Str_Get_Ptr8(field), -CFISH_Str_Get_Size(field), 0); if (sv_ptr) { retval = XSBind_perl_to_cfish_nullable(aTHX_ *sv_ptr, CFISH_OBJ); } return retval; }
void LUCY_Doc_Store_IMP(lucy_Doc *self, cfish_String *field, cfish_Obj *value) { lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self); const char *key = CFISH_Str_Get_Ptr8(field); size_t key_size = CFISH_Str_Get_Size(field); SV *key_sv = newSVpvn(key, key_size); SV *val_sv = value == NULL ? newSV(0) : CFISH_Obj_Is_A(value, CFISH_STRING) ? XSBind_str_to_sv((cfish_String*)value) : (SV*)CFISH_Obj_To_Host(value); SvUTF8_on(key_sv); (void)hv_store_ent((HV*)ivars->fields, key_sv, val_sv, 0); // TODO: make this a thread-local instead of creating it every time? SvREFCNT_dec(key_sv); }
Obj* cfish_inc_refcount(void *vself) { Obj *self = (Obj*)vself; // Handle special cases. cfish_Class *const klass = self->klass; if (klass->flags & CFISH_fREFCOUNTSPECIAL) { if (SI_is_string_type(klass)) { // Only copy-on-incref Strings get special-cased. Ordinary // strings fall through to the general case. if (CFISH_Str_Is_Copy_On_IncRef((cfish_String*)self)) { const char *utf8 = CFISH_Str_Get_Ptr8((cfish_String*)self); size_t size = CFISH_Str_Get_Size((cfish_String*)self); return (cfish_Obj*)cfish_Str_new_from_trusted_utf8(utf8, size); } } else if (SI_immortal(klass)) { return self; } } self->refcount++; return self; }