Exemplo n.º 1
0
int stream_write_block(StreamWriter *sp, StreamBlock *blk, STREAM_CHECKSUM check)
/*=============================================================================*/
{
  blk->error = 0 ;
  if (blk->type == '#') blk->error = STREAM_ERROR_HASHRESERVED ;
  else {
    int n ;
    char *json ;
    char lenbuf[32] ;

    md5_state_t md5, *md5p ;
    if (sp->checksum || check) {
      md5p = &md5 ;
      md5_init(md5p) ;
      }
    else md5p = NULL ;

    if (blk->header) {
      cJSON_DeleteItemFromObject(blk->header, "length") ;
      cJSON_AddNumberToObject(blk->header, "length", blk->length) ;
      json = cJSON_PrintUnformatted(blk->header) ;
      }
    else {
      json = calloc(32, 1) ;
      sprintf(json, "{\"length\":%d}", blk->length) ;
      }
    stream_write_data(sp->file, "#", 1, md5p) ;
    stream_write_data(sp->file, &blk->type, 1, md5p) ;
    sprintf(lenbuf, "%d", (int)strlen(json)) ;
    stream_write_data(sp->file, lenbuf, strlen(lenbuf), md5p) ;
    stream_write_data(sp->file, json, strlen(json), md5p) ;
    stream_write_data(sp->file, "\n", 1, md5p) ;
    free(json) ;
    n = 0 ;
    while (n < blk->length) {
      int w = min(blk->length - n, STREAM_BUFFER_SIZE) ;
      w = stream_write_data(sp->file, blk->content + n, w, md5p) ;
      if (w < 0) {
        blk->error = STREAM_ERROR_WRITEOF ;
        break ;
        }
      n += w ;
      }
    write(sp->file, "##", 2) ;
    if (md5p) {
      md5_byte_t digest[16] ;
      char hexdigest[33] ;
      int i ;
      md5_finish(md5p, digest) ;
      for (i = 0 ;  i < 16 ;  ++i) sprintf(hexdigest + 2*i, "%02x", digest[i]) ;
      write(sp->file, hexdigest, 32) ;
      }
    write(sp->file, "\n", 1) ;
    }
  return blk->error ;
  }
Exemplo n.º 2
0
static int stdout_print(Value *vret, Value *v, RefNode *node)
{
    int new_line = FUNC_INT(node);
    Value *varg = v + 1;

    if (fg->v_ctextio == VALUE_NULL) {
        v_ctextio_init();
    }
    *v = Value_cp(fg->v_ctextio);

    while (varg < fg->stk_top) {
        if (!textio_print_sub(*v, NULL, *varg, NULL)) {
            return FALSE;
        }
        varg++;
    }
    if (new_line && !stream_write_data(fg->v_cio, "\n", 1)) {
        return FALSE;
    }

    return TRUE;
}
Exemplo n.º 3
0
static int textio_print(Value *vret, Value *v, RefNode *node)
{
    Ref *ref = Value_ref(*v);
    Value *varg = v + 1;
    int new_line = FUNC_INT(node);
    Value stream = ref->v[INDEX_TEXTIO_STREAM];
    RefNode *s_type = Value_type(stream);
    StrBuf *sb = NULL;

    if (s_type == fs->cls_bytesio) {
        sb = bytesio_get_strbuf(stream);
    }
    while (varg < fg->stk_top) {
        if (!textio_print_sub(*v, sb, *varg, NULL)) {
            return FALSE;
        }
        varg++;
    }

    if (new_line) {
        RefTextIO *tio = Value_vp(ref->v[INDEX_TEXTIO_TEXTIO]);
        if (tio == NULL || tio->cs->ascii) {
            if (sb != NULL) {
                if (!StrBuf_add_c(sb, '\n')) {
                    return FALSE;
                }
            } else if (!stream_write_data(stream, "\n", 1)) {
                return FALSE;
            }
        } else {
            if (!stream_write_sub_s(stream, sb, "\n", 1, tio)) {
                return FALSE;
            }
        }
    }
    return TRUE;
}
Exemplo n.º 4
0
/**
 * 文字コードを変換しながらStreamに出力する
 * v : stream (optional,sb==NULLの場合必須)
 * sb : StrBuf : (optional)
 */
