Fix WriteBuffer and add WriteDynamicBuffer

This commit is contained in:
VITOR SANTOS COSTA 2012-09-18 23:06:26 +01:00
parent a6c91c99c7
commit 89030ce97d
6 changed files with 141 additions and 8 deletions

View File

@ -479,6 +479,7 @@ X_API Term STD_PROTO(YAP_Read, (IOSTREAM *));
X_API void STD_PROTO(YAP_Write, (Term, IOSTREAM *, int));
X_API Term STD_PROTO(YAP_CopyTerm, (Term));
X_API int STD_PROTO(YAP_WriteBuffer, (Term, char *, size_t, int));
X_API char *STD_PROTO(YAP_WriteDynamicBuffer, (Term, char *, size_t, size_t *, int *, int));
X_API char *STD_PROTO(YAP_CompileClause, (Term));
X_API void STD_PROTO(YAP_PutValue, (Atom,Term));
X_API Term STD_PROTO(YAP_GetValue, (Atom));
@ -2802,10 +2803,30 @@ YAP_CopyTerm(Term t)
X_API int
YAP_WriteBuffer(Term t, char *buf, size_t sze, int flags)
{
int enc;
size_t length;
char *b;
BACKUP_MACHINE_REGS();
t = Yap_TermToString(t, buf, sze, flags);
if ((b = Yap_TermToString(t, buf, sze, &length, &enc, flags)) != buf) {
if (b) free(b);
RECOVER_MACHINE_REGS();
return FALSE;
}
RECOVER_MACHINE_REGS();
return t;
return TRUE;
}
X_API char *
YAP_WriteDynamicBuffer(Term t, char *buf, size_t sze, size_t *lengthp, int *encp, int flags)
{
int enc;
char *b;
BACKUP_MACHINE_REGS();
b = Yap_TermToString(t, buf, sze, lengthp, encp, flags);
RECOVER_MACHINE_REGS();
return b;
}
X_API char *

View File

