[buffer] Implement buffer deserialization for format=json
Using a ragel machine.
diff --git a/src/Makefile.am b/src/Makefile.am
index f666d5e..269fabe 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -258,12 +258,14 @@
.PHONY: unicode-tables arabic-table indic-table
BUILT_SOURCES += \
+ hb-buffer-deserialize-json.hh \
hb-buffer-deserialize-text.hh \
hb-ot-shape-complex-indic-machine.hh \
hb-ot-shape-complex-myanmar-machine.hh \
hb-ot-shape-complex-sea-machine.hh \
$(NULL)
EXTRA_DIST += \
+ hb-buffer-deserialize-json.rl \
hb-buffer-deserialize-text.rl \
hb-ot-shape-complex-indic-machine.rl \
hb-ot-shape-complex-myanmar-machine.rl \
diff --git a/src/hb-buffer-deserialize-json.rl b/src/hb-buffer-deserialize-json.rl
new file mode 100644
index 0000000..d93765a
--- /dev/null
+++ b/src/hb-buffer-deserialize-json.rl
@@ -0,0 +1,129 @@
+/*
+ * Copyright © 2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_BUFFER_DESERIALIZE_JSON_HH
+#define HB_BUFFER_DESERIALIZE_JSON_HH
+
+#include "hb-private.hh"
+
+%%{
+
+machine deserialize_json;
+alphtype unsigned char;
+write data;
+
+action clear_item {
+ memset (&info, 0, sizeof (info));
+ memset (&pos , 0, sizeof (pos ));
+}
+
+action add_item {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+
+action tok {
+ tok = p;
+}
+
+action parse_glyph {
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+}
+
+action parse_gid { if (!parse_uint (tok, p, &info.codepoint)) return false; }
+action parse_cluster { if (!parse_uint (tok, p, &info.cluster )) return false; }
+action parse_x_offset { if (!parse_int (tok, p, &pos.x_offset )) return false; }
+action parse_y_offset { if (!parse_int (tok, p, &pos.y_offset )) return false; }
+action parse_x_advance { if (!parse_int (tok, p, &pos.x_advance)) return false; }
+action parse_y_advance { if (!parse_int (tok, p, &pos.y_advance)) return false; }
+
+unum = '0' | [1-9] digit*;
+num = '-'? unum;
+
+comma = space* ',' space*;
+colon = space* ':' space*;
+
+glyph_name = '"' (alnum+ >tok %parse_glyph) '"';
+glyph_number = (unum >tok %parse_gid);
+
+glyph = "\"g\"" colon (glyph_name | glyph_number);
+cluster = "\"cl\"" colon (unum >tok %parse_cluster);
+xoffset = "\"dx\"" colon (num >tok %parse_x_offset);
+yoffset = "\"dy\"" colon (num >tok %parse_y_offset);
+xadvance= "\"ax\"" colon (num >tok %parse_x_advance);
+yadvance= "\"ay\"" colon (num >tok %parse_y_advance);
+
+element = glyph | cluster | xoffset | yoffset | xadvance | yadvance;
+item =
+ ( '{' space* element (comma element)* space* '}')
+ >clear_item
+ @add_item
+ ;
+
+main := space* item (comma item)* space* (','|']')?;
+
+}%%
+
+static hb_bool_t
+_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer,
+ const char *buf,
+ unsigned int buf_len,
+ const char **end_ptr,
+ hb_font_t *font)
+{
+ const char *p = buf, *pe = buf + buf_len;
+
+ /* Ensure we have positions. */
+ (void) hb_buffer_get_glyph_positions (buffer, NULL);
+
+ while (p < pe && ISSPACE (*p))
+ p++;
+ if (p < pe && *p == (buffer->len ? ',' : '['))
+ {
+ *end_ptr = ++p;
+ }
+
+ const char *tok = NULL;
+ int cs;
+ hb_glyph_info_t info;
+ hb_glyph_position_t pos;
+ %%{
+ write init;
+ write exec;
+ }%%
+
+ *end_ptr = p;
+
+ return p == pe && *(p-1) != ']';
+}
+
+#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */
diff --git a/src/hb-buffer-deserialize-text.rl b/src/hb-buffer-deserialize-text.rl
index 7c370e7..5272690 100644
--- a/src/hb-buffer-deserialize-text.rl
+++ b/src/hb-buffer-deserialize-text.rl
@@ -30,54 +30,10 @@
#include "hb-private.hh"
%%{
- machine deserialize_text;
- alphtype unsigned char;
- write data;
-}%%
-static hb_bool_t
-parse_uint (const char *pp, const char *end, uint32_t *pv)
-{
- char buf[32];
- unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
- strncpy (buf, pp, len);
- buf[len] = '\0';
-
- char *p = buf;
- char *pend = p;
- uint32_t v;
-
- errno = 0;
- v = strtol (p, &pend, 10);
- if (errno || p == pend || pend - p != end - pp)
- return false;
-
- *pv = v;
- return true;
-}
-
-static hb_bool_t
-parse_int (const char *pp, const char *end, int32_t *pv)
-{
- char buf[32];
- unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
- strncpy (buf, pp, len);
- buf[len] = '\0';
-
- char *p = buf;
- char *pend = p;
- int32_t v;
-
- errno = 0;
- v = strtol (p, &pend, 10);
- if (errno || p == pend || pend - p != end - pp)
- return false;
-
- *pv = v;
- return true;
-}
-
-%%{
+machine deserialize_text;
+alphtype unsigned char;
+write data;
action clear_item {
memset (&info, 0, sizeof (info));
@@ -143,10 +99,8 @@
/* Ensure we have positions. */
(void) hb_buffer_get_glyph_positions (buffer, NULL);
-#define ISSPACE(c) ((c)==' '||(c)=='\f'||(c)=='\n'||(c)=='\r'||(c)=='\t'||(c)=='\v')
while (p < pe && ISSPACE (*p))
p++;
-#undef ISSPACE
if (p < pe && *p == (buffer->len ? '|' : '['))
{
*end_ptr = ++p;
diff --git a/src/hb-buffer-serialize.cc b/src/hb-buffer-serialize.cc
index 0271547..dc47ba7 100644
--- a/src/hb-buffer-serialize.cc
+++ b/src/hb-buffer-serialize.cc
@@ -242,15 +242,48 @@
static hb_bool_t
-_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer,
- const char *buf,
- unsigned int buf_len,
- const char **end_ptr,
- hb_font_t *font)
+parse_uint (const char *pp, const char *end, uint32_t *pv)
{
- return false;
+ char buf[32];
+ unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
+ strncpy (buf, pp, len);
+ buf[len] = '\0';
+
+ char *p = buf;
+ char *pend = p;
+ uint32_t v;
+
+ errno = 0;
+ v = strtol (p, &pend, 10);
+ if (errno || p == pend || pend - p != end - pp)
+ return false;
+
+ *pv = v;
+ return true;
}
+static hb_bool_t
+parse_int (const char *pp, const char *end, int32_t *pv)
+{
+ char buf[32];
+ unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
+ strncpy (buf, pp, len);
+ buf[len] = '\0';
+
+ char *p = buf;
+ char *pend = p;
+ int32_t v;
+
+ errno = 0;
+ v = strtol (p, &pend, 10);
+ if (errno || p == pend || pend - p != end - pp)
+ return false;
+
+ *pv = v;
+ return true;
+}
+
+#include "hb-buffer-deserialize-json.hh"
#include "hb-buffer-deserialize-text.hh"
hb_bool_t
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 91bce9b..0f652ad 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -516,10 +516,12 @@
/* ASCII tag/character handling */
-static inline unsigned char ISALPHA (unsigned char c)
+static inline bool ISALPHA (unsigned char c)
{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
-static inline unsigned char ISALNUM (unsigned char c)
+static inline bool ISALNUM (unsigned char c)
{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
+static inline bool ISSPACE (unsigned char c)
+{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
static inline unsigned char TOUPPER (unsigned char c)
{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
static inline unsigned char TOLOWER (unsigned char c)
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index e38f59f..67ef7e6 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -38,10 +38,8 @@
parse_space (const char **pp, const char *end)
{
char c;
-#define ISSPACE(c) ((c)==' '||(c)=='\f'||(c)=='\n'||(c)=='\r'||(c)=='\t'||(c)=='\v')
while (*pp < end && (c = **pp, ISSPACE (c)))
(*pp)++;
-#undef ISSPACE
}
static hb_bool_t
diff --git a/src/test-buffer-serialize.cc b/src/test-buffer-serialize.cc
index 71bb431..3577dbf 100644
--- a/src/test-buffer-serialize.cc
+++ b/src/test-buffer-serialize.cc
@@ -106,14 +106,14 @@
while (hb_buffer_deserialize_glyphs (buf,
p, -1, &p,
font,
- HB_BUFFER_SERIALIZE_FORMAT_TEXT))
+ HB_BUFFER_SERIALIZE_FORMAT_JSON))
;
if (*p && *p != '\n')
ret = false;
hb_buffer_serialize_glyphs (buf, 0, hb_buffer_get_length (buf),
out, sizeof (out), NULL,
- font, HB_BUFFER_SERIALIZE_FORMAT_TEXT,
+ font, HB_BUFFER_SERIALIZE_FORMAT_JSON,
HB_BUFFER_SERIALIZE_FLAGS_DEFAULT);
puts (out);
}