plist_lite 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/ext/plist_lite/ext/ext.c +233 -0
 - data/ext/plist_lite/ext/extconf.rb +4 -0
 - data/lib/minimal.plist +1 -0
 - data/lib/plist.dtd +19 -0
 - data/lib/plist_lite.rb +100 -0
 - data/lib/plist_lite/ext.bundle +0 -0
 - metadata +120 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 81c314a0ff465217564b4040a14bfc7a8913e26d9be6b365c489f4117f07fd76
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 0ae9856ea9b8b13c691a4459ea907140d32d99cafedc6b726c570649a4ea77f3
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: c12c104cfd7c1daf21fc7813e7dacc6498ec14efce8e3950dafae565050ee6b6fa9488638a4fe9e254cdcfb4388776005ab22c6c3495ad8cc4e1f155212c3bc6
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 49ef1de68941d7683ec69843dc9a607ca97b85de8f9b2a7fbf299ffd66d2f965ce445593405c492ef54f3a2d7ed080888ac8eb8d6a6d7522702607a4b06400e8
         
     | 
| 
         @@ -0,0 +1,233 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include "ruby.h"
         
     | 
| 
      
 2 
     | 
    
         
            +
            #include "ruby/encoding.h"
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include <stdint.h>
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include <stdlib.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            typedef struct
         
     | 
| 
      
 7 
     | 
    
         
            +
            {
         
     | 
| 
      
 8 
     | 
    
         
            +
              char *head;
         
     | 
| 
      
 9 
     | 
    
         
            +
              size_t size;
         
     | 
| 
      
 10 
     | 
    
         
            +
              size_t length;
         
     | 
| 
      
 11 
     | 
    
         
            +
            } string;
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            string *string_new(size_t size)
         
     | 
| 
      
 14 
     | 
    
         
            +
            {
         
     | 
| 
      
 15 
     | 
    
         
            +
              string *ptr = malloc(sizeof(string));
         
     | 
| 
      
 16 
     | 
    
         
            +
              ptr->size = size;
         
     | 
| 
      
 17 
     | 
    
         
            +
              ptr->head = malloc(size);
         
     | 
| 
      
 18 
     | 
    
         
            +
              ptr->head[0] = '\0';
         
     | 
| 
      
 19 
     | 
    
         
            +
              ptr->length = 0;
         
     | 
| 
      
 20 
     | 
    
         
            +
              return ptr;
         
     | 
| 
      
 21 
     | 
    
         
            +
            }
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            void string_concat(string *recv, char *src)
         
     | 
| 
      
 24 
     | 
    
         
            +
            {
         
     | 
| 
      
 25 
     | 
    
         
            +
              size_t len_src = strlen(src);
         
     | 
| 
      
 26 
     | 
    
         
            +
              size_t new_size = recv->size;
         
     | 
| 
      
 27 
     | 
    
         
            +
              while ((recv->length + len_src + 1) > new_size)
         
     | 
| 
      
 28 
     | 
    
         
            +
                new_size <<= 1;
         
     | 
| 
      
 29 
     | 
    
         
            +
              if (new_size > recv->size)
         
     | 
| 
      
 30 
     | 
    
         
            +
                recv->head = realloc(recv->head, new_size);
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              char *ptr = recv->head + recv->length;
         
     | 
| 
      
 33 
     | 
    
         
            +
              while ((*ptr++ = *src++))
         
     | 
| 
      
 34 
     | 
    
         
            +
                ;
         
     | 
| 
      
 35 
     | 
    
         
            +
              recv->length += len_src;
         
     | 
| 
      
 36 
     | 
    
         
            +
            }
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            void string_free(string *recv)
         
     | 
| 
      
 39 
     | 
    
         
            +
            {
         
     | 
| 
      
 40 
     | 
    
         
            +
              free(recv->head);
         
     | 
| 
      
 41 
     | 
    
         
            +
              free(recv);
         
     | 
| 
      
 42 
     | 
    
         
            +
            }
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            void time_to_plist_date(VALUE time, string *output)
         
     | 
| 
      
 45 
     | 
    
         
            +
            {
         
     | 
| 
      
 46 
     | 
    
         
            +
              rb_funcall(time, rb_intern("utc"), 0);
         
     | 
| 
      
 47 
     | 
    
         
            +
              VALUE str = rb_funcall(time, rb_intern("iso8601"), 0);
         
     | 
| 
      
 48 
     | 
    
         
            +
              string_concat(output, (char *)"<date>");
         
     | 
| 
      
 49 
     | 
    
         
            +
              string_concat(output, StringValueCStr(str));
         
     | 
| 
      
 50 
     | 
    
         
            +
              string_concat(output, (char *)"</date>");
         
     | 
| 
      
 51 
     | 
    
         
            +
            }
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            void dump_node(VALUE obj, string *output);
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            VALUE to_utf8_xml_text(VALUE obj)
         
     | 
