|
Ruby
2.0.0p481(2014-05-08revision45883)
|
00001 00002 #ifndef _FBUFFER_H_ 00003 #define _FBUFFER_H_ 00004 00005 #include "ruby.h" 00006 00007 #ifndef RHASH_SIZE 00008 #define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries) 00009 #endif 00010 00011 #ifndef RFLOAT_VALUE 00012 #define RFLOAT_VALUE(val) (RFLOAT(val)->value) 00013 #endif 00014 00015 #ifndef RARRAY_PTR 00016 #define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr 00017 #endif 00018 #ifndef RARRAY_LEN 00019 #define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len 00020 #endif 00021 #ifndef RSTRING_PTR 00022 #define RSTRING_PTR(string) RSTRING(string)->ptr 00023 #endif 00024 #ifndef RSTRING_LEN 00025 #define RSTRING_LEN(string) RSTRING(string)->len 00026 #endif 00027 00028 #ifdef PRIsVALUE 00029 # define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj) 00030 # define RB_OBJ_STRING(obj) (obj) 00031 #else 00032 # define PRIsVALUE "s" 00033 # define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj) 00034 # define RB_OBJ_STRING(obj) StringValueCStr(obj) 00035 #endif 00036 00037 #ifdef HAVE_RUBY_ENCODING_H 00038 #include "ruby/encoding.h" 00039 #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding()) 00040 #else 00041 #define FORCE_UTF8(obj) 00042 #endif 00043 00044 /* We don't need to guard objects for rbx, so let's do nothing at all. */ 00045 #ifndef RB_GC_GUARD 00046 #define RB_GC_GUARD(object) 00047 #endif 00048 00049 typedef struct FBufferStruct { 00050 unsigned long initial_length; 00051 char *ptr; 00052 unsigned long len; 00053 unsigned long capa; 00054 } FBuffer; 00055 00056 #define FBUFFER_INITIAL_LENGTH_DEFAULT 1024 00057 00058 #define FBUFFER_PTR(fb) (fb->ptr) 00059 #define FBUFFER_LEN(fb) (fb->len) 00060 #define FBUFFER_CAPA(fb) (fb->capa) 00061 #define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb) 00062 00063 static FBuffer *fbuffer_alloc(unsigned long initial_length); 00064 static void fbuffer_free(FBuffer *fb); 00065 static void fbuffer_clear(FBuffer *fb); 00066 static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len); 00067 #ifdef JSON_GENERATOR 00068 static void fbuffer_append_long(FBuffer *fb, long number); 00069 #endif 00070 static void fbuffer_append_char(FBuffer *fb, char newchr); 00071 #ifdef JSON_GENERATOR 00072 static FBuffer *fbuffer_dup(FBuffer *fb); 00073 static VALUE fbuffer_to_s(FBuffer *fb); 00074 #endif 00075 00076 static FBuffer *fbuffer_alloc(unsigned long initial_length) 00077 { 00078 FBuffer *fb; 00079 if (initial_length <= 0) initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT; 00080 fb = ALLOC(FBuffer); 00081 memset((void *) fb, 0, sizeof(FBuffer)); 00082 fb->initial_length = initial_length; 00083 return fb; 00084 } 00085 00086 static void fbuffer_free(FBuffer *fb) 00087 { 00088 if (fb->ptr) ruby_xfree(fb->ptr); 00089 ruby_xfree(fb); 00090 } 00091 00092 static void fbuffer_clear(FBuffer *fb) 00093 { 00094 fb->len = 0; 00095 } 00096 00097 static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested) 00098 { 00099 unsigned long required; 00100 00101 if (!fb->ptr) { 00102 fb->ptr = ALLOC_N(char, fb->initial_length); 00103 fb->capa = fb->initial_length; 00104 } 00105 00106 for (required = fb->capa; requested > required - fb->len; required <<= 1); 00107 00108 if (required > fb->capa) { 00109 REALLOC_N(fb->ptr, char, required); 00110 fb->capa = required; 00111 } 00112 } 00113 00114 static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len) 00115 { 00116 if (len > 0) { 00117 fbuffer_inc_capa(fb, len); 00118 MEMCPY(fb->ptr + fb->len, newstr, char, len); 00119 fb->len += len; 00120 } 00121 } 00122 00123 #ifdef JSON_GENERATOR 00124 static void fbuffer_append_str(FBuffer *fb, VALUE str) 00125 { 00126 const char *newstr = StringValuePtr(str); 00127 unsigned long len = RSTRING_LEN(str); 00128 00129 RB_GC_GUARD(str); 00130 00131 fbuffer_append(fb, newstr, len); 00132 } 00133 #endif 00134 00135 static void fbuffer_append_char(FBuffer *fb, char newchr) 00136 { 00137 fbuffer_inc_capa(fb, 1); 00138 *(fb->ptr + fb->len) = newchr; 00139 fb->len++; 00140 } 00141 00142 #ifdef JSON_GENERATOR 00143 static void freverse(char *start, char *end) 00144 { 00145 char c; 00146 00147 while (end > start) { 00148 c = *end, *end-- = *start, *start++ = c; 00149 } 00150 } 00151 00152 static long fltoa(long number, char *buf) 00153 { 00154 static char digits[] = "0123456789"; 00155 long sign = number; 00156 char* tmp = buf; 00157 00158 if (sign < 0) number = -number; 00159 do *tmp++ = digits[number % 10]; while (number /= 10); 00160 if (sign < 0) *tmp++ = '-'; 00161 freverse(buf, tmp - 1); 00162 return tmp - buf; 00163 } 00164 00165 static void fbuffer_append_long(FBuffer *fb, long number) 00166 { 00167 char buf[20]; 00168 unsigned long len = fltoa(number, buf); 00169 fbuffer_append(fb, buf, len); 00170 } 00171 00172 static FBuffer *fbuffer_dup(FBuffer *fb) 00173 { 00174 unsigned long len = fb->len; 00175 FBuffer *result; 00176 00177 result = fbuffer_alloc(len); 00178 fbuffer_append(result, FBUFFER_PAIR(fb)); 00179 return result; 00180 } 00181 00182 static VALUE fbuffer_to_s(FBuffer *fb) 00183 { 00184 VALUE result = rb_str_new(FBUFFER_PAIR(fb)); 00185 fbuffer_free(fb); 00186 FORCE_UTF8(result); 00187 return result; 00188 } 00189 #endif 00190 #endif 00191
1.7.6.1