PL_blob_data(atom_t a, size_t *len, struct PL_blob_t **type) { Atom x = SWIAtomToAtom(a); if (!IsBlob(x)) { if (IsWideAtom(x)) { if ( len ) *len = wcslen(x->WStrOfAE); if ( type ) *type = &unregistered_blob_atom; return x->WStrOfAE; } if ( len ) *len = strlen(x->StrOfAE); if ( type ) *type = &unregistered_blob_atom; return x->StrOfAE; } if ( len ) *len = x->rep.blob[0].length; if ( type ) *type = RepBlobProp(x->PropsOfAE)->blob_t; return x->rep.blob[0].data; }
YAP_find_blob_type(YAP_Atom at) { AtomEntry *a = RepAtom((Atom)at); if (!IsBlob(a)) { return &unregistered_blob_atom; } return RepBlobProp(a->PropsOfAE)->blob_t; }
static AtomEntry * lookupBlob(void *blob, size_t len, PL_blob_t *type) { BlobPropEntry *b; AtomEntry *ae; LOCK(SWI_Blobs_Lock); if (type->flags & PL_BLOB_UNIQUE) { /* just keep a linked chain for now */ ae = SWI_Blobs; while (ae) { if (ae->PropsOfAE && RepBlobProp(ae->PropsOfAE)->blob_t == type && ae->rep.blob->length == len && !memcmp(ae->rep.blob->data, blob, len)) { UNLOCK(SWI_Blobs_Lock); return ae; } ae = RepAtom(ae->NextOfAE); } } b = (BlobPropEntry *)Yap_AllocCodeSpace(sizeof(BlobPropEntry)); if (!b) { UNLOCK(SWI_Blobs_Lock); return NULL; } b->NextOfPE = NIL; b->KindOfPE = BlobProperty; b->blob_t = type; ae = (AtomEntry *)Yap_AllocCodeSpace(sizeof(AtomEntry)+len+sizeof(size_t)); if (!ae) { UNLOCK(SWI_Blobs_Lock); return NULL; } NOfBlobs++; INIT_RWLOCK(ae->ARWLock); ae->PropsOfAE = AbsBlobProp(b); ae->NextOfAE = AbsAtom(SWI_Blobs); ae->rep.blob->length = len; memcpy(ae->rep.blob->data, blob, len); SWI_Blobs = ae; UNLOCK(SWI_Blobs_Lock); if (NOfBlobs > NOfBlobsMax) { Yap_signal(YAP_CDOVF_SIGNAL); } return ae; }
bool YAP_is_blob(Term t, blob_type_t **type) { CACHE_REGS Term yt = Yap_GetFromSlot(t); Atom a; YAP_BlobPropEntry *b; if (IsVarTerm(yt)) return FALSE; if (!IsAtomTerm(yt)) return FALSE; a = AtomOfTerm(yt); if (!IsBlob(a)) return FALSE; b = RepBlobProp(a->PropsOfAE); *type = b->blob_type; return TRUE; }
int Yap_write_blob(AtomEntry *ref, FILE *stream) { blob_type_t *type = RepBlobProp(ref->PropsOfAE)->blob_type; if (type->write) { Atom at = AbsAtom(ref); return type->write(stream, at, 0); } else { #if defined(__linux__) || defined(__APPLE__) return fprintf(stream, "\'%s\'(%p)", RepAtom(AtomSWIStream)->StrOfAE, ref); #else return fprintf(stream, "\'%s\'(0x%p)", RepAtom(AtomSWIStream)->StrOfAE, ref); #endif } return 0; }
PL_is_blob(term_t t, PL_blob_t **type) { CACHE_REGS Term yt = Yap_GetFromSlot(t PASS_REGS); Atom a; BlobPropEntry *b; if (IsVarTerm(yt)) return FALSE; if (!IsAtomTerm(yt)) return FALSE; a = AtomOfTerm(yt); if (!IsBlob(a)) return FALSE; b = RepBlobProp(a->PropsOfAE); *type = b->blob_t; return TRUE; }
char *Yap_blob_to_string(AtomEntry *ref, const char *s0, size_t sz) { // int rc; char *s = (char *)s0; #if HAVE_FMEMOPEN blob_type_t *type = RepBlobProp(ref->PropsOfAE)->blob_type; if (type->write) { FILE *f = fmemopen(s, sz, "w"); if (f == NULL) { // could not find stream; return NULL; } Atom at = AbsAtom(ref); int rc = type->write(f, at, 0); if (rc < 0) { Yap_Error(EVALUATION_ERROR_UNDEFINED, MkAtomTerm(at), "failure in user-defined blob to string code"); } fclose(f); // return the final result. return s; } else { #endif #if __APPLE__ size_t sz0 = strlcpy(s, (char *)RepAtom(AtomSWIStream)->StrOfAE, sz); #else size_t sz0; char *f = (char *)memcpy(s, (char *)RepAtom(AtomSWIStream)->StrOfAE, sz); f[0] = '\0'; sz0 = f - s; #endif s = s + sz0; sz -= sz0; #if defined(__linux__) || defined(__APPLE__) snprintf(s + strlen(s), sz0, "(%p)", ref); #else snprintf(s + strlen(s), sz0, "(0x%p)", ref); #endif return s; #if HAVE_FMEMOPEN } return NULL; #endif }
static void clean_atom_list(AtomHashEntry *HashPtr) { Atom atm = HashPtr->Entry; Atom *patm = &(HashPtr->Entry); while (atm != NIL) { AtomEntry *at = RepAtom(atm); if (AtomResetMark(at) || ( at->PropsOfAE != NIL && !IsBlob(at) ) || (GLOBAL_AGCHook != NULL && !GLOBAL_AGCHook(atm))) { patm = &(at->NextOfAE); atm = at->NextOfAE; } else { NOfAtoms--; if (IsBlob(atm)) { BlobPropEntry *b = RepBlobProp(at->PropsOfAE); if (b->NextOfPE != NIL) { patm = &(at->NextOfAE); atm = at->NextOfAE; continue; } NOfAtoms++; NOfBlobs--; Yap_FreeCodeSpace((char *)b); GLOBAL_agc_collected += sizeof(BlobPropEntry); GLOBAL_agc_collected += sizeof(AtomEntry)+sizeof(size_t)+at->rep.blob->length; } else if (IsWideAtom(atm)) { #ifdef DEBUG_RESTORE3 fprintf(stderr, "Purged %p:%S\n", at, at->WStrOfAE); #endif GLOBAL_agc_collected += sizeof(AtomEntry)+wcslen(at->WStrOfAE); } else { #ifdef DEBUG_RESTORE3 fprintf(stderr, "Purged %p:%s patm=%p %p\n", at, at->StrOfAE, patm, at->NextOfAE); #endif GLOBAL_agc_collected += sizeof(AtomEntry)+strlen(at->StrOfAE); } *patm = atm = at->NextOfAE; Yap_FreeCodeSpace((char *)at); } } }