Drop a memory copy in pc_patch_to_string (#74)

This commit is contained in:
Sandro Santilli 2015-04-21 11:12:07 +02:00
parent ad1c71705a
commit cd7a644818
3 changed files with 45 additions and 22 deletions

View File

@ -13,39 +13,36 @@
#include "pc_api_internal.h"
#include "stringbuffer.h"
char *
pc_patch_uncompressed_to_string(const PCPATCH_UNCOMPRESSED *patch)
/* TODO: expose to API ? Would require also exposing stringbuffer
* See https://github.com/pgpointcloud/pointcloud/issues/74
*/
static int
pc_patch_uncompressed_to_stringbuffer(const PCPATCH_UNCOMPRESSED *patch, stringbuffer_t *sb)
{
/* { "pcid":1, "points":[[<dim1>, <dim2>, <dim3>, <dim4>],[<dim1>, <dim2>, <dim3>, <dim4>]] }*/
stringbuffer_t *sb = stringbuffer_create();
PCPOINTLIST *pl;
char *str;
int i, j;
/* { "pcid":1, "points":[[<dim1>, <dim2>, <dim3>, <dim4>],[<dim1>, <dim2>, <dim3>, <dim4>]] }*/
/* TODO: reserve space in buffer ? */
pl = pc_pointlist_from_uncompressed(patch);
stringbuffer_aprintf(sb, "{\"pcid\":%d,\"pts\":[", patch->schema->pcid);
for ( i = 0; i < pl->npoints; i++ )
{
PCPOINT *pt = pc_pointlist_get_point(pl, i);
if ( i )
{
stringbuffer_append(sb, ",");
}
stringbuffer_append(sb, "[");
if ( i ) stringbuffer_append(sb, ",[");
else stringbuffer_append(sb, "[");
for ( j = 0; j < pt->schema->ndims; j++ )
{
double d;
if ( ! pc_point_get_double_by_index(pt, j, &d))
{
pcerror("%s: unable to read double at index %d", __func__, j);
return NULL;
return PC_FAILURE;
}
if ( j )
{
stringbuffer_append(sb, ",");
}
stringbuffer_aprintf(sb, "%g", d);
if ( j ) stringbuffer_aprintf(sb, ",%g", d);
else stringbuffer_aprintf(sb, "%g", d);
}
stringbuffer_append(sb, "]");
}
@ -53,10 +50,20 @@ pc_patch_uncompressed_to_string(const PCPATCH_UNCOMPRESSED *patch)
/* All done, copy and clean up */
pc_pointlist_free(pl);
str = stringbuffer_getstringcopy(sb);
stringbuffer_destroy(sb);
return str;
return PC_SUCCESS;
}
char *
pc_patch_uncompressed_to_string(const PCPATCH_UNCOMPRESSED *patch)
{
stringbuffer_t *sb = stringbuffer_create();
char *str;
if ( PC_FAILURE == pc_patch_uncompressed_to_stringbuffer(patch, sb) )
return NULL;
str = stringbuffer_release_string(sb);
stringbuffer_destroy(sb);
return str;
}
uint8_t *

View File

@ -3,6 +3,7 @@
*
* Copyright 2002 Thamer Alharbash
* Copyright 2009 Paul Ramsey <pramsey@cleverelephant.ca>
* Copyright 2015 Sandro Santilli <strk@keybit.net>
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
@ -95,8 +96,8 @@ stringbuffer_makeroom(stringbuffer_t *s, size_t size_to_add)
size_t capacity = s->capacity;
size_t required_size = current_size + size_to_add;
while (capacity < required_size)
capacity *= 2;
if ( ! capacity ) capacity = STRINGBUFFER_STARTSIZE;
else while (capacity < required_size) capacity *= 2;
if ( capacity > s->capacity )
{
@ -142,6 +143,19 @@ stringbuffer_getstring(stringbuffer_t *s)
return s->str_start;
}
/**
* Transfer ownership of the internal string to caller,
* turning this buffer into an empty one
*/
char*
stringbuffer_release_string(stringbuffer_t *s)
{
char *ret = s->str_start;
s->str_start = s->str_end = NULL;
s->capacity = 0;
return ret;
}
/**
* Returns a newly allocated string large enough to contain the
* current state of the string. Caller is responsible for

View File

@ -3,6 +3,7 @@
*
* Copyright 2002 Thamer Alharbash
* Copyright 2009 Paul Ramsey <pramsey@cleverelephant.ca>
* Copyright 2015 Sandro Santilli <strk@keybit.net>
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
@ -70,6 +71,7 @@ extern void stringbuffer_append(stringbuffer_t *sb, const char *s);
extern int stringbuffer_aprintf(stringbuffer_t *sb, const char *fmt, ...);
extern const char *stringbuffer_getstring(stringbuffer_t *sb);
extern char *stringbuffer_getstringcopy(stringbuffer_t *sb);
extern char *stringbuffer_release_string(stringbuffer_t *sb);
extern int stringbuffer_getlength(stringbuffer_t *sb);
extern char stringbuffer_lastchar(stringbuffer_t *s);
extern int stringbuffer_trim_trailing_white(stringbuffer_t *s);