[buffer] Implement buffer deserialization for format=json
authorBehdad Esfahbod <behdad@behdad.org>
Wed, 27 Feb 2013 23:39:37 +0000 (18:39 -0500)
committerBehdad Esfahbod <behdad@behdad.org>
Wed, 27 Feb 2013 23:49:18 +0000 (18:49 -0500)
Using a ragel machine.

src/Makefile.am
src/hb-buffer-deserialize-json.rl [new file with mode: 0644]
src/hb-buffer-deserialize-text.rl
src/hb-buffer-serialize.cc
src/hb-private.hh
src/hb-shape.cc
src/test-buffer-serialize.cc

index f666d5e..269fabe 100644 (file)
@@ -258,12 +258,14 @@ arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt
 .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 (file)
index 0000000..d93765a
--- /dev/null
@@ -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 */
index 7c370e7..5272690 100644 (file)
 #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 @@ _hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
   /* 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;
index 0271547..dc47ba7 100644 (file)
@@ -242,15 +242,48 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
 
 
 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
index 91bce9b..0f652ad 100644 (file)
@@ -516,10 +516,12 @@ static inline uint32_t hb_uint32_swap (const uint32_t v)
 
 /* 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)
index e38f59f..67ef7e6 100644 (file)
@@ -38,10 +38,8 @@ static void
 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
index 71bb431..3577dbf 100644 (file)
@@ -106,14 +106,14 @@ main (int argc, char **argv)
     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);
   }