static int stream_write_sub_s(Value v, StrBuf *sb, const char *s_p, int s_size, RefTextIO *tio)
{
    if (s_size < 0) {
        s_size = strlen(s_p);
    }
    // TODO:未検証
    if (v != VALUE_NULL) {
        RefBytesIO *mb = Value_vp(v);
        if (mb->rh.type == fs->cls_bytesio) {
            sb = &mb->buf;
        }
    }
    if (sb != NULL) {
        // sprintfの場合tio==NULL
        if (tio == NULL || tio->cs->utf8) {
            if (!StrBuf_add(sb, s_p, s_size)) {
                return FALSE;
            }
            return TRUE;
        } else {
            if (tio->out.ic == (void*)-1) {
                if (!IconvIO_open(&tio->out, fs->cs_utf8, tio->cs, tio->trans ? "?" : NULL)) {
                    return FALSE;
                }
            }
            if (!IconvIO_conv(&tio->out, sb, s_p, s_size, TRUE, TRUE)) {
                return FALSE;
            }
            return TRUE;
        }
    } else {
        if (tio == NULL || tio->cs->utf8) {
            return stream_write_data(v, s_p, s_size);
        } else {
            Ref *r = Value_ref(v);
            IconvIO *ic = &tio->out;
            Value *vmb = &r->v[INDEX_WRITE_MEMIO];
            RefBytesIO *mb;
            int max = Value_integral(r->v[INDEX_WRITE_MAX]);

            if (max == -1) {
                throw_error_select(THROW_NOT_OPENED_FOR_WRITE);
                return FALSE;
            }
            if (tio->out.ic == (void*)-1) {
                if (!IconvIO_open(&tio->out, fs->cs_utf8, tio->cs, tio->trans ? "?" : NULL)) {
                    return FALSE;
                }
            }
            if (*vmb == VALUE_NULL) {
                *vmb = vp_Value(bytesio_new_sub(NULL, BUFFER_SIZE));
                max = BUFFER_SIZE;
                r->v[INDEX_WRITE_MAX] = int32_Value(max);
                // STDOUTだけ特別扱い
                if (fs->cgi_mode) {
                    if (r == Value_vp(fg->v_cio)) {
                        send_headers();
                    }
                }
            }
            mb = Value_vp(*vmb);

            ic->inbuf = s_p;
            ic->inbytesleft = s_size;
            ic->outbuf = mb->buf.p + mb->buf.size;
            ic->outbytesleft = max - mb->buf.size;

            for (;;) {
                switch (IconvIO_next(ic)) {
                case ICONV_OK:
                    mb->buf.size = ic->outbuf - mb->buf.p;
                    goto BREAK;
                case ICONV_OUTBUF:
                    mb->buf.size = ic->outbuf - mb->buf.p;
                    if (!stream_flush_sub(v)) {
                        return FALSE;
                    }
                    ic->outbuf = mb->buf.p;
                    ic->outbytesleft = max;
                    break;
                case ICONV_INVALID:
                    if (tio->trans) {
                        const char *ptr;
                        if (ic->outbytesleft == 0) {
                            mb->buf.size = ic->outbuf - mb->buf.p;
                            if (!stream_flush_sub(v)) {
                                return FALSE;
                            }
                            ic->outbuf = mb->buf.p;
                            ic->outbytesleft = max;
                        }
                        ptr = ic->inbuf;

                        *ic->outbuf++ = '?';
                        ic->outbytesleft--;

                        // 1文字進める
                        utf8_next(&ptr, ptr + ic->inbytesleft);
                        ic->inbytesleft -= ptr - ic->inbuf;
                        ic->inbuf = ptr;
                    } else {
                        RefCharset *cs = tio->cs;
                        throw_errorf(fs->mod_lang, "CharsetError", "Cannot convert %U to %S",
                                utf8_codepoint_at(ic->inbuf), cs->name);
                        return FALSE;
                    }
                    break;
                }
            }
        BREAK:
            return TRUE;
        }
    }
}