| Viewing file:  fbuffer.h (4.18 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
#ifndef _FBUFFER_H_
 #define _FBUFFER_H_
 
 #include "ruby.h"
 
 #ifndef RHASH_SIZE
 #define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries)
 #endif
 
 #ifndef RFLOAT_VALUE
 #define RFLOAT_VALUE(val) (RFLOAT(val)->value)
 #endif
 
 #ifndef RARRAY_LEN
 #define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len
 #endif
 #ifndef RSTRING_PTR
 #define RSTRING_PTR(string) RSTRING(string)->ptr
 #endif
 #ifndef RSTRING_LEN
 #define RSTRING_LEN(string) RSTRING(string)->len
 #endif
 
 #ifdef PRIsVALUE
 # define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj)
 # define RB_OBJ_STRING(obj) (obj)
 #else
 # define PRIsVALUE "s"
 # define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj)
 # define RB_OBJ_STRING(obj) StringValueCStr(obj)
 #endif
 
 #ifdef HAVE_RUBY_ENCODING_H
 #include "ruby/encoding.h"
 #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
 #else
 #define FORCE_UTF8(obj)
 #endif
 
 /* We don't need to guard objects for rbx, so let's do nothing at all. */
 #ifndef RB_GC_GUARD
 #define RB_GC_GUARD(object)
 #endif
 
 typedef struct FBufferStruct {
 unsigned long initial_length;
 char *ptr;
 unsigned long len;
 unsigned long capa;
 } FBuffer;
 
 #define FBUFFER_INITIAL_LENGTH_DEFAULT 1024
 
 #define FBUFFER_PTR(fb) (fb->ptr)
 #define FBUFFER_LEN(fb) (fb->len)
 #define FBUFFER_CAPA(fb) (fb->capa)
 #define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb)
 
 static FBuffer *fbuffer_alloc(unsigned long initial_length);
 static void fbuffer_free(FBuffer *fb);
 static void fbuffer_clear(FBuffer *fb);
 static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len);
 #ifdef JSON_GENERATOR
 static void fbuffer_append_long(FBuffer *fb, long number);
 #endif
 static void fbuffer_append_char(FBuffer *fb, char newchr);
 #ifdef JSON_GENERATOR
 static FBuffer *fbuffer_dup(FBuffer *fb);
 static VALUE fbuffer_to_s(FBuffer *fb);
 #endif
 
 static FBuffer *fbuffer_alloc(unsigned long initial_length)
 {
 FBuffer *fb;
 if (initial_length <= 0) initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
 fb = ALLOC(FBuffer);
 memset((void *) fb, 0, sizeof(FBuffer));
 fb->initial_length = initial_length;
 return fb;
 }
 
 static void fbuffer_free(FBuffer *fb)
 {
 if (fb->ptr) ruby_xfree(fb->ptr);
 ruby_xfree(fb);
 }
 
 static void fbuffer_clear(FBuffer *fb)
 {
 fb->len = 0;
 }
 
 static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
 {
 unsigned long required;
 
 if (!fb->ptr) {
 fb->ptr = ALLOC_N(char, fb->initial_length);
 fb->capa = fb->initial_length;
 }
 
 for (required = fb->capa; requested > required - fb->len; required <<= 1);
 
 if (required > fb->capa) {
 REALLOC_N(fb->ptr, char, required);
 fb->capa = required;
 }
 }
 
 static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
 {
 if (len > 0) {
 fbuffer_inc_capa(fb, len);
 MEMCPY(fb->ptr + fb->len, newstr, char, len);
 fb->len += len;
 }
 }
 
 #ifdef JSON_GENERATOR
 static void fbuffer_append_str(FBuffer *fb, VALUE str)
 {
 const char *newstr = StringValuePtr(str);
 unsigned long len = RSTRING_LEN(str);
 
 RB_GC_GUARD(str);
 
 fbuffer_append(fb, newstr, len);
 }
 #endif
 
 static void fbuffer_append_char(FBuffer *fb, char newchr)
 {
 fbuffer_inc_capa(fb, 1);
 *(fb->ptr + fb->len) = newchr;
 fb->len++;
 }
 
 #ifdef JSON_GENERATOR
 static void freverse(char *start, char *end)
 {
 char c;
 
 while (end > start) {
 c = *end, *end-- = *start, *start++ = c;
 }
 }
 
 static long fltoa(long number, char *buf)
 {
 static char digits[] = "0123456789";
 long sign = number;
 char* tmp = buf;
 
 if (sign < 0) number = -number;
 do *tmp++ = digits[number % 10]; while (number /= 10);
 if (sign < 0) *tmp++ = '-';
 freverse(buf, tmp - 1);
 return tmp - buf;
 }
 
 static void fbuffer_append_long(FBuffer *fb, long number)
 {
 char buf[20];
 unsigned long len = fltoa(number, buf);
 fbuffer_append(fb, buf, len);
 }
 
 static FBuffer *fbuffer_dup(FBuffer *fb)
 {
 unsigned long len = fb->len;
 FBuffer *result;
 
 result = fbuffer_alloc(len);
 fbuffer_append(result, FBUFFER_PAIR(fb));
 return result;
 }
 
 static VALUE fbuffer_to_s(FBuffer *fb)
 {
 VALUE result = rb_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb));
 fbuffer_free(fb);
 FORCE_UTF8(result);
 return result;
 }
 #endif
 #endif
 
 |