| 
      
 56 
     | 
    
         
            +
            {
         
     | 
| 
      
 57 
     | 
    
         
            +
              int idx = rb_enc_get_index(obj);
         
     | 
| 
      
 58 
     | 
    
         
            +
              if (idx < 0)
         
     | 
| 
      
 59 
     | 
    
         
            +
                rb_raise(rb_eTypeError, "unknown encoding");
         
     | 
| 
      
 60 
     | 
    
         
            +
              if (idx == rb_utf8_encindex())
         
     | 
| 
      
 61 
     | 
    
         
            +
              {
         
     | 
| 
      
 62 
     | 
    
         
            +
                VALUE options = rb_hash_new();
         
     | 
| 
      
 63 
     | 
    
         
            +
                rb_hash_aset(options, ID2SYM(rb_intern("xml")), ID2SYM(rb_intern("text")));
         
     | 
| 
      
 64 
     | 
    
         
            +
                return rb_funcallv_kw(obj, rb_intern("encode"), 1, &options, RB_PASS_KEYWORDS);
         
     | 
| 
      
 65 
     | 
    
         
            +
              }
         
     | 
| 
      
 66 
     | 
    
         
            +
              else
         
     | 
| 
      
 67 
     | 
    
         
            +
              {
         
     | 
| 
      
 68 
     | 
    
         
            +
                VALUE options = rb_hash_new();
         
     | 
| 
      
 69 
     | 
    
         
            +
                rb_hash_aset(options, ID2SYM(rb_intern("xml")), ID2SYM(rb_intern("text")));
         
     | 
| 
      
 70 
     | 
    
         
            +
                VALUE args[] = {rb_enc_from_encoding(rb_utf8_encoding()), options};
         
     | 
| 
      
 71 
     | 
    
         
            +
                return rb_funcallv_kw(obj, rb_intern("encode"), 2, args, RB_PASS_KEYWORDS);
         
     | 
| 
      
 72 
     | 
    
         
            +
              }
         
     | 
| 
      
 73 
     | 
    
         
            +
            }
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            VALUE array_each_block(VALUE obj, string *output)
         
     | 
| 
      
 76 
     | 
    
         
            +
            {
         
     | 
| 
      
 77 
     | 
    
         
            +
              dump_node(obj, output);
         
     | 
| 
      
 78 
     | 
    
         
            +
              return Qnil;
         
     | 
| 
      
 79 
     | 
    
         
            +
            }
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            VALUE hash_each_block(VALUE pair, string *output)
         
     | 
| 
      
 82 
     | 
    
         
            +
            {
         
     | 
| 
      
 83 
     | 
    
         
            +
              VALUE value = rb_ary_pop(pair);
         
     | 
| 
      
 84 
     | 
    
         
            +
              VALUE key = rb_ary_pop(pair);
         
     | 
| 
      
 85 
     | 
    
         
            +
              string_concat(output, (char *)"<key>");
         
     | 
| 
      
 86 
     | 
    
         
            +
              switch (TYPE(key))
         
     | 
| 
      
 87 
     | 
    
         
            +
              {
         
     | 
| 
      
 88 
     | 
    
         
            +
              case T_STRING:
         
     | 
| 
      
 89 
     | 
    
         
            +
              {
         
     | 
| 
      
 90 
     | 
    
         
            +
                VALUE encoded = to_utf8_xml_text(key);
         
     | 
| 
      
 91 
     | 
    
         
            +
                string_concat(output, StringValueCStr(encoded));
         
     | 
| 
      
 92 
     | 
    
         
            +
                break;
         
     | 
| 
      
 93 
     | 
    
         
            +
              }
         
     | 
| 
      
 94 
     | 
    
         
            +
              case T_SYMBOL:
         
     | 
| 
      
 95 
     | 
    
         
            +
              {
         
     | 
| 
      
 96 
     | 
    
         
            +
                VALUE str = rb_funcall(key, rb_intern("to_s"), 0);
         
     | 
| 
      
 97 
     | 
    
         
            +
                string_concat(output, StringValueCStr(str));
         
     | 
| 
      
 98 
     | 
    
         
            +
                break;
         
     | 
| 
      
 99 
     | 
    
         
            +
              }
         
     | 
| 
      
 100 
     | 
    
         
            +
              default:
         
     | 
| 
      
 101 
     | 
    
         
            +
              {
         
     | 
| 
      
 102 
     | 
    
         
            +
                VALUE encoded = to_utf8_xml_text(rb_funcall(key, rb_intern("to_s"), 0));
         
     | 
| 
      
 103 
     | 
    
         
            +
                string_concat(output, StringValueCStr(encoded));
         
     | 
| 
      
 104 
     | 
    
         
            +
                break;
         
     | 
| 
      
 105 
     | 
    
         
            +
              }
         
     | 
| 
      
 106 
     | 
    
         
            +
              }
         
     | 
| 
      
 107 
     | 
    
         
            +
              string_concat(output, (char *)"</key>");
         
     | 
| 
      
 108 
     | 
    
         
            +
              dump_node(value, output);
         
     | 
| 
      
 109 
     | 
    
         
            +
              return Qnil;
         
     | 
| 
      
 110 
     | 
    
         
            +
            }
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
            void dump_node(VALUE obj, string *output)
         
     | 