@ -1090,6 +1090,24 @@ Yap_InitBackIO (void)
{
}
/* used to test writebuffer
static Int
p_write_string( USES_REGS1 )
{
Term in = Deref(ARG1);
char *s;
size_t length;
int encoding;
char buf[256];
if ((s = Yap_TermToString( in, NULL, 0, &length, &encoding, 0)))
fprintf(stderr,"%ld %s\n",length, s);
if ((s = Yap_TermToString( in, buf, 256, &length, &encoding, 0)))
fprintf(stderr,"%ld %s\n",length, s);
return TRUE;
}
*/
void
Yap_InitIOPreds(void)
@ -1101,6 +1119,7 @@ Yap_InitIOPreds(void)
Yap_InitCPred ("$get_read_error_handler", 1, p_get_read_error_handler, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("$read", 7, p_read, SyncPredFlag|HiddenPredFlag|UserCPredFlag);
Yap_InitCPred ("$read", 8, p_read2, SyncPredFlag|HiddenPredFlag|UserCPredFlag);
/* test predicate Yap_InitCPred ("write_string", 2, p_write_string, SyncPredFlag|UserCPredFlag); */
Yap_InitCPred ("$start_line", 1, p_startline, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("$change_type_of_char", 2, p_change_type_of_char, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred ("$type_of_char", 2, p_type_of_char, SafePredFlag|SyncPredFlag|HiddenPredFlag);

View File

@ -836,7 +836,72 @@ PL_get_chars(term_t t, char **s, unsigned flags)
{ return PL_get_nchars(t, NULL, s, flags);
}
char *Yap_TermToString(Term t, char *s, size_t sz, size_t *length, int *encoding, int flags);
char *
Yap_TermToString(Term t, char *s, size_t sz, size_t *length, int *encoding, int flags)
{
CACHE_REGS
Int l;
Yap_StartSlots( PASS_REGS1 );
l = Yap_InitSlot(t);
{ IOENC encodings[3];
IOENC *enc;
char *r, buf[256];
encodings[0] = ENC_ISO_LATIN_1;
encodings[1] = ENC_WCHAR;
encodings[2] = ENC_UNKNOWN;
for(enc = encodings; *enc != ENC_UNKNOWN; enc++)
{
int64_t size;
IOSTREAM *fd;
if (s) {
r = s;
} else {
r = buf;
}
fd = Sopenmem(&r, &sz, "w");
fd->encoding = *enc;
if ( PL_write_term(fd, l, 1200, flags) &&
Sputcode(EOS, fd) >= 0 &&
Sflush(fd) >= 0 )
{ *encoding = *enc;
size = Stell64(fd);
if ( *enc == ENC_ISO_LATIN_1 )
{
*length = size-1;
} else
{
*length = (size/sizeof(pl_wchar_t))-1;
}
/* found, just check if using local space */
if (r == buf) {
char *bf = malloc(*length+1);
if (!bf)
return NULL;
strncpy(bf,buf,*length+1);
r = bf;
}
/* go away */
Yap_CloseSlots( PASS_REGS1 );
return r;
} else
{ Sclose(fd);
}
}
/* failed */
if ( r != s && r != buf ) {
Sfree(r);
}
}
Yap_CloseSlots( PASS_REGS1 );
return NULL;
}
X_API int

View File

@ -278,7 +278,7 @@ int STD_PROTO(Yap_GetCharForSIGINT,(void));
Int STD_PROTO(Yap_StreamToFileNo,(Term));
Term STD_PROTO(Yap_OpenStream,(FILE *,char *,Term,int));
Term STD_PROTO(Yap_StringToTerm,(char *,Term *));
int Yap_TermToString(Term t, char *s, size_t sz, int flags);
char *Yap_TermToString(Term t, char *s, size_t sz, size_t *length, int *encoding, int flags);
int Yap_GetFreeStreamD(void);
int Yap_GetFreeStreamDForReading(void);

View File

@ -17738,11 +17738,24 @@ flags in the @code{flag} argument: @code{YAP_WRITE_QUOTED},
@var{buff}, @code{size_t}
@var{size}, @code{int} @var{flags})
@findex YAP_WriteBuffer/4
Write a YAP_Term @var{t} to buffer @var{buff} with size @var{size}. The
flag are currently ignored. This function can fail, say, if the term
cannot be encoded in ISO-LATIN8. The code always uses
@code{YAP_WRITE_HANDLE_VARS}. You may also use @code{YAP_WRITE_QUOTED},
and @code{YAP_WRITE_IGNORE_OPS} together.
Write a YAP_Term @var{t} to buffer @var{buff} with size
@var{size}. The term is written
according to a mask of the following flags in the @code{flag}
argument: @code{YAP_WRITE_QUOTED}, @code{YAP_WRITE_HANDLE_VARS},
@code{YAP_WRITE_USE_PORTRAY}, and @code{YAP_WRITE_IGNORE_OPS}. The
function will fail if it does not have enough space in the buffer.
@item @code{char *} YAP_WriteDynamicBuffer(@code{YAP_Term} @var{t}, @code{char *}
@var{buff}, @code{size_t}
@var{size}, @code{size_t}
@var{*lengthp}, @code{size_t}
@var{*encodingp}, @code{int} @var{flags})
@findex YAP_WriteDynamicBuffer/6
Write a YAP_Term @var{t} to buffer @var{buff} with size
@var{size}. The code will allocate an extra buffer if @var{buff} is
@code{NULL} or if @code{buffer} does not have enough room. The
variable @code{lengthp} is assigned the size of the resulting buffer,
and @code{encodingp} will receive the type of encoding (currently only @code{PL_ENC_ISO_LATIN_1} and @code{PL_ENC_WCHAR} are supported)
@item @code{void} YAP_InitConsult(@code{int} @var{mode}, @code{char *} @var{filename})
@findex YAP_InitConsult/2

View File

@ -255,6 +255,21 @@ typedef enum
YAPC_COMPILE_ALL /* compile all predicates */
} yapc_exec_mode;
/********* encoding ***********************/
typedef enum
{ PL_ENC_UNKNOWN = 0, /* invalid/unknown */
PL_ENC_OCTET, /* raw 8 bit input */
PL_ENC_ASCII, /* US-ASCII (0..127) */
PL_ENC_ISO_LATIN_1, /* ISO Latin-1 (0..256) */
PL_ENC_ANSI, /* default (multibyte) codepage */
PL_ENC_UTF8,
PL_ENC_UNICODE_BE, /* big endian unicode file */
PL_ENC_UNICODE_LE, /* little endian unicode file */
PL_ENC_WCHAR /* pl_wchar_t */
} PL_IOENC;
/********* YAP C-Flags ***********************/
typedef enum