PCPOINT * pc_point_make(const PCSCHEMA *s) { size_t sz; PCPOINT *pt; if ( ! s ) { pcerror("null schema passed into pc_point_make"); return NULL; } /* Width of the data area */ sz = s->size; if ( ! sz ) { pcerror("invalid size calculation in pc_point_make"); return NULL; } /* Make our own data area */ pt = pcalloc(sizeof(PCPOINT)); pt->data = pcalloc(sz); /* Set up basic info */ pt->schema = s; pt->readonly = PC_FALSE; return pt; };
PCPOINT * pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t nelems) { int i; PCPOINT *pt; if ( ! s ) { pcerror("null schema passed into pc_point_from_double_array"); return NULL; } if ( s->ndims != nelems ) { pcerror("number of elements in schema and array differ in pc_point_from_double_array"); return NULL; } /* Reference the external data */ pt = pcalloc(sizeof(PCPOINT)); pt->data = pcalloc(s->size); pt->schema = s; pt->readonly = PC_FALSE; for ( i = 0; i < nelems; i++ ) { if ( PC_FAILURE == pc_point_set_double_by_index(pt, i, array[i]) ) { pcerror("failed to write value into dimension %d in pc_point_from_double_array", i); return NULL; } } return pt; }
size_t pc_patch_serialized_size(const PCPATCH *patch) { switch( patch->type ) { case PC_NONE: { PCPATCH_UNCOMPRESSED *pu = (PCPATCH_UNCOMPRESSED*)patch; return sizeof(SERIALIZED_PATCH) - 1 + pu->datasize; } case PC_GHT: { pcerror("pc_patch_serialized_size: GHT format not yet supported"); } case PC_DIMENSIONAL: { return sizeof(SERIALIZED_PATCH) - 1 + pc_patch_dimensional_serialized_size((PCPATCH_DIMENSIONAL*)patch); } default: { pcerror("pc_patch_serialized_size: unknown compresed %d", patch->type); } } return -1; }
void pc_schema_check_xy(PCSCHEMA *s) { int i; for ( i = 0; i < s->ndims; i++ ) { char *dimname = s->dims[i]->name; if ( strcasecmp(dimname, "X") == 0 || strcasecmp(dimname, "Longitude") == 0 || strcasecmp(dimname, "Lon") == 0 ) { s->x_position = i; continue; } if ( strcasecmp(dimname, "Y") == 0 || strcasecmp(dimname, "Latitude") == 0 || strcasecmp(dimname, "Lat") == 0 ) { s->y_position = i; continue; } } if ( s->x_position < 0 ) pcerror("pc_schema_check_xy: invalid x_position '%d'", s->x_position); if ( s->y_position < 0 ) pcerror("pc_schema_check_xy: invalid y_position '%d'", s->y_position); }
uint8_t* bytes_from_hexbytes(const char *hexbuf, size_t hexsize) { uint8_t *buf = NULL; register uint8_t h1, h2; int i; if( hexsize % 2 ) pcerror("Invalid hex string, length (%d) has to be a multiple of two!", hexsize); buf = pcalloc(hexsize/2); if( ! buf ) pcerror("Unable to allocate memory buffer."); for( i = 0; i < hexsize/2; i++ ) { h1 = hex2char[(int)hexbuf[2*i]]; h2 = hex2char[(int)hexbuf[2*i+1]]; if( h1 > 15 ) pcerror("Invalid hex character (%c) encountered", hexbuf[2*i]); if( h2 > 15 ) pcerror("Invalid hex character (%c) encountered", hexbuf[2*i+1]); /* First character is high bits, second is low bits */ buf[i] = ((h1 & 0x0F) << 4) | (h2 & 0x0F); } return buf; }
static void pc_schema_check_xy(const PCSCHEMA *s) { if ( s->x_position < 0 ) pcerror("pc_schema_check_xy: invalid x_position '%d'", s->x_position); if ( s->y_position < 0 ) pcerror("pc_schema_check_xy: invalid y_position '%d'", s->y_position); }
int pc_patch_uncompressed_add_point(PCPATCH_UNCOMPRESSED *c, const PCPOINT *p) { size_t sz; uint8_t *ptr; double x, y; if ( ! ( c && p ) ) { pcerror("%s: null point or patch argument", __func__); return PC_FAILURE; } if ( c->schema->pcid != p->schema->pcid ) { pcerror("%s: pcids of point (%d) and patch (%d) not equal", __func__, c->schema->pcid, p->schema->pcid); return PC_FAILURE; } if ( c->readonly ) { pcerror("%s: cannot add point to readonly patch", __func__); return PC_FAILURE; } if ( c->type != PC_NONE ) { pcerror("%s: cannot add point to compressed patch", __func__); return PC_FAILURE; } sz = c->schema->size; /* Double the data buffer if it's already full */ if ( c->npoints == c->maxpoints ) { c->maxpoints *= 2; c->datasize = c->maxpoints * sz; c->data = pcrealloc(c->data, c->datasize); } /* Copy the data buffer from point to patch */ ptr = c->data + sz * c->npoints; memcpy(ptr, p->data, sz); c->npoints += 1; /* Update bounding box */ x = pc_point_get_x(p); y = pc_point_get_y(p); if ( c->bounds.xmin > x ) c->bounds.xmin = x; if ( c->bounds.ymin > y ) c->bounds.ymin = y; if ( c->bounds.xmax < x ) c->bounds.xmax = x; if ( c->bounds.ymax < y ) c->bounds.ymax = y; return PC_SUCCESS; }
PCPATCH * pc_patch_uncompressed_from_wkb(const PCSCHEMA *s, const uint8_t *wkb, size_t wkbsize) { /* byte: endianness (1 = NDR, 0 = XDR) uint32: pcid (key to POINTCLOUD_SCHEMAS) uint32: compression (0 = no compression, 1 = dimensional, 2 = lazperf) uint32: npoints pcpoint[]: data (interpret relative to pcid) */ static size_t hdrsz = 1+4+4+4; /* endian + pcid + compression + npoints */ PCPATCH_UNCOMPRESSED *patch; uint8_t *data; uint8_t swap_endian = (wkb[0] != machine_endian()); uint32_t npoints; if ( wkb_get_compression(wkb) != PC_NONE ) { pcerror("%s: call with wkb that is not uncompressed", __func__); return NULL; } npoints = wkb_get_npoints(wkb); if ( (wkbsize - hdrsz) != (s->size * npoints) ) { pcerror("%s: wkb size and expected data size do not match", __func__); return NULL; } if ( swap_endian ) { data = uncompressed_bytes_flip_endian(wkb+hdrsz, s, npoints); } else { data = pcalloc(npoints * s->size); memcpy(data, wkb+hdrsz, npoints*s->size); } patch = pcalloc(sizeof(PCPATCH_UNCOMPRESSED)); patch->type = PC_NONE; patch->readonly = PC_FALSE; patch->schema = s; patch->npoints = npoints; patch->maxpoints = npoints; patch->datasize = (wkbsize - hdrsz); patch->data = data; patch->stats = NULL; return (PCPATCH*)patch; }
/** * Convert struct to byte array. * Userdata is currently only PCDIMSTATS, hopefully updated across * a number of iterations and saved. */ SERIALIZED_PATCH * pc_patch_serialize(const PCPATCH *patch_in, void *userdata) { PCPATCH *patch = (PCPATCH*)patch_in; SERIALIZED_PATCH *serpatch = NULL; /* * Ensure the patch has stats calculated before going on */ if ( ! patch->stats ) { pcerror("%s: patch is missing stats", __func__); return NULL; } /* * Convert the patch to the final target compression, * which is the one in the schema. */ if ( patch->type != patch->schema->compression ) { patch = pc_patch_compress(patch_in, userdata); } switch( patch->type ) { case PC_NONE: { serpatch = pc_patch_uncompressed_serialize(patch); break; } case PC_DIMENSIONAL: { serpatch = pc_patch_dimensional_serialize(patch); break; } case PC_GHT: { serpatch = pc_patch_ght_serialize(patch); break; } default: { pcerror("%s: unsupported compression type %d", __func__, patch->type); } } if ( patch != patch_in ) pc_patch_free(patch); return serpatch; }
PCPATCH * pc_patch_ght_from_wkb(const PCSCHEMA *schema, const uint8_t *wkb, size_t wkbsize) { #ifndef HAVE_LIBGHT pcerror("%s: libght support is not enabled", __func__); return NULL; #else /* byte: endianness (1 = NDR, 0 = XDR) uint32: pcid (key to POINTCLOUD_SCHEMAS) uint32: compression (0 = no compression, 1 = dimensional, 2 = GHT) uint32: npoints uint32: ghtsize uint8[]: ghtbuffer */ static size_t hdrsz = 1+4+4+4; /* endian + pcid + compression + npoints */ PCPATCH_GHT *patch; uint8_t swap_endian = (wkb[0] != machine_endian()); uint32_t npoints; size_t ghtsize; const uint8_t *buf; if ( wkb_get_compression(wkb) != PC_GHT ) { pcerror("%s: call with wkb that is not GHT compressed", __func__); return NULL; } npoints = wkb_get_npoints(wkb); patch = pcalloc(sizeof(PCPATCH_GHT)); patch->type = PC_GHT; patch->readonly = PC_FALSE; patch->schema = schema; patch->npoints = npoints; /* Start on the GHT */ buf = wkb+hdrsz; ghtsize = wkb_get_int32(buf, swap_endian); buf += 4; /* Move to start of GHT buffer */ /* Copy in the tree buffer */ patch->ght = pcalloc(ghtsize); patch->ghtsize = ghtsize; memcpy(patch->ght, buf, ghtsize); return (PCPATCH*)patch; #endif }
PCPATCH * pc_patch_deserialize(const SERIALIZED_PATCH *serpatch, const PCSCHEMA *schema) { switch(schema->compression) { case PC_NONE: return pc_patch_uncompressed_deserialize(serpatch, schema); case PC_DIMENSIONAL: return pc_patch_dimensional_deserialize(serpatch, schema); case PC_GHT: pcerror("pc_patch_deserialize: GHT compression currently unsupported"); } pcerror("pc_patch_deserialize: unsupported compression type"); return NULL; }
size_t pc_patch_serialized_size(const PCPATCH *patch) { size_t stats_size = pc_stats_size(patch->schema); size_t common_size = sizeof(SERIALIZED_PATCH) - 1; switch( patch->type ) { case PC_NONE: { PCPATCH_UNCOMPRESSED *pu = (PCPATCH_UNCOMPRESSED*)patch; return common_size + stats_size + pu->datasize; } case PC_GHT: { static size_t ghtsize_size = 4; PCPATCH_GHT *pg = (PCPATCH_GHT*)patch; return common_size + stats_size + ghtsize_size + pg->ghtsize; } case PC_DIMENSIONAL: { return common_size + stats_size + pc_patch_dimensional_serialized_size((PCPATCH_DIMENSIONAL*)patch); } default: { pcerror("%s: unknown compresed %d", __func__, patch->type); } } return -1; }
PCPOINTLIST * pc_pointlist_from_patch(const PCPATCH *patch) { switch ( patch->type ) { case PC_NONE: { return pc_pointlist_from_uncompressed((PCPATCH_UNCOMPRESSED*)patch); } case PC_GHT: { return pc_pointlist_from_ght((PCPATCH_GHT*)patch); } case PC_DIMENSIONAL: { return pc_pointlist_from_dimensional((PCPATCH_DIMENSIONAL*)patch); } case PC_LAZPERF: { return pc_pointlist_from_lazperf((PCPATCH_LAZPERF*)patch); } } /* Don't get here */ pcerror("pc_pointlist_from_patch: unsupported compression type %d", patch->type); return NULL; }
char * pc_point_to_string(const PCPOINT *pt) { /* { "pcid":1, "values":[<dim1>, <dim2>, <dim3>, <dim4>] }*/ stringbuffer_t *sb = stringbuffer_create(); char *str; int i; stringbuffer_aprintf(sb, "{\"pcid\":%d,\"pt\":[", pt->schema->pcid); for ( i = 0; i < pt->schema->ndims; i++ ) { double d; if ( ! pc_point_get_double_by_index(pt, i, &d) ) { pcerror("pc_point_to_string: unable to read double at position %d", i); } if ( i ) { stringbuffer_append(sb, ","); } stringbuffer_aprintf(sb, "%g", d); } stringbuffer_append(sb, "]}"); str = stringbuffer_getstringcopy(sb); stringbuffer_destroy(sb); return str; }
int pc_patch_ght_compute_extent(PCPATCH_GHT *patch) { #ifndef HAVE_LIBGHT pcerror("%s: libght support is not enabled", __func__); return PC_FAILURE; #else GhtTreePtr tree; GhtArea area; /* Get a tree */ tree = ght_tree_from_pc_patch(patch); if ( ! tree ) return PC_FAILURE; /* Calculate bounds and save */ if ( GHT_OK != ght_tree_get_extent(tree, &area) ) return PC_FAILURE; patch->bounds.xmin = area.x.min; patch->bounds.xmax = area.x.max; patch->bounds.ymin = area.y.min; patch->bounds.ymax = area.y.max; // ght_tree_free(tree); return PC_SUCCESS; #endif }
PCPOINT * pc_point_from_wkb(const PCSCHEMA *schema, uint8_t *wkb, size_t wkblen) { /* byte: endianness (1 = NDR, 0 = XDR) uint32: pcid (key to POINTCLOUD_SCHEMAS) uchar[]: data (interpret relative to pcid) */ const size_t hdrsz = 1+4; /* endian + pcid */ uint8_t wkb_endian; uint32_t pcid; uint8_t *data; PCPOINT *pt; if ( ! wkblen ) { pcerror("pc_point_from_wkb: zero length wkb"); } wkb_endian = wkb[0]; pcid = wkb_get_pcid(wkb); if ( (wkblen-hdrsz) != schema->size ) { pcerror("pc_point_from_wkb: wkb size inconsistent with schema size"); } if ( wkb_endian != machine_endian() ) { /* uncompressed_bytes_flip_endian creates a flipped copy */ data = uncompressed_bytes_flip_endian(wkb+hdrsz, schema, 1); } else { data = pcalloc(schema->size); memcpy(data, wkb+hdrsz, wkblen-hdrsz); } pt = pc_point_from_data(schema, data); pt->readonly = PC_FALSE; return pt; }
PCPATCH * pc_patch_filter(const PCPATCH *pa, uint32_t dimnum, PC_FILTERTYPE filter, double val1, double val2) { if ( ! pa ) return NULL; PCPATCH *paout; switch ( pa->type ) { case PC_NONE: { PCBITMAP *map = pc_patch_uncompressed_bitmap((PCPATCH_UNCOMPRESSED*)pa, dimnum, filter, val1, val2); PCPATCH_UNCOMPRESSED *pu; if ( map->nset == 0 ) { pc_bitmap_free(map); return (PCPATCH*)pc_patch_uncompressed_make(pa->schema, 0); } pu = pc_patch_uncompressed_filter((PCPATCH_UNCOMPRESSED*)pa, map); pc_bitmap_free(map); /* pc_patch_uncompressed_filter computes stats and bounds, so we're ready to return here */ /* TODO, it could/should compute bounds and stats while filtering the points */ paout = (PCPATCH*)pu; break; } case PC_GHT: { PCPATCH_GHT *pgh = pc_patch_ght_filter((PCPATCH_GHT*)pa, dimnum, filter, val1, val2); /* pc_patch_ght_filter computes the bounds itself */ /* TODO: add stats computation to pc_patch_ght_filter */ /* pc_patch_ght_filter is just re-using the input stats, which is wrong */ paout = (PCPATCH*)pgh; break; } case PC_DIMENSIONAL: { PCBITMAP *map = pc_patch_dimensional_bitmap((PCPATCH_DIMENSIONAL*)pa, dimnum, filter, val1, val2); PCPATCH_DIMENSIONAL *pdl; if ( map->nset == 0 ) { pc_bitmap_free(map); return (PCPATCH*)pc_patch_uncompressed_make(pa->schema, 0); } pdl = pc_patch_dimensional_filter((PCPATCH_DIMENSIONAL*)pa, map); pc_bitmap_free(map); /* pc_patch_dimensional_filter computes both stats and bounds, so we're done*/ paout = (PCPATCH*)pdl; break; } default: pcerror("%s: failure", __func__); } return paout; }
PCPATCH_UNCOMPRESSED * pc_patch_uncompressed_make(const PCSCHEMA *s, uint32_t maxpoints) { PCPATCH_UNCOMPRESSED *pch; size_t datasize; if ( ! s ) { pcerror("%s: null schema passed in", __func__); return NULL; } /* Width of the data area */ if ( ! s->size ) { pcerror("%s, invalid size calculation", __func__); return NULL; } /* Set up basic info */ pch = pcalloc(sizeof(PCPATCH_UNCOMPRESSED)); pch->type = PC_NONE; pch->readonly = PC_FALSE; pch->schema = s; pch->npoints = 0; pch->stats = NULL; pch->maxpoints = maxpoints; /* Make our own data area */ datasize = s->size * maxpoints; pch->datasize = datasize; pch->data = NULL; if ( datasize ) { pch->data = pcalloc(datasize); } pc_bounds_init(&(pch->bounds)); return pch; }
/** * Convert struct to byte array. * Userdata is currently only PCDIMSTATS, hopefully updated across * a number of iterations and saved. */ SERIALIZED_PATCH * pc_patch_serialize(const PCPATCH *patch_in, void *userdata) { PCPATCH *patch = (PCPATCH*)patch_in; SERIALIZED_PATCH *serpatch; /* * Convert the patch to the final target compression, * which is the one in the schema. */ if ( patch->type != patch->schema->compression ) { patch = pc_patch_compress(patch_in, userdata); } switch( patch->type ) { case PC_NONE: serpatch = pc_patch_uncompressed_serialize(patch); break; case PC_DIMENSIONAL: { serpatch = pc_patch_dimensional_serialize(patch); break; } case PC_GHT: { pcerror("pc_patch_serialize: GHT compression currently unsupported"); break; } default: { pcerror("pc_patch_serialize: unsupported compression type %d", patch->type); } } if ( patch != patch_in ) pc_patch_free(patch); return serpatch; }
char * pc_patch_ght_to_string(const PCPATCH_GHT *pa) { #ifndef HAVE_LIBGHT pcerror("%s: libght support is not enabled", __func__); return NULL; #else PCPATCH_UNCOMPRESSED *patch = pc_patch_uncompressed_from_ght(pa); char *str = pc_patch_uncompressed_to_string(patch); pc_patch_uncompressed_free(patch); return str; #endif }
/** Convert type interpretation number size in bytes */ size_t pc_interpretation_size(uint32_t interp) { if ( interp >= 0 && interp < NUM_INTERPRETATIONS ) { return INTERPRETATION_SIZES[interp]; } else { pcerror("pc_interpretation_size: invalid interpretation"); return 0; } }
static PCPATCH_UNCOMPRESSED * pc_patch_uncompressed_filter(const PCPATCH_UNCOMPRESSED *pu, const PCBITMAP *map) { int i = 0, j = 0; size_t sz = pu->schema->size; PCPATCH_UNCOMPRESSED *fpu = pc_patch_uncompressed_make(pu->schema, map->nset); uint8_t *buf = pu->data; uint8_t *fbuf = fpu->data; assert(map->npoints == pu->npoints); while ( i < pu->npoints ) { if ( pc_bitmap_get(map, i) ) { memcpy(fbuf, buf, sz); fbuf += sz; } buf += sz; i++; } fpu->maxpoints = fpu->npoints = map->nset; if ( PC_FAILURE == pc_patch_uncompressed_compute_extent(fpu) ) { pcerror("%s: failed to compute patch extent", __func__); return NULL; } if ( PC_FAILURE == pc_patch_uncompressed_compute_stats(fpu) ) { pcerror("%s: failed to compute patch stats", __func__); return NULL; } return fpu; }
static SERIALIZED_PATCH * pc_patch_dimensional_serialize(const PCPATCH *patch_in) { // uint32_t size; // uint32_t pcid; // uint32_t compression; // uint32_t npoints; // double xmin, xmax, ymin, ymax; // data: // pcpoint[3] stats; // serialized_pcbytes[ndims] dimensions; int i; uint8_t *buf; size_t serpch_size = pc_patch_serialized_size(patch_in); SERIALIZED_PATCH *serpch = pcalloc(serpch_size); const PCPATCH_DIMENSIONAL *patch = (PCPATCH_DIMENSIONAL*)patch_in; assert(patch_in); assert(patch_in->type == PC_DIMENSIONAL); /* Copy basics */ serpch->pcid = patch->schema->pcid; serpch->npoints = patch->npoints; serpch->bounds = patch->bounds; serpch->compression = patch->type; //pcinfo(" dim serialisation : just copied basic : pcid : %d, npoints : %d, compression :%d, bounds\n", serpch->pcid,serpch->npoints,serpch->compression ); /* Get a pointer to the data area */ buf = serpch->data; /* Write stats into the buffer */ if ( patch->stats ) { buf += pc_patch_stats_serialize(buf, patch->schema, patch->stats); } else { pcerror("%s: stats missing!", __func__); } /* Write each dimension in after the stats */ for ( i = 0; i < patch->schema->ndims; i++ ) { size_t bsize = 0; PCBYTES *pcb = &(patch->bytes[i]); pc_bytes_serialize(pcb, buf, &bsize); buf += bsize; } SET_VARSIZE(serpch, serpch_size); return serpch; }
/** * This function returns the position of a dimension of the given name, or -1 if there is no dimension of the given name * * */ uint32_t pc_schema_get_dimension_position_by_name(const PCSCHEMA *s, const char *name) { PCDIMENSION * temp ; temp = pc_schema_get_dimension_by_name(s, name); if(temp == NULL) { return -1; pcerror("error, the dimension %s doesn't exit in the schema %s \n",name,pc_schema_to_json(s)); } else { return temp->position; } }
PCPATCH * pc_patch_deserialize(const SERIALIZED_PATCH *serpatch, const PCSCHEMA *schema) { switch(serpatch->compression) { case PC_NONE: return pc_patch_uncompressed_deserialize(serpatch, schema); case PC_DIMENSIONAL: return pc_patch_dimensional_deserialize(serpatch, schema); case PC_GHT: return pc_patch_ght_deserialize(serpatch, schema); } pcerror("%s: unsupported compression type", __func__); return NULL; }
static SERIALIZED_PATCH * pc_patch_ght_serialize(const PCPATCH *patch_in) { // uint32_t size; // uint32_t pcid; // uint32_t compression; // uint32_t npoints; // double xmin, xmax, ymin, ymax; // data: // pcpoint[3] stats; // uint32_t ghtsize; // uint8_t ght[]; size_t serpch_size = pc_patch_serialized_size(patch_in); SERIALIZED_PATCH *serpch = pcalloc(serpch_size); const PCPATCH_GHT *patch = (PCPATCH_GHT*)patch_in; uint32_t ghtsize = patch->ghtsize; uint8_t *buf = serpch->data; assert(patch); assert(patch->type == PC_GHT); /* Copy basics */ serpch->pcid = patch->schema->pcid; serpch->npoints = patch->npoints; serpch->bounds = patch->bounds; serpch->compression = patch->type; /* Write stats into the buffer first */ if ( patch->stats ) { buf += pc_patch_stats_serialize(buf, patch->schema, patch->stats); } else { pcerror("%s: stats missing!", __func__); } /* Write tree buffer size */ memcpy(buf, &(ghtsize), 4); buf += 4; /* Write tree buffer */ memcpy(buf, patch->ght, patch->ghtsize); SET_VARSIZE(serpch, serpch_size); return serpch; }
AST* AST_initialize(ASTnode node) { AST *ast; if (!(ast = malloc(sizeof(*ast)))) { pcerror("Out of memory.\n"); return NULL; } ast->node = node; ast->name = NULL; ast->sym = eofsym; ast->val.ival = 0; ast->head = NULL; ast->tail = NULL; return ast; }
PCPATCH * pc_patch_dimensional_from_wkb(const PCSCHEMA *schema, const uint8_t *wkb, size_t wkbsize) { /* byte: endianness (1 = NDR, 0 = XDR) uint32: pcid (key to POINTCLOUD_SCHEMAS) uint32: compression (0 = no compression, 1 = dimensional, 2 = GHT) uint32: npoints dimensions[]: dims (interpret relative to pcid and compressions) */ static size_t hdrsz = 1+4+4+4; /* endian + pcid + compression + npoints */ PCPATCH_DIMENSIONAL *patch; uint8_t swap_endian = (wkb[0] != machine_endian()); uint32_t npoints, ndims; const uint8_t *buf; int i; if ( wkb_get_compression(wkb) != PC_DIMENSIONAL ) { pcerror("%s: call with wkb that is not dimensionally compressed", __func__); return NULL; } npoints = wkb_get_npoints(wkb); ndims = schema->ndims; patch = pcalloc(sizeof(PCPATCH_DIMENSIONAL)); patch->type = PC_DIMENSIONAL; patch->readonly = PC_FALSE; patch->schema = schema; patch->npoints = npoints; patch->bytes = pcalloc(ndims*sizeof(PCBYTES)); buf = wkb+hdrsz; for ( i = 0; i < ndims; i++ ) { PCBYTES *pcb = &(patch->bytes[i]); PCDIMENSION *dim = schema->dims[i]; pc_bytes_deserialize(buf, dim, pcb, PC_FALSE /*readonly*/, swap_endian); pcb->npoints = npoints; buf += pc_bytes_serialized_size(pcb); } return (PCPATCH*)patch; }
static PCPATCH * pc_patch_uncompressed_deserialize(const SERIALIZED_PATCH *serpatch, const PCSCHEMA *schema) { // typedef struct // { // uint32_t size; // uint32_t pcid; // uint32_t compression; // uint32_t npoints; // double xmin, xmax, ymin, ymax; // data: // pcpoint[3] pcstats(min, max, avg) // pcpoint[npoints] // } // SERIALIZED_PATCH; uint8_t *buf; size_t stats_size = pc_stats_size(schema); // 3 pcpoints worth of stats PCPATCH_UNCOMPRESSED *patch = pcalloc(sizeof(PCPATCH_UNCOMPRESSED)); /* Set up basic info */ patch->type = serpatch->compression; patch->schema = schema; patch->readonly = true; patch->npoints = serpatch->npoints; patch->maxpoints = 0; patch->bounds = serpatch->bounds; buf = (uint8_t*)serpatch->data; /* Point into the stats area */ patch->stats = pc_patch_stats_deserialize(schema, buf); /* Advance data pointer past the stats serialization */ patch->data = buf + stats_size; /* Calculate the point data buffer size */ patch->datasize = VARSIZE(serpatch) - sizeof(SERIALIZED_PATCH) + 1 - stats_size; if ( patch->datasize != patch->npoints * schema->size ) pcerror("%s: calucated patch data sizes don't match (%d != %d)", __func__, patch->datasize, patch->npoints * schema->size); return (PCPATCH*)patch; }
char* hexbytes_from_bytes(const uint8_t *bytebuf, size_t bytesize) { char *buf = pcalloc(2*bytesize + 1); /* 2 chars per byte + null terminator */ int i; char *ptr = buf; for ( i = 0; i < bytesize; i++ ) { int incr = snprintf(ptr, 3, "%02X", bytebuf[i]); if ( incr < 0 ) { pcerror("write failure in hexbytes_from_bytes"); return NULL; } ptr += incr; } return buf; }