int Scm_CharReadyUnsafe(ScmPort *p) #endif { int r = 0; VMDECL; SHORTCUT(p, return Scm_CharReadyUnsafe(p)); if (!SCM_IPORTP(p)) Scm_Error("input port required, but got %S", p); LOCK(p); if (p->ungotten != SCM_CHAR_INVALID) r = TRUE; else { switch (SCM_PORT_TYPE(p)) { case SCM_PORT_FILE: if (p->src.buf.current < p->src.buf.end) r = TRUE; else if (p->src.buf.ready == NULL) r = TRUE; else { SAFE_CALL(p, r = (p->src.buf.ready(p) != SCM_FD_WOULDBLOCK)); } break; case SCM_PORT_PROC: SAFE_CALL(p, r = p->src.vt.Ready(p, TRUE)); break; default: r = TRUE; } } UNLOCK(p); return r; }
static void readerror_port_set(ScmReadError *obj, ScmObj val) { if (SCM_IPORTP(val)) { obj->port = SCM_PORT(val); } else if (SCM_FALSEP(val)) { obj->port = NULL; } else { Scm_Error("input port or #f required, but got %S", val); } }
ScmObj Scm_MakeInputConversionPort(ScmPort *fromPort, const char *fromCode, const char *toCode, ScmObj handler, int bufsiz, int ownerp) { char *inbuf = NULL; int preread = 0; if (!SCM_IPORTP(fromPort)) Scm_Error("input port required, but got %S", fromPort); if (bufsiz <= 0) bufsiz = DEFAULT_CONVERSION_BUFFER_SIZE; if (bufsiz <= MINIMUM_CONVERSION_BUFFER_SIZE) { bufsiz = MINIMUM_CONVERSION_BUFFER_SIZE; } conv_guess *guess = findGuessingProc(fromCode); if (guess) { const char *guessed; inbuf = SCM_NEW_ATOMIC2(char *, bufsiz); preread = Scm_Getz(inbuf, bufsiz, fromPort); if (preread <= 0) { /* Input buffer is already empty or unreadable. Determining character code is not necessary. We just return a dummy empty port. */ return Scm_MakeInputStringPort(SCM_STRING(SCM_MAKE_STR("")), FALSE); } guessed = guess->proc(inbuf, preread, guess->data); if (guessed == NULL) Scm_Error("%s: failed to guess input encoding", fromCode); fromCode = guessed; } ScmConvInfo *cinfo = jconv_open(toCode, fromCode); if (cinfo == NULL) { Scm_Error("conversion from code %s to code %s is not supported", fromCode, toCode); } cinfo->remote = fromPort; cinfo->ownerp = ownerp; cinfo->bufsiz = bufsiz; cinfo->remoteClosed = FALSE; if (preread > 0) { cinfo->buf = inbuf; cinfo->ptr = inbuf + preread; } else { cinfo->buf = SCM_NEW_ATOMIC2(char *, cinfo->bufsiz); cinfo->ptr = cinfo->buf; } ScmPortBuffer bufrec; memset(&bufrec, 0, sizeof(bufrec)); bufrec.size = cinfo->bufsiz; bufrec.buffer = SCM_NEW_ATOMIC2(char *, cinfo->bufsiz); bufrec.mode = SCM_PORT_BUFFER_FULL; bufrec.filler = conv_input_filler; bufrec.flusher = NULL; bufrec.closer = conv_input_closer; bufrec.ready = conv_ready; bufrec.filenum = conv_fileno; bufrec.data = (void*)cinfo; ScmObj name = conv_name(SCM_PORT_INPUT, fromPort, fromCode, toCode); return Scm_MakeBufferedPort(SCM_CLASS_PORT, name, SCM_PORT_INPUT, TRUE, &bufrec); }