/ 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.