Contiki-NG
aql-adt.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, Swedish Institute of Computer Science
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  */
32 
33 /**
34  * \file
35  * Utilities for building the internal representation of an AQL command.
36  * \author
37  * Nicolas Tsiftes <nvt@sics.se>
38  */
39 
40 #include <string.h>
41 
42 #include "aql.h"
43 
44 #define DEBUG DEBUG_NONE
45 #include "net/ipv6/uip-debug.h"
46 
47 static unsigned char char_buf[DB_MAX_CHAR_SIZE_PER_ROW];
48 static uint8_t next_free_offset;
49 
50 static aql_attribute_t *
51 get_attribute(aql_adt_t *adt, char *name)
52 {
53  int i;
54 
55  for(i = 0; i < AQL_ATTRIBUTE_COUNT(adt); i++) {
56  if(strcmp(adt->attributes[i].name, name) == 0) {
57  return &adt->attributes[i];
58  }
59  }
60  return NULL;
61 }
62 
63 static unsigned char *
64 save_char(unsigned char *ptr, size_t length)
65 {
66  unsigned char *start_ptr;
67 
68  if(length + next_free_offset > DB_MAX_CHAR_SIZE_PER_ROW) {
69  return NULL;
70  }
71 
72  start_ptr = char_buf + next_free_offset;
73  memcpy(start_ptr, ptr, length);
74  next_free_offset += length;
75 
76  return start_ptr;
77 }
78 
79 void
80 aql_clear(aql_adt_t *adt)
81 {
82  char_buf[0] = 0;
83  next_free_offset = 0;
84 
85  adt->optype = AQL_TYPE_NONE;
86  adt->relation_count = 0;
87  adt->attribute_count = 0;
88  adt->value_count = 0;
89  adt->flags = 0;
90  memset(adt->aggregators, 0, sizeof(adt->aggregators));
91 }
92 
93 db_result_t
94 aql_add_relation(aql_adt_t *adt, const char *name)
95 {
96  if(adt->relation_count >= AQL_RELATION_LIMIT) {
97  return DB_LIMIT_ERROR;
98  }
99 
100  strncpy(adt->relations[adt->relation_count], name,
101  sizeof(adt->relations[0]) - 1);
102  adt->relations[adt->relation_count][sizeof(adt->relations[0]) - 1] = '\0';
103  adt->relation_count++;
104 
105  return DB_OK;
106 }
107 
108 db_result_t
109 aql_add_attribute(aql_adt_t *adt, char *name, domain_t domain,
110  unsigned element_size, int processed_only)
111 {
112  aql_attribute_t *attr;
113 
114  if(adt->attribute_count == AQL_ATTRIBUTE_LIMIT) {
115  return DB_LIMIT_ERROR;
116  }
117 
118  if(processed_only && get_attribute(adt, name)) {
119  /* No need to have multiple instances of attributes that are only
120  used for processing in the PLE. */
121  return DB_OK;
122  }
123 
124  attr = &adt->attributes[adt->attribute_count++];
125 
126  if(strlen(name) + 1 > sizeof(attr->name)) {
127  return DB_LIMIT_ERROR;
128  }
129 
130  strcpy(attr->name, name);
131  attr->domain = domain;
132  attr->element_size = element_size;
133  attr->flags = processed_only ? ATTRIBUTE_FLAG_NO_STORE : 0;
134 
135  return DB_OK;
136 }
137 
138 db_result_t
139 aql_add_value(aql_adt_t *adt, domain_t domain, void *value_ptr)
140 {
141  attribute_value_t *value;
142 
143  if(adt->value_count == AQL_ATTRIBUTE_LIMIT) {
144  return DB_LIMIT_ERROR;
145  }
146 
147  value = &adt->values[adt->value_count++];
148  value->domain = domain;
149 
150  switch(domain) {
151  case DOMAIN_INT:
152  VALUE_LONG(value) = *(long *)value_ptr;
153  break;
154  case DOMAIN_STRING:
155  VALUE_STRING(value) = save_char(value_ptr, strlen(value_ptr) + 1);
156  if(VALUE_STRING(value) != NULL) {
157  break;
158  }
159  default:
160  return DB_TYPE_ERROR;
161  }
162 
163  return DB_OK;
164 }
A set of debugging macros for the IP stack
Definitions and declarations for AQL, the Antelope Query Language.