Ruby  2.1.10p492(2016-04-01revision54464)
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 HAVE_RUBY_ENCODING_H
29 #include "ruby/encoding.h"
30 #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
31 #else
32 #define FORCE_UTF8(obj)
33 #endif
34 
35 /* We don't need to guard objects for rbx, so let's do nothing at all. */
36 #ifndef RB_GC_GUARD
37 #define RB_GC_GUARD(object)
38 #endif
39 
40 typedef struct FBufferStruct {
41  unsigned long initial_length;
42  char *ptr;
43  unsigned long len;
44  unsigned long capa;
45 } FBuffer;
46 
47 #define FBUFFER_INITIAL_LENGTH_DEFAULT 1024
48 
49 #define FBUFFER_PTR(fb) (fb->ptr)
50 #define FBUFFER_LEN(fb) (fb->len)
51 #define FBUFFER_CAPA(fb) (fb->capa)
52 #define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb)
53 
54 static FBuffer *fbuffer_alloc(unsigned long initial_length);
55 static void fbuffer_free(FBuffer *fb);
56 static void fbuffer_clear(FBuffer *fb);
57 static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len);
58 #ifdef JSON_GENERATOR
59 static void fbuffer_append_long(FBuffer *fb, long number);
60 #endif
61 static void fbuffer_append_char(FBuffer *fb, char newchr);
62 #ifdef JSON_GENERATOR
63 static FBuffer *fbuffer_dup(FBuffer *fb);
64 static VALUE fbuffer_to_s(FBuffer *fb);
65 #endif
66 
67 static FBuffer *fbuffer_alloc(unsigned long initial_length)
68 {
69  FBuffer *fb;
70  if (initial_length <= 0) initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
71  fb = ALLOC(FBuffer);
72  memset((void *) fb, 0, sizeof(FBuffer));
73  fb->initial_length = initial_length;
74  return fb;
75 }
76 
77 static void fbuffer_free(FBuffer *fb)
78 {
79  if (fb->ptr) ruby_xfree(fb->ptr);
80  ruby_xfree(fb);
81 }
82 
83 static void fbuffer_clear(FBuffer *fb)
84 {
85  fb->len = 0;
86 }
87 
88 static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
89 {
90  unsigned long required;
91 
92  if (!fb->ptr) {
93  fb->ptr = ALLOC_N(char, fb->initial_length);
94  fb->capa = fb->initial_length;
95  }
96 
97  for (required = fb->capa; requested > required - fb->len; required <<= 1);
98 
99  if (required > fb->capa) {
100  REALLOC_N(fb->ptr, char, required);
101  fb->capa = required;
102  }
103 }
104 
105 static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
106 {
107  if (len > 0) {
108  fbuffer_inc_capa(fb, len);
109  MEMCPY(fb->ptr + fb->len, newstr, char, len);
110  fb->len += len;
111  }
112 }
113 
114 #ifdef JSON_GENERATOR
115 static void fbuffer_append_str(FBuffer *fb, VALUE str)
116 {
117  const char *newstr = StringValuePtr(str);
118  unsigned long len = RSTRING_LEN(str);
119 
120  RB_GC_GUARD(str);
121 
122  fbuffer_append(fb, newstr, len);
123 }
124 #endif
125 
126 static void fbuffer_append_char(FBuffer *fb, char newchr)
127 {
128  fbuffer_inc_capa(fb, 1);
129  *(fb->ptr + fb->len) = newchr;
130  fb->len++;
131 }
132 
133 #ifdef JSON_GENERATOR
134 static void freverse(char *start, char *end)
135 {
136  char c;
137 
138  while (end > start) {
139  c = *end, *end-- = *start, *start++ = c;
140  }
141 }
142 
143 static long fltoa(long number, char *buf)
144 {
145  static char digits[] = "0123456789";
146  long sign = number;
147  char* tmp = buf;
148 
149  if (sign < 0) number = -number;
150  do *tmp++ = digits[number % 10]; while (number /= 10);
151  if (sign < 0) *tmp++ = '-';
152  freverse(buf, tmp - 1);
153  return tmp - buf;
154 }
155 
156 static void fbuffer_append_long(FBuffer *fb, long number)
157 {
158  char buf[20];
159  unsigned long len = fltoa(number, buf);
160  fbuffer_append(fb, buf, len);
161 }
162 
163 static FBuffer *fbuffer_dup(FBuffer *fb)
164 {
165  unsigned long len = fb->len;
166  FBuffer *result;
167 
168  result = fbuffer_alloc(len);
169  fbuffer_append(result, FBUFFER_PAIR(fb));
170  return result;
171 }
172 
173 static VALUE fbuffer_to_s(FBuffer *fb)
174 {
175  VALUE result = rb_str_new(FBUFFER_PAIR(fb));
176  fbuffer_free(fb);
177  FORCE_UTF8(result);
178  return result;
179 }
180 #endif
181 #endif
#define ALLOC(type)
static void fbuffer_clear(FBuffer *fb)
Definition: fbuffer.h:83
#define FBUFFER_PAIR(fb)
Definition: fbuffer.h:52
unsigned long capa
Definition: fbuffer.h:44
RB_GC_GUARD(args)
static void fbuffer_append_char(FBuffer *fb, char newchr)
Definition: fbuffer.h:126
tmp
Definition: enum.c:447
#define FBUFFER_INITIAL_LENGTH_DEFAULT
Definition: fbuffer.h:47
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
#define StringValuePtr(v)
unsigned long initial_length
Definition: fbuffer.h:41
static VALUE char * str
Definition: tcltklib.c:3539
static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
Definition: fbuffer.h:105
struct FBufferStruct FBuffer
#define RSTRING_LEN(str)
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
int len
Definition: enumerator.c:1332
static FBuffer * fbuffer_alloc(unsigned long initial_length)
Definition: fbuffer.h:67
void ruby_xfree(void *x)
Definition: gc.c:6245
char * ptr
Definition: fbuffer.h:42
VpDivd * c
Definition: bigdecimal.c:1223
#define MEMCPY(p1, p2, type, n)
gz end
Definition: zlib.c:2272
unsigned long len
Definition: fbuffer.h:43
static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
Definition: fbuffer.h:88
#define FORCE_UTF8(obj)
Definition: fbuffer.h:30
static void fbuffer_free(FBuffer *fb)
Definition: fbuffer.h:77
#define ALLOC_N(type, n)
VALUE rb_str_new(const char *, long)
Definition: string.c:534
unsigned long VALUE
Definition: ripper.y:88
#define REALLOC_N(var, type, n)
volatile VALUE result
Definition: enum.c:1989