add blob parsing and several other features

This commit is contained in:
Martin Schröder 2016-02-16 13:07:44 +01:00
parent 713c8f5688
commit a1dc5d65b4
6 changed files with 64 additions and 1 deletions

7
blob.h
View file

@ -49,6 +49,7 @@ enum {
BLOB_FIELD_FLOAT64, // a packed 64 bit float
BLOB_FIELD_ARRAY, // only unnamed elements
BLOB_FIELD_TABLE, // only named elements
BLOB_FIELD_ANY, // to be used only as a wildcard
BLOB_FIELD_LAST
};
@ -57,6 +58,12 @@ struct blob {
void *buf; // raw buffer data
};
struct blob_policy {
const char *name;
int type;
struct blob_field *value;
};
//! Initializes a blob structure. Optionally takes memory area to be copied into the buffer which must represent a valid blob buf.
void blob_init(struct blob *buf, const char *data, size_t size);
//! Frees the memory allocated with the buffer

View file

@ -377,3 +377,30 @@ bool blob_field_parse(struct blob_field *attr, const char *signature, struct blo
}
return true;
}
bool blob_field_parse_values(struct blob_field *attr, struct blob_policy *policy, int policy_size){
bool valid = true;
if(blob_field_type(attr) == BLOB_FIELD_TABLE){
struct blob_field *key, *value;
blob_field_for_each_kv(attr, key, value){
for(int c = 0; c < policy_size; c++){
if(strcmp(blob_field_get_string(key), policy[c].name) == 0){
if(policy[c].type == BLOB_FIELD_ANY || blob_field_type(value) == policy[c].type) {
policy[c].value = value;
} else { policy[c].value = NULL; valid = false; }
break;
}
}
}
} else if(blob_field_type(attr) == BLOB_FIELD_ARRAY){
struct blob_field *child;
int pidx = 0;
blob_field_for_each_child(attr, child){
if(policy[pidx].type == BLOB_FIELD_ANY || blob_field_type(child) == policy[pidx].type) {
policy[pidx].value = child;
} else { policy[pidx].value = NULL; valid = false; }
pidx++;
}
}
return valid;
}

View file

@ -79,6 +79,9 @@ bool blob_field_validate(struct blob_field *attr, const char *signature);
bool blob_field_parse(struct blob_field *attr, const char *signature, struct blob_field **out, int out_size);
struct blob_policy;
bool blob_field_parse_values(struct blob_field *attr, struct blob_policy *policy, int policy_size);
#define blob_field_for_each_kv(attr, key, value) \
for(key = blob_field_first_child(attr), value = blob_field_next_child(attr, key); \
key && value; \

View file

@ -227,7 +227,7 @@ static void blob_format_element(struct strbuf *s, struct blob_field *attr, bool
switch(blob_field_type(attr)) {
case BLOB_FIELD_INVALID:
sprintf(buf, "(invalid)");
sprintf(buf, "null");
break;
//case BLOB_FIELD_BOOL:
// sprintf(buf, "%s", *(uint8_t *)data ? "true" : "false");

View file

@ -38,5 +38,6 @@ char *blob_field_to_json(struct blob_field *self);
static inline char *blob_to_json(struct blob *self){ return blob_field_to_json(blob_head(self)); }
bool blob_put_json(struct blob *self, const char *json);
bool blob_put_json_from_file(struct blob *self, const char *file);
#endif

View file

@ -25,6 +25,8 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Added blob parsing code:
Copyright (C) 2016 Martin K. Schröder <mkschreder.uk@gmail.com>
Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc)
http://code.google.com/p/stringencoders/
@ -39,6 +41,9 @@ http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms
#include "blobpack.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "ujson.h"
#define DEBUG(...) {}
@ -161,3 +166,23 @@ bool blob_put_json(struct blob *self, const char *json){
return true;
}
bool blob_put_json_from_file(struct blob *self, const char *file){
// this is a rather simplistic approach where we just load the whole file into memory and then parse the buffer.
// there can probably be better ways where we parse data in place..
// TODO: solve if this becomes a problem later
size_t file_size = 0;
int fd = open(file, O_RDONLY);
if(fd < 0) return false;
file_size = lseek(fd, SEEK_END, 0);
if(file_size > 1000000UL) { close(fd); return false; }
lseek(fd, SEEK_SET, 0);
char *buffer = alloca(file_size + 1); // allocate on stack
memset(buffer, 0, file_size + 1);
if(file_size != read(fd, buffer, file_size)){
close(fd);
return false;
}
close(fd);
return blob_put_json(self, buffer);
}