Ruby  2.0.0p451(2014-02-24revision45167)
fbuffer.h
Go to the documentation of this file.
1 
2 #ifndef _FBUFFER_H_
3 #define _FBUFFER_H_
4 
5 #include "ruby.h"
6 
7 #ifndef RHASH_SIZE
8 #define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries)
9 #endif
10 
11 #ifndef RFLOAT_VALUE
12 #define RFLOAT_VALUE(val) (RFLOAT(val)->value)
13 #endif
14 
15 #ifndef RARRAY_PTR
16 #define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr
17 #endif
18 #ifndef RARRAY_LEN
19 #define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len
20 #endif
21 #ifndef RSTRING_PTR
22 #define RSTRING_PTR(string) RSTRING(string)->ptr
23 #endif
24 #ifndef RSTRING_LEN
25 #define RSTRING_LEN(string) RSTRING(string)->len
26 #endif
27 
28 #ifdef PRIsVALUE
29 # define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj)
30 # define RB_OBJ_STRING(obj) (obj)
31 #else
32 # define PRIsVALUE "s"
33 # define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj)
34 # define RB_OBJ_STRING(obj) StringValueCStr(obj)
35 #endif
36 
37 #ifdef HAVE_RUBY_ENCODING_H
38 #include "ruby/encoding.h"
39 #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
40 #else
41 #define FORCE_UTF8(obj)
42 #endif
43 
44 /* We don't need to guard objects for rbx, so let's do nothing at all. */
45 #ifndef RB_GC_GUARD
46 #define RB_GC_GUARD(object)
47 #endif
48 
49 typedef struct FBufferStruct {
50  unsigned long initial_length;
51  char *ptr;
52  unsigned long len;
53  unsigned long capa;
54 } FBuffer;
55 
56 #define FBUFFER_INITIAL_LENGTH_DEFAULT 1024
57 
58 #define FBUFFER_PTR(fb) (fb->ptr)
59 #define FBUFFER_LEN(fb) (fb->len)
60 #define FBUFFER_CAPA(fb) (fb->capa)
61 #define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb)
62 
63 static FBuffer *fbuffer_alloc(unsigned long initial_length);
64 static void fbuffer_free(FBuffer *fb);
65 static void fbuffer_clear(FBuffer *fb);
66 static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len);
67 #ifdef JSON_GENERATOR
68 static void fbuffer_append_long(FBuffer *fb, long number);
69 #endif
70 static void fbuffer_append_char(FBuffer *fb, char newchr);
71 #ifdef JSON_GENERATOR
72 static FBuffer *fbuffer_dup(FBuffer *fb);
73 static VALUE fbuffer_to_s(FBuffer *fb);
74 #endif
75 
76 static FBuffer *fbuffer_alloc(unsigned long initial_length)
77 {
78  FBuffer *fb;
79  if (initial_length <= 0) initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
80  fb = ALLOC(FBuffer);
81  memset((void *) fb, 0, sizeof(FBuffer));
82  fb->initial_length = initial_length;
83  return fb;
84 }
85 
86 static void fbuffer_free(FBuffer *fb)
87 {
88  if (fb->ptr) ruby_xfree(fb->ptr);
89  ruby_xfree(fb);
90 }
91 
92 static void fbuffer_clear(FBuffer *fb)
93 {
94  fb->len = 0;
95 }
96 
97 static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
98 {
99  unsigned long required;
100 
101  if (!fb->ptr) {
102  fb->ptr = ALLOC_N(char, fb->initial_length);
103  fb->capa = fb->initial_length;
104  }
105 
106  for (required = fb->capa; requested > required - fb->len; required <<= 1);
107 
108  if (required > fb->capa) {
109  REALLOC_N(fb->ptr, char, required);
110  fb->capa = required;
111  }
112 }
113 
114 static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
115 {
116  if (len > 0) {
117  fbuffer_inc_capa(fb, len);
118  MEMCPY(fb->ptr + fb->len, newstr, char, len);
119  fb->len += len;
120  }
121 }
122 
123 #ifdef JSON_GENERATOR
124 static void fbuffer_append_str(FBuffer *fb, VALUE str)
125 {
126  const char *newstr = StringValuePtr(str);
127  unsigned long len = RSTRING_LEN(str);
128 
129  RB_GC_GUARD(str);
130 
131  fbuffer_append(fb, newstr, len);
132 }
133 #endif
134 
135 static void fbuffer_append_char(FBuffer *fb, char newchr)
136 {
137  fbuffer_inc_capa(fb, 1);
138  *(fb->ptr + fb->len) = newchr;
139  fb->len++;
140 }
141 
142 #ifdef JSON_GENERATOR
143 static void freverse(char *start, char *end)
144 {
145  char c;
146 
147  while (end > start) {
148  c = *end, *end-- = *start, *start++ = c;
149  }
150 }
151 
152 static long fltoa(long number, char *buf)
153 {
154  static char digits[] = "0123456789";
155  long sign = number;
156  char* tmp = buf;
157 
158  if (sign < 0) number = -number;
159  do *tmp++ = digits[number % 10]; while (number /= 10);
160  if (sign < 0) *tmp++ = '-';
161  freverse(buf, tmp - 1);
162  return tmp - buf;
163 }
164 
165 static void fbuffer_append_long(FBuffer *fb, long number)
166 {
167  char buf[20];
168  unsigned long len = fltoa(number, buf);
169  fbuffer_append(fb, buf, len);
170 }
171 
172 static FBuffer *fbuffer_dup(FBuffer *fb)
173 {
174  unsigned long len = fb->len;
175  FBuffer *result;
176 
177  result = fbuffer_alloc(len);
178  fbuffer_append(result, FBUFFER_PAIR(fb));
179  return result;
180 }
181 
182 static VALUE fbuffer_to_s(FBuffer *fb)
183 {
184  VALUE result = rb_str_new(FBUFFER_PAIR(fb));
185  fbuffer_free(fb);
186  FORCE_UTF8(result);
187  return result;
188 }
189 #endif
190 #endif
#define ALLOC(type)
static void fbuffer_clear(FBuffer *fb)
Definition: fbuffer.h:92
#define FBUFFER_PAIR(fb)
Definition: fbuffer.h:61
unsigned long VALUE
Definition: ripper.y:104
unsigned long capa
Definition: fbuffer.h:53
static void fbuffer_append_char(FBuffer *fb, char newchr)
Definition: fbuffer.h:135
#define FBUFFER_INITIAL_LENGTH_DEFAULT
Definition: fbuffer.h:56
#define StringValuePtr(v)
unsigned long initial_length
Definition: fbuffer.h:50
return c
Definition: ripper.y:7591
static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
Definition: fbuffer.h:114
struct FBufferStruct FBuffer
#define RSTRING_LEN(str)
static FBuffer * fbuffer_alloc(unsigned long initial_length)
Definition: fbuffer.h:76
void ruby_xfree(void *x)
Definition: gc.c:3653
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
#define RB_GC_GUARD(v)
static VALUE result
Definition: nkf.c:40
char * ptr
Definition: fbuffer.h:51
#define MEMCPY(p1, p2, type, n)
unsigned long len
Definition: fbuffer.h:52
static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
Definition: fbuffer.h:97
#define FORCE_UTF8(obj)
Definition: fbuffer.h:39
static void fbuffer_free(FBuffer *fb)
Definition: fbuffer.h:86
#define ALLOC_N(type, n)
VALUE rb_str_new(const char *, long)
Definition: string.c:425
#define REALLOC_N(var, type, n)