| 
      
 113 
     | 
    
         
            +
            {
         
     | 
| 
      
 114 
     | 
    
         
            +
              switch (TYPE(obj))
         
     | 
| 
      
 115 
     | 
    
         
            +
              {
         
     | 
| 
      
 116 
     | 
    
         
            +
              case T_ARRAY:
         
     | 
| 
      
 117 
     | 
    
         
            +
                string_concat(output, (char *)"<array>");
         
     | 
| 
      
 118 
     | 
    
         
            +
                rb_block_call(obj, rb_intern("each"), 0, NULL, (rb_block_call_func_t)array_each_block, (VALUE)output);
         
     | 
| 
      
 119 
     | 
    
         
            +
                string_concat(output, (char *)"</array>");
         
     | 
| 
      
 120 
     | 
    
         
            +
                break;
         
     | 
| 
      
 121 
     | 
    
         
            +
              case T_HASH:
         
     | 
| 
      
 122 
     | 
    
         
            +
                string_concat(output, (char *)"<dict>");
         
     | 
| 
      
 123 
     | 
    
         
            +
                rb_block_call(obj, rb_intern("each"), 0, NULL, (rb_block_call_func_t)hash_each_block, (VALUE)output);
         
     | 
| 
      
 124 
     | 
    
         
            +
                string_concat(output, (char *)"</dict>");
         
     | 
| 
      
 125 
     | 
    
         
            +
                break;
         
     | 
| 
      
 126 
     | 
    
         
            +
              case T_TRUE:
         
     | 
| 
      
 127 
     | 
    
         
            +
                string_concat(output, (char *)"<true/>");
         
     | 
| 
      
 128 
     | 
    
         
            +
                break;
         
     | 
| 
      
 129 
     | 
    
         
            +
              case T_FALSE:
         
     | 
| 
      
 130 
     | 
    
         
            +
              {
         
     | 
| 
      
 131 
     | 
    
         
            +
                string_concat(output, (char *)"<false/>");
         
     | 
| 
      
 132 
     | 
    
         
            +
                break;
         
     | 
| 
      
 133 
     | 
    
         
            +
              }
         
     | 
| 
      
 134 
     | 
    
         
            +
              case T_BIGNUM:
         
     | 
| 
      
 135 
     | 
    
         
            +
              case T_FIXNUM:
         
     | 
| 
      
 136 
     | 
    
         
            +
              {
         
     | 
| 
      
 137 
     | 
    
         
            +
                VALUE str = rb_funcall(obj, rb_intern("to_s"), 0);
         
     | 
| 
      
 138 
     | 
    
         
            +
                string_concat(output, (char *)"<integer>");
         
     | 
| 
      
 139 
     | 
    
         
            +
                string_concat(output, StringValueCStr(str));
         
     | 
| 
      
 140 
     | 
    
         
            +
                string_concat(output, (char *)"</integer>");
         
     | 
| 
      
 141 
     | 
    
         
            +
                break;
         
     | 
| 
      
 142 
     | 
    
         
            +
              }
         
     | 
| 
      
 143 
     | 
    
         
            +
              case T_FLOAT:
         
     | 
| 
      
 144 
     | 
    
         
            +
              {
         
     | 
| 
      
 145 
     | 
    
         
            +
                VALUE str = rb_funcall(obj, rb_intern("to_s"), 0);
         
     | 
| 
      
 146 
     | 
    
         
            +
                string_concat(output, (char *)"<real>");
         
     | 
| 
      
 147 
     | 
    
         
            +
                string_concat(output, StringValueCStr(str));
         
     | 
| 
      
 148 
     | 
    
         
            +
                string_concat(output, (char *)"</real>");
         
     | 
| 
      
 149 
     | 
    
         
            +
                break;
         
     | 
| 
      
 150 
     | 
    
         
            +
              }
         
     | 
| 
      
 151 
     | 
    
         
            +
              case T_STRING:
         
     | 
| 
      
 152 
     | 
    
         
            +
              {
         
     | 
| 
      
 153 
     | 
    
         
            +
                int idx = rb_enc_get_index(obj);
         
     | 
| 
      
 154 
     | 
    
         
            +
                if (idx == rb_ascii8bit_encindex())
         
     | 
| 
      
 155 
     | 
    
         
            +
                {
         
     | 
| 
      
 156 
     | 
    
         
            +
                  string_concat(output, (char *)"<data>");
         
     | 
| 
      
 157 
     | 
    
         
            +
                  VALUE data = rb_funcall(
         
     | 
| 
      
 158 
     | 
    
         
            +
                      rb_ary_new_from_values(1, &obj),
         
     | 
| 
      
 159 
     | 
    
         
            +
                      rb_intern("pack"),
         
     | 
| 
      
 160 
     | 
    
         
            +
                      1,
         
     | 
| 
      
 161 
     | 
    
         
            +
                      rb_str_new_literal("m"));
         
     | 
| 
      
 162 
     | 
    
         
            +
                  string_concat(output, StringValueCStr(data));
         
     | 
| 
      
 163 
     | 
    
         
            +
                  string_concat(output, (char *)"</data>");
         
     | 
| 
      
 164 
     | 
    
         
            +
                }
         
     | 
| 
      
 165 
     | 
    
         
            +
                else
         
     | 
| 
      
 166 
     | 
    
         
            +
                {
         
     | 
| 
      
 167 
     | 
    
         
            +
                  string_concat(output, (char *)"<string>");
         
     | 
| 
      
 168 
     | 
    
         
            +
                  VALUE encoded = to_utf8_xml_text(obj);
         
     | 
| 
      
 169 
     | 
    
         
            +
                  string_concat(output, StringValueCStr(encoded));
         
     | 
| 
      
 170 
     | 
    
         
            +
                  string_concat(output, (char *)"</string>");
         
     | 
| 
      
 171 
     | 
    
         
            +
                }
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                break;
         
     | 
| 
      
 174 
     | 
    
         
            +
              }
         
     | 
| 
      
 175 
     | 
    
         
            +
              case T_SYMBOL:
         
     | 
| 
      
 176 
     | 
    
         
            +
              {
         
     | 
| 
      
 177 
     | 
    
         
            +
                VALUE str = rb_funcall(obj, rb_intern("to_s"), 0);
         
     | 
| 
      
 178 
     | 
    
         
            +
                string_concat(output, (char *)"<string>");
         
     | 
| 
      
 179 
     | 
    
         
            +
                string_concat(output, StringValueCStr(str));
         
     | 
| 
      
 180 
     | 
    
         
            +
                string_concat(output, (char *)"</string>");
         
     | 
| 
      
 181 
     | 
    
         
            +
                break;
         
     | 
| 
      
 182 
     | 
    
         
            +
              }
         
     | 
| 
      
 183 
     | 
    
         
            +
              default:
         
     | 
| 
      
 184 
     | 
    
         
            +
              {
         
     | 
| 
      
 185 
     | 
    
         
            +
                if (rb_obj_is_kind_of(obj, rb_cTime) == Qtrue)
         
     | 
| 
      
 186 
     | 
    
         
            +
                {
         
     | 
| 
      
 187 
     | 
    
         
            +
                  VALUE time = rb_funcall(rb_cTime, rb_intern("at"), 1, obj);
         
     | 
| 
      
 188 
     | 
    
         
            +
                  time_to_plist_date(time, output);
         
     | 
| 
      
 189 
     | 
    
         
            +
                }
         
     | 
| 
      
 190 
     | 
    
         
            +
                else if (rb_obj_is_kind_of(obj, rb_const_get(rb_cObject, rb_intern("DateTime"))) == Qtrue)
         
     | 
| 
      
 191 
     | 
    
         
            +
                {
         
     | 
| 
      
 192 
     | 
    
         
            +
                  VALUE time = rb_funcall(obj, rb_intern("to_time"), 0);
         
     | 
| 
      
 193 
     | 
    
         
            +
                  time_to_plist_date(time, output);
         
     | 
| 
      
 194 
     | 
    
         
            +
                }
         
     | 
| 
      
 195 
     | 
    
         
            +
                else if (rb_obj_is_kind_of(obj, rb_const_get(rb_cObject, rb_intern("Date"))) == Qtrue)
         
     | 
| 
      
 196 
     | 
    
         
            +
                {
         
     | 
| 
      
 197 
     | 
    
         
            +
                  rb_warn("Consider not using Date object because it does not contain time zone information");
         
     | 
| 
      
 198 
     | 
    
         
            +
                  VALUE str = rb_funcall(obj, rb_intern("iso8601"), 0);
         
     | 
| 
      
 199 
     | 
    
         
            +
                  string_concat(output, (char *)"<date>");
         
     | 
| 
      
 200 
     | 
    
         
            +
                  string_concat(output, StringValueCStr(str));
         
     | 
| 
      
 201 
     | 
    
         
            +
                  string_concat(output, (char *)"T00:00:00Z</date>");
         
     | 
| 
      
 202 
     | 
    
         
            +
                }
         
     | 
| 
      
 203 
     | 
    
         
            +
                else
         
     | 
| 
      
 204 
     | 
    
         
            +
                {
         
     | 
| 
      
 205 
     | 
    
         
            +
                  VALUE msg = rb_funcall(rb_obj_class(obj), rb_intern("to_s"), 0);
         
     | 
| 
      
 206 
     | 
    
         
            +
                  rb_raise(rb_eArgError, "Unsupported type: %s", StringValueCStr(msg));
         
     | 
| 
      
 207 
     | 
    
         
            +
                }
         
     | 
| 
      
 208 
     | 
    
         
            +
                break;
         
     | 
| 
      
 209 
     | 
    
         
            +
              }
         
     | 
| 
      
 210 
     | 
    
         
            +
              }
         
     | 
| 
      
 211 
     | 
    
         
            +
            }
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
            VALUE dump(VALUE recv, VALUE obj)
         
     | 
