/ story-6-Symbols-Parameters-Accessors-and-Callbacks.org
story-6-Symbols-Parameters-Accessors-and-Callbacks.org
1 #+TITLE: Story 6 - Symbols, Parameters, Accessors and Callbacks 2 #+OPTIONS: author:nil date:nil 3 4 *NOTE: Revoked by [[file:story-9-Revoking-Symbols-Parameters-Accessors-and-Callbacks.org::+TITLE: Story 9 - Revoking 'Story 6 - Symbols, Parameters, Accessors and Callbacks'][Story 9 - Revoking 'Story 6 - Symbols, Parameters, Accessors and Callbacks']]* 5 6 * Symbols 7 8 Symbols are very simple things, aren't they? They're just... words, what 9 can be hard about that? 10 11 They are indeed simple on a conceptual basis, but when it comes down to 12 code, it might get a bit more complicated... like, how do you repreaent a 13 symbol? They could be represented with strings, that should be easy enough, 14 but then you have multiple strings, and need to compare them to know if they 15 represent the same symbol or not. That's usually slow. 16 17 A way to look at symbols is that they can be represented with an address, 18 i.e. be some sort of unique object. Common Lisp does exactly this, it has a 19 function ~intern~ which is used to either find a symbol that matches a given 20 string, or if it doesn't exist yet, create it. The result is a symbol, i.e. 21 an object at a specific and unique address in memory. 22 23 For Le'Sec Core, an easy way to do something like Common Lisp does is to 24 call an ~intern~ like function with a string, and if it isn't already 25 registered, simply register its address, and decide that /that/ address is 26 the symbol. Any other calls of this ~intern~ like function with the same 27 string contents will return the address that was registered. Code that 28 wants to be efficient should remember that address and use it any time it 29 wants to compare symbols. 30 31 * Parameter values 32 33 A parameter value is a < data type, data length, data > tuple, and can be 34 used in multiple manners. 35 36 ** Type + length 37 38 The type primarly needs to encode what sort of data is expected coupled with 39 how it's organised in memory. Among others, this means that there's no need 40 for a large variety of integer types like C does, since the length is 41 encoded separately. 42 43 *** NULL value 44 45 The NULL value is a parameter value where the data type is zero. Everything 46 else can be ignored. 47 48 *** Small numeric scalars 49 50 For these, the data field is expected to hold the actual data. 51 52 - integer (maximum size: what can be held in an =intmax_t=) 53 - unsigned integer (maximum size: what can be held in an =uintmax_t=) 54 - real number (maximum size: what can be held in a =double=) 55 56 *** Large scalars 57 58 For these the data field is expected to hold a pointer to the data. Exactly 59 what is depends on the type. 60 61 - integer and unsigned integer 62 63 Because there's no single solution for larger integers in C, they are a 64 bit more complex, and need to be treated via an [[*Accessors][accessor]]. 65 66 - string 67 - blob (corresponds to the ASN.1 OCTET STRING and BIT STRING) 68 69 *** Arrays 70 71 For arrays, the data field is expected to be a pointer to an array of 72 parameter values, terminated with a [[*NULL value][NULL value]]. 73 74 Arrays can represent two concepts: 75 76 - sets, which makes the array unordered. 77 - sequences, which makes the array ordered. 78 79 *** Structures 80 81 The value is a pointer to an array of [[*Parameters][parameters]]. 82 83 ** Usages 84 85 *** Passing a value 86 87 This is a simple straightforward case. The data field has actual value, in 88 accordance with the [[*Type + length][type and length]]. An accessor that implements 89 [[*Getter][getter functions]] may be specified. 90 91 *** Declaring an accepted value 92 93 This is returned on request, to tell a caller what's accepted. In this 94 case, the data field has no value at all, unless it's an [[*Accessors][accessor]] that 95 implements parsing functions. 96 97 *** Requesting a value 98 99 This is passed when a parameter value is to be returned. 100 101 Just as for [[*Declaring an accepted value][declaring an accepted value]], the data field has no value at all, 102 unless it's an accessor that implements [[*Setter][setter functions]]. 103 104 * Parameters 105 106 A parameter is a binding between a [[*Symbols][symbol]] and a [[*Parameter values][parameter value]]. 107 108 A parameter may be passed as a single value. In that case, it should 109 usually be passed by value. 110 111 A set of parameters may also be passed as an array, where ordering 112 isn't expected to matter. In this case, the array must be terminated 113 by a NULL parameter, which is a parameter where the [[*Symbols][symbol]] is NULL. 114 115 A parameter or parameter set is always read-only for the recipient. When 116 [[*Requesting a value][requesting values]], a way to pass the value back is expected to be 117 passed as well: 118 119 - For a single parameter, a result pointer 120 - For a parameter set, a [[*Callbacks][callback]]. This callback is expected to 121 receive another parameters set with the values set. 122 123 If no way to pass the value back is given, the value of each requested 124 parameter /must/ be an [[*Accessors][accessor]] that implements [[*Setter][setter functions]]. 125 126 * Accessors 127 128 An accessor is a data set, where the dispatch function supports generic 129 access functionality to the actual data. 130 131 The idea is that Le'Sec shouldn't push any particular technology for types 132 of data that don't have direct support in C's existing type system, but 133 should rather provide technology agnostic ways for the receiver to retrieve 134 the data and do what they want with it. 135 136 ** Access patterns 137 138 An access pattern is a specific way to access the data. For the moment, two 139 access patterns are foreseen: equally sized chunked or single buffer. 140 141 A "chunk" may be termed differently. For example, most big number 142 technologies implement them in arrays of limbs, where each limb is a C 143 language integer of some kind, and some of these technologies also allows 144 direct (read) access to those limbs. Those limbs can be regarded and 145 treated as "chunks". 146 147 ** Functions 148 149 *** Common 150 151 - *Get Meta-Data*: Returns meta-data items, given a selection identity and a 152 meta-data identity (also a number). The diverse possible meta-data is 153 covered below. Some common meta-data are: 154 155 - *Direction*: /[Supported for big numbers]/ 156 - 0: LSB first (little endian) 157 - 1: MSB first (bit endian) 158 159 - *Sign*: /[Supported for big numbers]/ 160 161 The sign associated with the data. May be one the the following values: 162 - -1: Negative 163 - 1: Positive 164 - 0: Embedded in the highest bit of the data, interpretted as a 2's 165 complement sign. 166 167 - *Patterns*: /[Supported for [[*Getter][getters]] and [[*Setter][setters]]]/ 168 169 An integer that's the combination of bits to represent what access 170 patterns are supported. For each known access pattern, the access pattern 171 identity acts as a bit number. 172 173 *** Getter 174 175 - For the single buffer access pattern: 176 177 - Additional possible Meta-data items: 178 179 - *Size*: The size that the data would take up in an export buffer. 180 181 - *Get Export*: Given a pointer to a buffer, exports all the data into it. 182 183 - For the chunked access pattern: 184 185 - Possible Meta-data items: 186 187 - *Chunks*: The amount of chunks 188 - *Chunk Direction*: /[Supported for big numbers]/ Like the general 189 *Direction*, but specifically for the chunks. 190 - *Chunk Size*: The size of each chunk in bytes. 191 192 - *Get Chunk*: Given a chunk index, returns that chunk. 193 194 *** Setter 195 196 - For the single buffer access pattern: 197 198 - Additional possible Meta-data items: 199 200 - *Size*: The maximum size that the data may take up in an export 201 buffer. 202 203 - *Set Export*: Given a pointer to a buffer and a pointer to a size 204 variable, exports all the data into the buffer and sets the size 205 of the data to the size variable.. 206 207 - For the chunked access pattern: 208 209 - Possible Meta-data items: 210 211 - *Chunks*: The amount of chunks 212 - *Chunk Direction*: /[Supported for big numbers]/ Like the general 213 *Direction*, but specifically for the chunks. 214 - *Chunk Size*: The size of each chunk in bytes. 215 216 - *Set Chunk*: Given a chunk index, sets that chunk. 217 218 *** Parser 219 220 TBA 221 222 * Callbacks 223 224 There are going to be a need for callbacks. For example, the parameter sets 225 are read-only, which means that they can be used to pass diverse data down a 226 call chain, but not to receive data up a command chain. An easy way to 227 solve that is for a function to call a callback to pass data back to the 228 caller. 229 230 With any callback function pointer that's passed down, it should always be 231 possible to also pass down an application data pointer as well. 232 233 The callback type should look approximately like this: 234 235 #+begin_src C 236 typedef struct { 237 LE_STATUS (*cb_fn)(LSC_param_t *p, void *cb_arg); 238 void *cb_arg; 239 } LSC_callback_t; 240 #+end_src 241 242 ~LSC_param_t~ is thought to be the type for a set of [[*Parameters][parameters]], which 243 serves as generic input for the callback.