~clint-fewbar/ubuntu/precise/gearmand/drop-unneeded-patches

« back to all changes in this revision

Viewing changes to libgearman/vector.cc

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2009-09-28 21:43:31 UTC
  • mto: (1.2.3 upstream) (6.1.1 sid)
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20090928214331-9bku0d3v1b1ypgp4
ImportĀ upstreamĀ versionĀ 0.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2
 
 * 
3
 
 *  Gearmand String
4
 
 *
5
 
 *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
6
 
 *
7
 
 *  Redistribution and use in source and binary forms, with or without
8
 
 *  modification, are permitted provided that the following conditions are
9
 
 *  met:
10
 
 *
11
 
 *      * Redistributions of source code must retain the above copyright
12
 
 *  notice, this list of conditions and the following disclaimer.
13
 
 *
14
 
 *      * Redistributions in binary form must reproduce the above
15
 
 *  copyright notice, this list of conditions and the following disclaimer
16
 
 *  in the documentation and/or other materials provided with the
17
 
 *  distribution.
18
 
 *
19
 
 *      * The names of its contributors may not be used to endorse or
20
 
 *  promote products derived from this software without specific prior
21
 
 *  written permission.
22
 
 *
23
 
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
 
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
 
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
 
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
 
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
 
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
 
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
 
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
 
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
 
 *
35
 
 */
36
 
 
37
 
 
38
 
#include <libgearman/common.h>
39
 
 
40
 
#include <cassert>
41
 
#include <cstdlib>
42
 
#include <cstring>
43
 
 
44
 
#define GEARMAN_BLOCK_SIZE 1024*4
45
 
 
46
 
inline static gearman_return_t _string_check(gearman_vector_st *string, const size_t need)
47
 
{
48
 
  if (not string)
49
 
    return GEARMAN_INVALID_ARGUMENT;
50
 
 
51
 
  if (need && need > size_t(string->current_size - size_t(string->end - string->string)))
52
 
  {
53
 
    size_t current_offset= size_t(string->end - string->string);
54
 
    char *new_value;
55
 
    size_t adjust;
56
 
    size_t new_size;
57
 
 
58
 
    /* This is the block multiplier. To keep it larger and surive division errors we must round it up */
59
 
    adjust= (need - size_t(string->current_size - size_t(string->end - string->string))) / GEARMAN_BLOCK_SIZE;
60
 
    adjust++;
61
 
 
62
 
    new_size= sizeof(char) * size_t((adjust * GEARMAN_BLOCK_SIZE) + string->current_size);
63
 
    /* Test for overflow */
64
 
    if (new_size < need)
65
 
    {
66
 
      return GEARMAN_MEMORY_ALLOCATION_FAILURE;
67
 
    }
68
 
 
69
 
    new_value= static_cast<char *>(realloc(string->string, new_size));
70
 
    if (new_value == NULL)
71
 
    {
72
 
      return GEARMAN_MEMORY_ALLOCATION_FAILURE;
73
 
    }
74
 
 
75
 
    string->string= new_value;
76
 
    string->end= string->string + current_offset;
77
 
 
78
 
    string->current_size+= (GEARMAN_BLOCK_SIZE * adjust);
79
 
  }
80
 
 
81
 
  return GEARMAN_SUCCESS;
82
 
}
83
 
 
84
 
static inline void _init_string(gearman_vector_st *self)
85
 
{
86
 
  self->current_size= 0;
87
 
  self->end= self->string= NULL;
88
 
}
89
 
 
90
 
gearman_vector_st *gearman_string_create(gearman_vector_st *self, const char *str, size_t initial_size)
91
 
{
92
 
  if (not str)
93
 
    return NULL;
94
 
 
95
 
  self= gearman_string_create(self, initial_size);
96
 
 
97
 
  if (not self)
98
 
    return NULL;
99
 
 
100
 
   if (gearman_failed(gearman_string_append(self, str, initial_size)))
101
 
   {
102
 
     gearman_string_free(self);
103
 
     return NULL;
104
 
   }
105
 
 
106
 
   return self;
107
 
}
108
 
 
109
 
gearman_vector_st *gearman_string_create(gearman_vector_st *self, size_t initial_size)
110
 
{
111
 
  /* Saving malloc calls :) */
112
 
  if (self)
113
 
  {
114
 
    gearman_set_allocated(self, false);
115
 
  }
116
 
  else
117
 
  {
118
 
    self= static_cast<gearman_vector_st *>(malloc(sizeof(gearman_vector_st)));
119
 
 
120
 
    if (not self)
121
 
    {
122
 
      return NULL;
123
 
    }
124
 
 
125
 
    gearman_set_allocated(self, true);
126
 
  }
127
 
 
128
 
  _init_string(self);
129
 
 
130
 
  if (gearman_failed(_string_check(self, initial_size)))
131
 
  {
132
 
    if (gearman_is_allocated(self))
133
 
    {
134
 
      free(self);
135
 
    }
136
 
 
137
 
    return NULL;
138
 
  }
139
 
 
140
 
  if (initial_size)
141
 
    self->string[0]= 0;
142
 
 
143
 
  return self;
144
 
}
145
 
 
146
 