| 
      
 214 
     | 
    
         
            +
            {
         
     | 
| 
      
 215 
     | 
    
         
            +
              string *output = string_new(2048);
         
     | 
| 
      
 216 
     | 
    
         
            +
              string_concat(
         
     | 
| 
      
 217 
     | 
    
         
            +
                  output,
         
     | 
| 
      
 218 
     | 
    
         
            +
                  (char *)"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
         
     | 
| 
      
 219 
     | 
    
         
            +
                          "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
         
     | 
| 
      
 220 
     | 
    
         
            +
                          "<plist version=\"1.0\">");
         
     | 
| 
      
 221 
     | 
    
         
            +
              dump_node(obj, output);
         
     | 
| 
      
 222 
     | 
    
         
            +
              string_concat(output, (char *)"</plist>");
         
     | 
| 
      
 223 
     | 
    
         
            +
              VALUE ret = rb_utf8_str_new(output->head, output->length);
         
     | 
| 
      
 224 
     | 
    
         
            +
              string_free(output);
         
     | 
| 
      
 225 
     | 
    
         
            +
              return ret;
         
     | 
| 
      
 226 
     | 
    
         
            +
            }
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
            void Init_ext(void)
         
     | 
| 
      
 229 
     | 
    
         
            +
            {
         
     | 
| 
      
 230 
     | 
    
         
            +
              rb_require("time");
         
     | 
| 
      
 231 
     | 
    
         
            +
              VALUE cPlistLite = rb_define_module("PlistLite");
         
     | 
| 
      
 232 
     | 
    
         
            +
              rb_define_singleton_method(cPlistLite, "dump", dump, 1);
         
     | 
| 
      
 233 
     | 
    
         
            +
            }
         
     | 
    
        data/lib/minimal.plist
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            <?xml version="1.0"?><!DOCTYPE plist SYSTEM "plist.dtd"><_/>
         
     | 
    
        data/lib/plist.dtd
    ADDED
    
    | 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            <!ENTITY % plistObject "(array | data | date | dict | real | integer | string | true | false )" >
         
     | 
