--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+p
+{
+ color:red;
+ text-align:center;
+}
+</style>
+</head>
+
+<body>
+<p>Hello World!</p>
+<p>这个段落采用CSS样式化。</p>
+</body>
+
+</html>
CFILES += main.c
CFILES += abc_obj.c
CFILES += abc_html.c
-CFILES += abc_html_util.c
+CFILES += abc_css.c
+CFILES += abc_io_util.c
CFILES += abc_io_file.c
CFILES += abc_io_http.c
+CFILES += abc_io_str.c
CFILES += ../js/util/scf_string.c
CFILES += ../js/util/scf_graph.c
--- /dev/null
+#include"abc_html.h"
+int __html_add_attr(abc_obj_t* obj, int type, char** names, const char* value, int flags);
+html_label_t* __html_find_label(const char* name);
+
+static int __css_parse_value(abc_obj_t* css, abc_obj_t* attr)
+{
+ scf_string_t* value = scf_string_alloc();
+ if (!value)
+ return -ENOMEM;
+
+ abc_char_t* c = NULL;
+ abc_char_t* c2 = NULL;
+
+ while (1) {
+ c = __io_pop_char(&css->io);
+ if (!c) {
+ scf_loge("\n");
+ scf_string_free(value);
+ return -1;
+ }
+
+ css->text_pos += c->len;
+
+ if (';' == c->c)
+ break;
+ else
+ scf_string_cat_cstr_len(value, c->utf8, c->len);
+
+ free(c);
+ c = NULL;
+ }
+
+ int tmp = c->c;
+
+ free(c);
+ c = NULL;
+
+ if (attr->value)
+ scf_string_free(attr->value);
+
+ attr->value = value;
+ return tmp;
+}
+
+static int __css_parse_attr2(abc_obj_t* css, abc_obj_t* obj, const html_attr_t* attrs, int n_attrs)
+{
+ scf_string_t* key = scf_string_alloc();
+ if (!key)
+ return -ENOMEM;
+
+ abc_char_t* c = NULL;
+
+ while (1) {
+ c = __io_pop_char(&css->io);
+ if (!c) {
+ scf_loge("\n");
+ scf_string_free(key);
+ return -1;
+ }
+
+ css->text_pos += c->len;
+
+ if ('}' == c->c) {
+ free(c);
+ scf_string_free(key);
+ return '}';
+ }
+
+ if (':' == c->c)
+ break;
+
+ if ('_' == c->c
+ || '-' == c->c
+ || ('a' <= c->c && 'z' >= c->c)) {
+ scf_string_cat_cstr_len(key, c->utf8, c->len);
+
+ } else if (' ' == c->c || '\t' == c->c || '\r' == c->c) {
+
+ } else {
+ scf_loge("invalid char '%c:%#x' in CSS attribute, file: %s, line: %d\n",
+ c->c, c->c, css->file->data, css->text_line);
+ assert(0);
+ free(c);
+ scf_string_free(key);
+ return -1;
+ }
+
+ free(c);
+ c = NULL;
+ }
+
+ int tmp = c->c;
+
+ free(c);
+ c = NULL;
+
+ scf_list_t* l;
+ abc_obj_t* attr;
+
+ int i;
+ int j;
+ if (attrs && n_attrs > 0) {
+ for (i = 0; i < n_attrs; i++) {
+
+ for (j = 0; attrs[i].names[j]; j++) {
+ if (!strcmp(attrs[i].names[j], key->data))
+ goto found;
+ }
+ }
+ }
+
+ scf_loge("invalid HTML attribute '%s' in file: %s, line: %d\n", key->data, css->file->data, css->text_pos);
+ scf_string_free(key);
+ return -1;
+
+found:
+ for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
+ attr = scf_list_data(l, abc_obj_t, list);
+
+ for (j = 0; attr->keys[j]; j++) {
+ if (!strcmp(attr->keys[j], key->data))
+ break;
+ }
+ }
+
+ if (l == scf_list_sentinel(&obj->attrs)) {
+ int ret = __html_add_attr(obj, attrs[i].type, attrs[i].names, attrs[i].value, attrs[i].flags);
+ if (ret < 0)
+ return ret;
+
+ l = scf_list_tail(&obj->attrs);
+ attr = scf_list_data(l, abc_obj_t, list);
+ }
+
+ scf_string_free(key);
+ key = NULL;
+
+ attr->line = css->text_line;
+ attr->pos = css->text_pos;
+
+ return __css_parse_value(css, attr);
+}
+
+static int __css_parse_attr(abc_obj_t* css, abc_obj_t* obj, const html_attr_t* attrs, int n_attrs)
+{
+ int ret = 0;
+
+ while (1) {
+ ret = __css_parse_attr2(css, obj, attrs, n_attrs);
+ if (ret < 0)
+ return ret;
+
+ if ('}' == ret)
+ break;
+ }
+
+ return ret;
+}
+
+static int __css_parse_obj(abc_obj_t* css, abc_char_t* c)
+{
+ html_label_t* label;
+ abc_obj_t* obj;
+
+ scf_string_t* key = scf_string_cstr_len(c->utf8, c->len);
+
+ css->text_pos += c->len;
+ free(c);
+ c = NULL;
+
+ if (!key)
+ return -ENOMEM;
+
+ while (1) {
+ c = __io_pop_char(&css->io);
+ if (!c) {
+ scf_loge("\n");
+ scf_string_free(key);
+ return -1;
+ }
+
+ css->text_pos += c->len;
+
+ if (' ' == c->c || '{' == c->c)
+ break;
+
+ if ('\n' == c->c) {
+ css->text_line++;
+ css->text_pos = 0;
+ break;
+ }
+
+ scf_string_cat_cstr_len(key, c->utf8, c->len);
+ free(c);
+ c = NULL;
+ }
+
+ int tmp = c->c;
+ int ret;
+
+ free(c);
+ c = NULL;
+
+ label = __html_find_label(key->data);
+ if (!label) {
+ scf_loge("invalid HTML label '%s' in file: %s, line: %d\n",
+ key->data, css->file->data, css->text_line);
+ scf_string_free(key);
+ return -1;
+ }
+
+ scf_string_free(key);
+ key = NULL;
+
+ obj = abc_obj_alloc(css->file, css->text_line, css->text_pos, label->type);
+ if (!obj)
+ return -ENOMEM;
+
+ obj->flags = label->flags;
+ obj->keys = label->names;
+
+ obj->parent = css;
+
+ switch (tmp) {
+ case '{':
+ ret = __css_parse_attr(css, obj, label->attrs, label->n_attrs);
+ if (ret < 0) {
+ abc_obj_free(obj);
+ return ret;
+ }
+ break;
+ default:
+ ret = 0;
+ break;
+ };
+
+ scf_list_add_tail(&css->childs, &obj->list);
+ return 0;
+}
+
+int abc_css_parse(abc_obj_t* css)
+{
+ abc_char_t* c;
+ abc_io_t* io = abc_io_array[ABC_PROTO_STR];
+
+ css->io.proto = io->proto;
+ css->io.priv = NULL;
+ css->io.open = io->open;
+ css->io.close = io->close;
+ css->io.popc = io->popc;
+ css->io.post = io->post;
+
+ css->text_line = 1;
+ css->text_pos = 0;
+
+ int ret = io->open(&css->io, css->text->data);
+ if (ret < 0)
+ return ret;
+
+ while (1) {
+ c = __io_pop_char(&css->io);
+ if (!c)
+ return -1;
+
+ if (EOF == c->c) {
+ free(c);
+ return 0;
+ }
+
+ if ('\n' == c->c || '\r' == c->c) {
+ css->text_line++;
+ css->text_pos = 0;
+
+ free(c);
+ continue;
+ }
+
+ if (' ' == c->c || '\t' == c->c) {
+ css->text_pos++;
+ free(c);
+ continue;
+ }
+
+ if (('a' <= c->c && 'z' >= c->c)
+ || (0x4e00 <= c->c && 0x9fa5 >= c->c)) {
+
+ int ret = __css_parse_obj(css, c);
+ if (ret < 0) {
+ scf_loge("css->text_line: %d, css->text_pos: %d\n", css->text_line, css->text_pos);
+ return ret;
+ }
+ } else {
+ scf_loge("%c:%#x, css->text_line: %d, css->text_pos: %d\n", c->c, c->c, css->text_line, css->text_pos);
+ free(c);
+ return -1;
+ }
+ }
+
+ return -1;
+}
#include"abc_html.h"
-typedef struct {
- char** names;
- char* value;
- int type;
- int flags;
-} html_attr_t;
-
-typedef struct {
- char** names;
- int type;
-
- int n_attrs;
- html_attr_t* attrs;
-
- uint32_t flags;
-} html_label_t;
-
-#define abc_number_of(__array) (sizeof(__array) / sizeof(__array[0]))
-
-extern abc_io_t abc_io_file;
-extern abc_io_t abc_io_http;
-
-static abc_io_t* abc_io_array[ABC_PROTO_NB] =
-{
- [ABC_PROTO_FILE] = &abc_io_file,
- [ABC_PROTO_HTTP] = &abc_io_http,
-};
-
// HTML attrs
static char* src_keys[] = {"src", "源", NULL};
static char* href_keys[] = {"href", "地址", NULL};
static char* font_keys[] = {"font", "字体", NULL};
static char* font_size_keys[] = {"font-size", "字号", NULL};
-static char* font_color_keys[] = {"font-color", "字体颜色", NULL};
+static char* font_color_keys[] = {"font-color", "字体颜色", "color", "颜色", NULL};
+
+static char* text_align_keys[] = {"text-align", "对齐", NULL};
static char* type_keys[] = {"type", "类型", NULL};
static char* name_keys[] = {"name", "名字", NULL};
static char* progress_keys[] = {"progress", "进度条", NULL};
static char* script_keys[] = {"script", "脚本", NULL};
+static char* style_keys[] = {"style", "样式", NULL};
static html_attr_t html_attrs[] =
{
static html_attr_t p_attrs[] =
{
- {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0},
- {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0},
+ {font_keys, "SimSong", ABC_HTML_ATTR_FONT, 0},
+ {font_size_keys, "16", ABC_HTML_ATTR_FONT_SIZE, 0},
+ {font_color_keys, "black", ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
+ {text_align_keys, "left", ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
};
static html_attr_t a_attrs[] =
{progress_keys, ABC_HTML_PROGRESS, 0, NULL, ABC_HTML_FLAG_OPEN},
{script_keys, ABC_HTML_SCRIPT, abc_number_of(script_attrs), script_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+
+ {style_keys, ABC_HTML_STYLE, 0, NULL, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
};
static int __html_parse_obj(abc_html_t* html, abc_char_t* c);
-
-static html_label_t* __html_find_label(const char* name)
+html_label_t* __html_find_label(const char* name)
{
html_label_t* label;
return NULL;
}
-static int __html_add_attr(abc_obj_t* obj, int type, char** names, const char* value, int flags)
+int __html_add_attr(abc_obj_t* obj, int type, char** names, const char* value, int flags)
{
abc_obj_t* attr = abc_obj_alloc(NULL, 0, 0, type);
if (!attr)
html->io.popc = io->popc;
html->io.post = io->post;
- ret = io->post(html, url->data + n, content);
+ ret = io->post(&html->io, url->data + n, content);
if (ret < 0) {
scf_string_free(url);
scf_string_free(content);
html->io.popc = io->popc;
html->io.post = io->post;
- int ret = io->open(html, path + n);
+ int ret = io->open(&html->io, path + n);
if (ret < 0) {
free(html);
return ret;
abc_char_t* c;
if (html) {
- while ( html->tmp_list) {
- c = html->tmp_list;
+ while ( html->io.tmp_list) {
+ c = html->io.tmp_list;
- html->tmp_list = c->next;
+ html->io.tmp_list = c->next;
free(c);
}
abc_obj_free(html->root);
if (html->io.close)
- html->io.close(html);
+ html->io.close(&html->io);
if (html->file)
scf_string_free(html->file);
abc_char_t* c = NULL;
while (1) {
- c = __html_pop_char(html);
+ c = __io_pop_char(&html->io);
if (!c) {
scf_loge("\n");
scf_string_free(end);
int flag = 0;
while (1) {
- c = __html_pop_char(html);
+ c = __io_pop_char(&html->io);
if (!c) {
scf_loge("\n");
scf_string_free(text);
if (ABC_HTML_SCRIPT != obj->type)
break;
- abc_char_t* c2 = __html_pop_char(html);
+ abc_char_t* c2 = __io_pop_char(&html->io);
if (!c2) {
scf_loge("\n");
scf_string_free(text);
return -1;
}
- __html_push_char(html, c2);
+ __io_push_char(&html->io, c2);
if ('/' == c2->c)
break;
text = NULL;
if (ABC_HTML_FLAG_OPEN == (obj->flags & 0x1)) { // single labels
- __html_push_char(html, c);
+ __io_push_char(&html->io, c);
c = NULL;
return 0;
};
free(c);
c = NULL;
- c = __html_pop_char(html);
+ c = __io_pop_char(&html->io);
if (!c) {
scf_loge("\n");
free(c);
int flag = 0;
while (1) {
- c = __html_pop_char(html);
+ c = __io_pop_char(&html->io);
if (!c) {
scf_loge("\n");
scf_string_free(value);
break;
if ('/' == c->c) {
- c2 = __html_pop_char(html);
+ c2 = __io_pop_char(&html->io);
- __html_push_char(html, c2);
+ __io_push_char(&html->io, c2);
if ('>' == c2->c)
break;
}
abc_char_t* c = NULL;
while (1) {
- c = __html_pop_char(html);
+ c = __io_pop_char(&html->io);
if (!c) {
scf_loge("\n");
scf_string_free(key);
return ret;
}
#if 1
- assert(!html->tmp_list_js);
+ assert(!html->io.tmp_list_js);
void* so = dlopen(obj->js_so->data, RTLD_LAZY);
void (*f)() = dlsym(so, "__js_main");
so = NULL;
#endif
abc_char_t* c;
- while ( html->tmp_list_js) {
- c = html->tmp_list_js;
+ while ( html->io.tmp_list_js) {
+ c = html->io.tmp_list_js;
- html->tmp_list_js = c->next;
+ html->io.tmp_list_js = c->next;
- c->next = html->tmp_list;
- html->tmp_list = c;
+ c->next = html->io.tmp_list;
+ html->io.tmp_list = c;
}
}
return -ENOMEM;
while (1) {
- c = __html_pop_char(html);
+ c = __io_pop_char(&html->io);
if (!c) {
scf_loge("\n");
scf_string_free(key);
}
if ('/' == ret) {
- c = __html_pop_char(html);
+ c = __io_pop_char(&html->io);
if (!c) {
scf_loge("\n");
return -1;
return -1;
break;
+ case ABC_HTML_STYLE:
+ if (obj->text) {
+ scf_logi("\033[33mcss: %s\033[0m\n", obj->text->data);
+
+ if (abc_css_parse(obj) < 0)
+ return -1;
+ }
+ break;
+
case ABC_HTML_VIDEO:
html->has_video = 1;
abc_char_t* c;
while (1) {
- c = __html_pop_char(html);
+ c = __io_pop_char(&html->io);
if (!c)
return -1;
free(c);
- c = __html_pop_char(html);
+ c = __io_pop_char(&html->io);
if ('!' == c->c) { // <! note >
free(c);
while (1) {
- c = __html_pop_char(html);
+ c = __io_pop_char(&html->io);
int tmp = c->c;
free(c);
#ifndef ABC_HTML_H
#define ABC_HTML_H
+#include"abc_io.h"
#include"abc_obj.h"
#include"scf_parse.h"
-typedef struct abc_char_s abc_char_t;
typedef struct abc_html_s abc_html_t;
-typedef struct abc_io_s abc_io_t;
-enum abc_protos
-{
- ABC_PROTO_FILE,
- ABC_PROTO_HTTP,
-
- ABC_PROTO_NB
-};
-
-#define ABC_UTF8_MAX 6
-struct abc_char_s
-{
- abc_char_t* next;
- int c;
+typedef struct {
+ char** names;
+ char* value;
+ int type;
+ int flags;
+} html_attr_t;
- int len;
- uint8_t utf8[ABC_UTF8_MAX];
-};
+typedef struct {
+ char** names;
+ int type;
-struct abc_io_s
-{
- char* proto;
- void* priv;
+ int n_attrs;
+ html_attr_t* attrs;
- int (*open )(abc_html_t* html, const char* path);
- void (*close)(abc_html_t* html);
+ uint32_t flags;
+} html_label_t;
- int (*popc )(abc_html_t* html);
- int (*post )(abc_html_t* html, const char* path, scf_string_t* content);
-};
+#define abc_number_of(__array) (sizeof(__array) / sizeof(__array[0]))
struct abc_html_s
{
scf_list_t list;
- abc_char_t* tmp_list;
- abc_char_t* tmp_list_js;
-
abc_obj_t* root;
abc_obj_t* current;
scf_parse_t* js;
- uint8_t download :1;
uint8_t has_video:1;
};
void abc_html_close(abc_html_t* html);
int abc_html_parse(abc_html_t* html);
-
-abc_char_t* __html_pop_char (abc_html_t* html);
-void __html_push_char(abc_html_t* html, abc_char_t* c);
+int abc_css_parse (abc_obj_t* css);
#endif
--- /dev/null
+#ifndef ABC_IO_H
+#define ABC_IO_H
+
+#include"scf_string.h"
+#include"scf_list.h"
+
+typedef struct abc_char_s abc_char_t;
+typedef struct abc_io_s abc_io_t;
+
+enum abc_protos
+{
+ ABC_PROTO_FILE,
+ ABC_PROTO_HTTP,
+ ABC_PROTO_STR,
+
+ ABC_PROTO_NB
+};
+
+extern abc_io_t* abc_io_array[ABC_PROTO_NB];
+
+#define ABC_UTF8_MAX 6
+struct abc_char_s
+{
+ abc_char_t* next;
+ int c;
+
+ int len;
+ uint8_t utf8[ABC_UTF8_MAX];
+};
+
+struct abc_io_s
+{
+ char* proto;
+
+ void* priv;
+ uint8_t download:1;
+
+ abc_char_t* tmp_list;
+ abc_char_t* tmp_list_js;
+
+ int (*open )(abc_io_t* io, const char* path);
+ void (*close)(abc_io_t* io);
+
+ int (*popc )(abc_io_t* io);
+ int (*post )(abc_io_t* io, const char* path, scf_string_t* content);
+};
+
+abc_char_t* __io_pop_char (abc_io_t* io);
+void __io_push_char(abc_io_t* io, abc_char_t* c);
+
+#endif
-#include"abc_html.h"
+#include"abc_io.h"
-static int __file_open(abc_html_t* html, const char* path)
+static int __file_open(abc_io_t* io, const char* path)
{
- if (!html || !path)
+ if (!io || !path)
return -EINVAL;
- html->io.priv = fopen(path, "r");
- if (!html->io.priv) {
+ io->priv = fopen(path, "r");
+ if (!io->priv) {
char cwd[4096];
getcwd(cwd, 4095);
return -1;
}
- html->download = 1;
+ io->download = 1;
return 0;
}
-static void __file_close(abc_html_t* html)
+static void __file_close(abc_io_t* io)
{
- if (html && html->io.priv) {
-
- fclose(html->io.priv);
- }
+ if (io && io->priv)
+ fclose(io->priv);
}
-static int __file_popc(abc_html_t* html)
+static int __file_popc(abc_io_t* io)
{
- if (html && html->io.priv) {
-
- return fgetc(html->io.priv);
- }
-
+ if (io && io->priv)
+ return fgetc(io->priv);
return EOF;
}
-#include"abc_html.h"
+#include"abc_io.h"
typedef struct {
scf_string_t* host;
}
}
-static int http_filter_chunk(abc_html_t* html)
+static int http_filter_chunk(abc_io_t* io)
{
- abc_http_t* http = html->io.priv;
+ abc_http_t* http = io->priv;
- if (html->download)
+ if (io->download)
return 0;
while (http->cpos < http->rbuf->len) {
http->cpos += 2;
if (0 == http->content_length) {
- html->download = 1;
+ io->download = 1;
return 0;
}
static void* http_thread(void* arg)
{
- abc_html_t* html = arg;
- abc_http_t* http = html->io.priv;
+ abc_io_t* io = arg;
+ abc_http_t* http = io->priv;
while (!http->exit) {
struct epoll_event ev;
if (http->rpos > 0) {
if (!http->chunk_flag) {
if (http->content_length == http->rbuf->len - http->rpos) {
- html->download = 1;
+ io->download = 1;
scf_logi("http response: %s\n", http->rbuf->data);
}
} else {
- http_filter_chunk(html);
+ http_filter_chunk(io);
- if (html->download)
+ if (io->download)
scf_logi("http response: %s\n", http->rbuf->data);
}
}
if (ev.events & EPOLLOUT) {
pthread_mutex_lock(&http->mutex);
if (0 == http->wpos) {
- html->download = 0;
+ io->download = 0;
http->rbuf->len = 0;
http->rpos = 0;
}
return 0;
}
-static int __http_open(abc_html_t* html, const char* path)
+static int __http_open(abc_io_t* io, const char* path)
{
- if (!html || !path)
+ if (!io || !path)
return -EINVAL;
abc_http_t* http = NULL;
ABC_HTTP_FILL("Accept: */*\r\n");
ABC_HTTP_FILL("\r\n");
- html->io.priv = http;
+ io->priv = http;
- if (pthread_create(&http->tid, NULL, http_thread, html)) {
+ if (pthread_create(&http->tid, NULL, http_thread, io)) {
abc_http_close(http);
- html->io.priv = NULL;
+ io->priv = NULL;
return -1;
}
return 0;
}
-static int __http_post(abc_html_t* html, const char* path, scf_string_t* content)
+static int __http_post(abc_io_t* io, const char* path, scf_string_t* content)
{
- if (!html || !path || !content)
+ if (!io || !path || !content)
return -EINVAL;
abc_http_t* http = NULL;
ABC_HTTP_FILL(content->data);
- html->io.priv = http;
+ io->priv = http;
- if (pthread_create(&http->tid, NULL, http_thread, html)) {
+ if (pthread_create(&http->tid, NULL, http_thread, io)) {
abc_http_close(http);
- html->io.priv = NULL;
+ io->priv = NULL;
return -1;
}
return 0;
}
-static void __http_close(abc_html_t* html)
+static void __http_close(abc_io_t* io)
{
- if (html)
- abc_http_close(html->io.priv);
+ if (io)
+ abc_http_close(io->priv);
}
-static int __http_popc(abc_html_t* html)
+static int __http_popc(abc_io_t* io)
{
abc_http_t* http;
- if (html) {
- http = html->io.priv;
+ if (io) {
+ http = io->priv;
if (http) {
int c;
--- /dev/null
+#include"abc_io.h"
+
+typedef struct {
+ scf_string_t* text;
+ int text_i;
+} abc_str_t;
+
+static int __str_open(abc_io_t* io, const char* path)
+{
+ if (!io || !path)
+ return -EINVAL;
+
+ abc_str_t* s = calloc(1, sizeof(abc_str_t));
+ if (!s)
+ return -ENOMEM;
+
+ s->text = scf_string_cstr(path);
+ if (!s->text) {
+ free(s);
+ return -ENOMEM;
+ }
+
+ io->priv = s;
+ io->download = 1;
+ return 0;
+}
+
+static void __str_close(abc_io_t* io)
+{
+ abc_str_t* s;
+
+ if (io && io->priv) {
+ s = io->priv;
+
+ if (s->text)
+ scf_string_free(s->text);
+
+ free(s);
+ io->priv = NULL;
+ }
+}
+
+static int __str_popc(abc_io_t* io)
+{
+ abc_str_t* s;
+
+ if (io && io->priv) {
+ s = io->priv;
+
+ if (s->text_i < s->text->len)
+ return s->text->data[s->text_i++];
+ }
+
+ return EOF;
+}
+
+abc_io_t abc_io_str =
+{
+ .proto = "str://",
+
+ .open = __str_open,
+ .close = __str_close,
+
+ .popc = __str_popc,
+};
--- /dev/null
+#include"abc_io.h"
+
+extern abc_io_t abc_io_file;
+extern abc_io_t abc_io_http;
+extern abc_io_t abc_io_str;
+
+abc_io_t* abc_io_array[ABC_PROTO_NB] =
+{
+ [ABC_PROTO_FILE] = &abc_io_file,
+ [ABC_PROTO_HTTP] = &abc_io_http,
+ [ABC_PROTO_STR] = &abc_io_str,
+};
+
+abc_char_t* __io_pop_char(abc_io_t* io)
+{
+ assert(io);
+
+ abc_char_t* c;
+
+ if (io->tmp_list) {
+ c = io->tmp_list;
+ io->tmp_list = c->next;
+ return c;
+ }
+
+ c = malloc(sizeof(abc_char_t));
+ if (!c)
+ return NULL;
+
+ int ret = io->popc(io);
+ if (EOF == ret) {
+ c->c = ret;
+ return c;
+ }
+
+ if (ret < 0x80) {
+ c->c = ret;
+ c->len = 1;
+ c->utf8[0] = ret;
+ return c;
+ }
+
+ if (0x6 == (ret >> 5)) {
+ c->c = ret & 0x1f;
+ c->len = 2;
+
+ } else if (0xe == (ret >> 4)) {
+ c->c = ret & 0xf;
+ c->len = 3;
+
+ } else if (0x1e == (ret >> 3)) {
+ c->c = ret & 0x7;
+ c->len = 4;
+
+ } else if (0x3e == (ret >> 2)) {
+ c->c = ret & 0x3;
+ c->len = 5;
+
+ } else if (0x7e == (ret >> 1)) {
+ c->c = ret & 0x1;
+ c->len = 6;
+ } else {
+ scf_loge("utf8 first byte wrong %#x\n", ret);
+ free(c);
+ return NULL;
+ }
+
+ c->utf8[0] = ret;
+
+ int i;
+ for (i = 1; i < c->len; i++) {
+
+ ret = io->popc(io);
+
+ if (0x2 == (ret >> 6)) {
+ c->c <<= 6;
+ c->c |= ret & 0x3f;
+
+ c->utf8[i] = ret;
+ } else {
+ scf_loge("utf8 byte[%d] wrong %#x\n", i + 1, ret);
+ free(c);
+ return NULL;
+ }
+ }
+
+ return c;
+}
+
+void __io_push_char(abc_io_t* io, abc_char_t* c)
+{
+ assert(io);
+ assert(c);
+
+ c->next = io->tmp_list;
+ io->tmp_list = c;
+}
#include"scf_string.h"
#include"scf_list.h"
#include"abc_ffmpeg.h"
+#include"abc_io.h"
typedef struct abc_obj_s abc_obj_t;
ABC_HTML_SCRIPT,
+ ABC_HTML_STYLE,
+
ABC_HTML_NB, // total HTML objects
ABC_HTML_ATTR_ID,
ABC_HTML_ATTR_FONT_SIZE,
ABC_HTML_ATTR_FONT_COLOR,
+ ABC_HTML_ATTR_TEXT_ALIGN,
+
ABC_HTML_ATTR_WIDTH,
ABC_HTML_ATTR_HEIGHT,
scf_string_t* value;
scf_string_t* text;
+ int text_line;
+ int text_pos;
+ abc_io_t io;
+
scf_string_t* file; // file name
int line; // line
int pos; // position
return -1;
}
- while (!html->download)
+ while (!html->io.download)
usleep(50 * 1000);
if (abc_html_parse(html) < 0) {
while (*pp)
pp = &(*pp)->next;
- *pp = html->tmp_list_js;
+ *pp = html->io.tmp_list_js;
- html->tmp_list_js = h;
+ html->io.tmp_list_js = h;
return 0;
error:
CFILES += abc_render_audio.c
CFILES += ../html/abc_html.c
-CFILES += ../html/abc_html_util.c
CFILES += ../html/abc_obj.c
+CFILES += ../html/abc_io_util.c
CFILES += ../html/abc_io_file.c
CFILES += ../html/abc_io_http.c
+CFILES += ../html/abc_io_str.c
CFILES += ../ffmpeg/abc_ffmpeg_img.c
CFILES += ../ffmpeg/abc_ffmpeg_input.c
GdkWindow* window;
GdkCursor* cursor;
- if (!ctx->current->download)
+ if (!ctx->current->io.download)
return 0;
if (!ctx->current->root)
abc_obj_t* obj;
if (ctx->current) {
- if (!ctx->current->download)
+ if (!ctx->current->io.download)
return TRUE;
if (!ctx->current->root) {
return ret;
}
- while (!html->download)
+ while (!html->io.download)
usleep(50 * 1000);
ret = abc_html_parse(html);