gearman_vector_st *gearman_string_clone(const gearman_vector_st *self)
147
 
{
148
 
  if (not self)
149
 
    return NULL;
150
 
 
151
 
  gearman_vector_st *clone= gearman_string_create(NULL, gearman_string_length(self));
152
 
  if (not clone)
153
 
    return NULL;
154
 
 
155
 
  if (gearman_string_length(self))
156
 
  {
157
 
    if (gearman_failed(gearman_string_append(clone, gearman_string_value(self), gearman_string_length(self))))
158
 
    {
159
 
      gearman_string_free(clone);
160
 
      return NULL;
161
 
    }
162
 
  }
163
 
 
164
 
  return clone;
165
 
}
166
 
 
167
 
gearman_return_t gearman_string_append_character(gearman_vector_st *string, char character)
168
 
{
169
 
  gearman_return_t rc;
170
 
 
171
 
 
172
 
  if (gearman_failed(rc= _string_check(string, 1 +1))) // Null terminate
173
 
  {
174
 
    return rc;
175
 
  }
176
 
 
177
 
  *string->end= character;
178
 
  string->end++;
179
 
  *string->end= 0;
180
 
 
181
 
  return GEARMAN_SUCCESS;
182
 
}
183
 
 
184
 
gearman_return_t gearman_string_append(gearman_vector_st *string,
185
 
                                       const char *value, size_t length)
186
 
{
187
 
  gearman_return_t rc;
188
 
 
189
 
  if (gearman_failed(rc= _string_check(string, length +1)))
190
 
  {
191
 
    return rc;
192
 
  }
193
 
 
194
 
  memcpy(string->end, value, length);
195
 
  string->end+= length;
196
 
  *string->end= 0; // Add a NULL
197
 
 
198
 
  return GEARMAN_SUCCESS;
199
 
}
200
 
 
201
 
char *gearman_string_c_copy(gearman_vector_st *string)
202
 
{
203
 
  char *c_ptr;
204
 
 
205
 
  if (gearman_string_length(string) == 0)
206
 
    return NULL;
207
 
 
208
 
  c_ptr= static_cast<char *>(malloc((gearman_string_length(string) +1) * sizeof(char)));
209
 
 
210
 
  if (not c_ptr)
211
 
    return NULL;
212
 
 
213
 
  memcpy(c_ptr, gearman_string_value(string), gearman_string_length(string));
214
 
  c_ptr[gearman_string_length(string)]= 0;
215
 
 
216
 
  return c_ptr;
217
 
}
218
 
 
219
 
void gearman_string_reset(gearman_vector_st *string)
220
 
{
221
 
  assert(string);
222
 
  string->end= string->string;
223
 
}
224
 
 
225
 
void gearman_string_free(gearman_vector_st *ptr)
226
 
{
227
 
  if (not ptr)
228
 
    return;
229
 
 
230
 
  if (ptr->string)
231
 
  {
232
 
    free(ptr->string);
233
 
  }
234
 
 
235
 
  if (ptr->options.is_allocated)
236
 
  {
237
 
    free(ptr);
238
 
  }
239
 
}
240
 
 
241
 
gearman_return_t gearman_string_check(gearman_vector_st *string, size_t need)
242
 
{
243
 
  return _string_check(string, need);
244
 
}
245
 
 
246
 
size_t gearman_string_length(const gearman_vector_st *self)
247
 
{
248
 
  if (not self)
249
 
    return 0;
250
 
 
251
 
  return size_t(self->end - self->string);
252
 
}
253
 
 
254
 
const char *gearman_string_value(const gearman_vector_st *self)
255
 
{
256
 
  if (not self)
257
 
    return NULL;
258
 
 
259
 
  return self->string;
260
 
}
261
 
 
262
 
gearman_string_t gearman_string(const gearman_vector_st *self)
263
 
{
264
 
  assert(self);
265
 
  gearman_string_t passable= { gearman_string_value(self), gearman_string_length(self) };
266
 
  return passable;
267
 
}
268
 
 
269
 
gearman_string_t gearman_string_take_string(gearman_vector_st *self)
270
 
{
271
 
  assert(self);
272
 
  gearman_string_t passable= gearman_string(self);
273
 
  _init_string(self);
274
 
 
275
 
  return passable;
276
 
}