| 
      
 2 
     | 
    
         
            +
            <!ELEMENT plist %plistObject;>
         
     | 
| 
      
 3 
     | 
    
         
            +
            <!ATTLIST plist version CDATA "1.0" >
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            <!-- Collections -->
         
     | 
| 
      
 6 
     | 
    
         
            +
            <!ELEMENT array (%plistObject;)*>
         
     | 
| 
      
 7 
     | 
    
         
            +
            <!ELEMENT dict (key, %plistObject;)*>
         
     | 
| 
      
 8 
     | 
    
         
            +
            <!ELEMENT key (#PCDATA)>
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            <!--- Primitive types -->
         
     | 
| 
      
 11 
     | 
    
         
            +
            <!ELEMENT string (#PCDATA)>
         
     | 
| 
      
 12 
     | 
    
         
            +
            <!ELEMENT data (#PCDATA)> <!-- Contents interpreted as Base-64 encoded -->
         
     | 
| 
      
 13 
     | 
    
         
            +
            <!ELEMENT date (#PCDATA)> <!-- Contents should conform to a subset of ISO 8601 (in particular, YYYY '-' MM '-' DD 'T' HH ':' MM ':' SS 'Z'.  Smaller units may be omitted with a loss of precision) -->
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            <!-- Numerical primitives -->
         
     | 
| 
      
 16 
     | 
    
         
            +
            <!ELEMENT true EMPTY>  <!-- Boolean constant true -->
         
     | 
| 
      
 17 
     | 
    
         
            +
            <!ELEMENT false EMPTY> <!-- Boolean constant false -->
         
     | 
| 
      
 18 
     | 
    
         
            +
            <!ELEMENT real (#PCDATA)> <!-- Contents should represent a floating point number matching ("+" | "-")? d+ ("."d*)? ("E" ("+" | "-") d+)? where d is a digit 0-9.  -->
         
     | 
| 
      
 19 
     | 
    
         
            +
            <!ELEMENT integer (#PCDATA)> <!-- Contents should represent a (possibly signed) integer number in base 10 -->
         
     | 
    
        data/lib/plist_lite.rb
    ADDED
    
    | 
         @@ -0,0 +1,100 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'nokogiri'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'time'
         
     | 
| 
      
 5 
     | 
    
         
            +
            module PlistLite
         
     | 
| 
      
 6 
     | 
    
         
            +
              DTD = Dir.chdir(__dir__) do
         
     | 
| 
      
 7 
     | 
    
         
            +
                Nokogiri::XML::Document.parse(
         
     | 
| 
      
 8 
     | 
    
         
            +
                  IO.read("#{__dir__}/minimal.plist"), nil, nil,
         
     | 
| 
      
 9 
     | 
    
         
            +
                  Nokogiri::XML::ParseOptions.new(Nokogiri::XML::ParseOptions::DTDLOAD)
         
     | 
| 
      
 10 
     | 
    
         
            +
                )
         
     | 
| 
      
 11 
     | 
    
         
            +
              end.external_subset
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 14 
     | 
    
         
            +
                def load(source)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  doc = Nokogiri::XML::Document.parse(
         
     | 
| 
      
 16 
     | 
    
         
            +
                    source, nil, nil,
         
     | 
| 
      
 17 
     | 
    
         
            +
                    Nokogiri::XML::ParseOptions.new(Nokogiri::XML::ParseOptions::STRICT)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  )
         
     | 
| 
      
 19 
     | 
    
         
            +
                  raise doc.errors.first unless doc.errors.empty?
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  errors = DTD.validate(doc)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  raise errors.first unless errors.empty?
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  load_node(doc.root.elements.first)
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                def dump(obj)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  output = +'<?xml version="1.0" encoding="UTF-8"?>' \
         
     | 
| 
      
 29 
     | 
    
         
            +
                  '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' \
         
     | 
| 
      
 30 
     | 
    
         
            +
                  '<plist version="1.0">'
         
     | 
| 
      
 31 
     | 
    
         
            +
                  dump_node(obj, output)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  output << '</plist>'
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                private
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def load_node(node)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  case node.name
         
     | 
| 
      
 39 
     | 
    
         
            +
                  when 'dict'
         
     | 
| 
      
 40 
     | 
    
         
            +
                    hash = {}
         
     | 
| 
      
 41 
     | 
    
         
            +
                    node.elements.each_slice(2) do |key_node, value_node|
         
     | 
| 
      
 42 
     | 
    
         
            +
                      hash[key_node.text] = load_node(value_node)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
                    hash
         
     | 
| 
      
 45 
     | 
    
         
            +
                  when 'array'
         
     | 
| 
      
 46 
     | 
    
         
            +
                    array = []
         
     | 
| 
      
 47 
     | 
    
         
            +
                    node.elements.each { |element| array << load_node(element) }
         
     | 
| 
      
 48 
     | 
    
         
            +
                    array
         
     | 
| 
      
 49 
     | 
    
         
            +
                  when 'integer' then node.text.to_i
         
     | 
| 
      
 50 
     | 
    
         
            +
                  when 'real' then node.text.to_f
         
     | 
| 
      
 51 
     | 
    
         
            +
                  when 'date' then Time.iso8601(node.text)
         
     | 
| 
      
 52 
     | 
    
         
            +
                  when 'string' then node.text
         
     | 
| 
      
 53 
     | 
    
         
            +
                  when 'data' then node.text.unpack1('m')
         
     | 
| 
      
 54 
     | 
    
         
            +
                  when 'true' then true
         
     | 
| 
      
 55 
     | 
    
         
            +
                  when 'false' then false
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                def dump_node(obj, output)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  case obj
         
     | 
| 
      
 61 
     | 
    
         
            +
                  when Hash
         
     | 
| 
      
 62 
     | 
    
         
            +
                    output << '<dict>'
         
     | 
| 
      
 63 
     | 
    
         
            +
                    obj.each do |key, value|
         
     | 
| 
      
 64 
     | 
    
         
            +
                      case key
         
     | 
| 
      
 65 
     | 
    
         
            +
                      when String then output << "<key>#{key.encode(xml: :text)}</key>"
         
     | 
| 
      
 66 
     | 
    
         
            +
                      when Symbol then output << "<key>#{key}</key>"
         
     | 
| 
      
 67 
     | 
    
         
            +
                      else
         
     | 
| 
      
 68 
     | 
    
         
            +
                        raise TypeError, 'Hash key should be String or Symbol'
         
     | 
| 
      
 69 
     | 
    
         
            +
                      end
         
     | 
| 
      
 70 
     | 
    
         
            +
                      dump_node(value, output)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    end
         
     | 
| 
      
 72 
     | 
    
         
            +
                    output << '</dict>'
         
     | 
| 
      
 73 
     | 
    
         
            +
                  when Array
         
     | 
| 
      
 74 
     | 
    
         
            +
                    output << '<array>'
         
     | 
| 
      
 75 
     | 
    
         
            +
                    obj.each { |i| dump_node(i, output) }
         
     | 
| 
      
 76 
     | 
    
         
            +
                    output << '</array>'
         
     | 
| 
      
 77 
     | 
    
         
            +
                  when Symbol then output << "<string>#{obj}</string>"
         
     | 
| 
      
 78 
     | 
    
         
            +
                  when String
         
     | 
| 
      
 79 
     | 
    
         
            +
                    output <<
         
     | 
| 
      
 80 
     | 
    
         
            +
                      case obj.encoding
         
     | 
| 
      
 81 
     | 
    
         
            +
                      when Encoding::ASCII_8BIT then "<data>#{[obj].pack('m')}</data>"
         
     | 
| 
      
 82 
     | 
    
         
            +
                      when Encoding::UTF_8 then "<string>#{obj.encode(xml: :text)}</string>"
         
     | 
| 
      
 83 
     | 
    
         
            +
                      else "<string>#{obj.encode(Encoding::UTF_8, xml: :text)}</string>"
         
     | 
| 
      
 84 
     | 
    
         
            +
                      end
         
     | 
| 
      
 85 
     | 
    
         
            +
                  when Integer then output << "<integer>#{obj}</integer>"
         
     | 
| 
      
 86 
     | 
    
         
            +
                  when Float then output << "<real>#{obj}</real>"
         
     | 
| 
      
 87 
     | 
    
         
            +
                  when true then output << '<true/>'
         
     | 
| 
      
 88 
     | 
    
         
            +
                  when false then output << '<false/>'
         
     | 
| 
      
 89 
     | 
    
         
            +
                  when Time then output << "<date>#{Time.at(obj).utc.iso8601}</date>"
         
     | 
| 
      
 90 
     | 
    
         
            +
                  when DateTime then output << "<date>#{obj.to_time.utc.iso8601}</date>"
         
     | 
| 
      
 91 
     | 
    
         
            +
                  when Date
         
     | 
| 
      
 92 
     | 
    
         
            +
                    warn 'Consider not using Date object because it does not contain time zone information'
         
     | 
| 
      
 93 
     | 
    
         
            +
                    output << "<date>#{obj.iso8601}T00:00:00Z</date>"
         
     | 
| 
      
 94 
     | 
    
         
            +
                  else raise ArgumentError, "unknown type: #{obj.class}"
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
      
 97 
     | 
    
         
            +
              end
         
     | 
| 
      
 98 
     | 
    
         
            +
            end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            require 'plist_lite/ext'
         
     | 
| 
         Binary file 
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,120 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: plist_lite
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.1.0
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Weihang Jian
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire:
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2021-06-27 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 13 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 14 
     | 
    
         
            +
              name: nokogiri
         
     | 
| 
      
 15 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 16 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 17 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 19 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
      
 20 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 21 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 22 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 23 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 24 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 25 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 26 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
      
 27 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 28 
     | 
    
         
            +
              name: bundler
         
     | 
| 
      
 29 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 30 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 31 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 32 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 33 
     | 
    
         
            +
                    version: '2.0'
         
     | 
| 
      
 34 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 35 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 36 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 37 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 38 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 39 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 40 
     | 
    
         
            +
                    version: '2.0'
         
     | 
| 
      
 41 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 42 
     | 
    
         
            +
              name: minitest
         
     | 
| 
      
 43 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 44 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 45 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 46 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 47 
     | 
    
         
            +
                    version: '5.0'
         
     | 
| 
      
 48 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 49 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 50 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 51 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 52 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 53 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 54 
     | 
    
         
            +
                    version: '5.0'
         
     | 
| 
      
 55 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 56 
     | 
    
         
            +
              name: rake
         
     | 
| 
      
 57 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 58 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 59 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 60 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 61 
     | 
    
         
            +
                    version: '13.0'
         
     | 
| 
      
 62 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 63 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 64 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 65 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 66 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 67 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 68 
     | 
    
         
            +
                    version: '13.0'
         
     | 
| 
      
 69 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 70 
     | 
    
         
            +
              name: rake-compiler
         
     | 
| 
      
 71 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 72 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 73 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 74 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 75 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
      
 76 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 77 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 78 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 79 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 80 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 81 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 82 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
      
 83 
     | 
    
         
            +
            description: plist_lite is the fastest plist processor for Ruby written in C.It can
         
     | 
| 
      
 84 
     | 
    
         
            +
              convert Ruby object to XML plist (a.k.a. property list), vice versa.
         
     | 
| 
      
 85 
     | 
    
         
            +
            email: tonytonyjan@gmail.com
         
     | 
| 
      
 86 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 87 
     | 
    
         
            +
            extensions:
         
     | 
| 
      
 88 
     | 
    
         
            +
            - ext/plist_lite/ext/extconf.rb
         
     | 
| 
      
 89 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 90 
     | 
    
         
            +
            files:
         
     | 
| 
      
 91 
     | 
    
         
            +
            - ext/plist_lite/ext/ext.c
         
     | 
| 
      
 92 
     | 
    
         
            +
            - ext/plist_lite/ext/extconf.rb
         
     | 
| 
      
 93 
     | 
    
         
            +
            - lib/minimal.plist
         
     | 
| 
      
 94 
     | 
    
         
            +
            - lib/plist.dtd
         
     | 
| 
      
 95 
     | 
    
         
            +
            - lib/plist_lite.rb
         
     | 
| 
      
 96 
     | 
    
         
            +
            - lib/plist_lite/ext.bundle
         
     | 
| 
      
 97 
     | 
    
         
            +
            homepage: https://github.com/tonytonyjan/plist_lite
         
     | 
| 
      
 98 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 99 
     | 
    
         
            +
            - MIT
         
     | 
| 
      
 100 
     | 
    
         
            +
            metadata: {}
         
     | 
| 
      
 101 
     | 
    
         
            +
            post_install_message:
         
     | 
| 
      
 102 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 103 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 104 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 105 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 106 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 107 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 108 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 109 
     | 
    
         
            +
                  version: '2.7'
         
     | 
| 
      
 110 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 111 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 112 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 113 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 114 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 115 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 116 
     | 
    
         
            +
            rubygems_version: 3.2.15
         
     | 
| 
      
 117 
     | 
    
         
            +
            signing_key:
         
     | 
| 
      
 118 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 119 
     | 
    
         
            +
            summary: plist_lite is the fastest plist processor for Ruby written in C.
         
     | 
| 
      
 120 
     | 
    
         
            +
            test_files: []
         
     |