Skip to content

Commit

Permalink
#418 Support nested replicator queries, path transposing
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Dec 3, 2015
1 parent 18212e8 commit d5791ce
Show file tree
Hide file tree
Showing 12 changed files with 325 additions and 79 deletions.
36 changes: 17 additions & 19 deletions packages/corto/lang/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ attributes for all subsequently created objects in the thread from which the
function is called. By default the attribute is set to `ATTR_DEFAULT`.
The `corto_checkAttr` function can be used to check which attributes are enabled
for an object. The following example checks whether an object is SCOPED:

```
if (corto_checkAttr(o, CORTO_ATTR_SCOPED)) {
printf("name of o is %s\n", corto_nameof(o));
Expand Down Expand Up @@ -147,7 +146,6 @@ will validate that all methods of an implemented interface are implemented by
the class. Any composite type can be used as an interface. Interface variables
require run time type information to invoke interface methods, which is why this
behavior can only be implemented on reference types.

An example of a class that implements the `dispatcher` interface (notice that
implements expects a sequence of interfaces):

Expand Down Expand Up @@ -244,12 +242,6 @@ Enables construction of collection types.
### compatible(type type)
#### type
#### Returns
### elementRequiresAlloc()
Returns whether memory has to be allocated to accommodate for a new element.
Arrays and sequences will always return false, since memory for elements is
allocated in a consecutive block. Lists and maps require allocations for
value types as element type that are larger than the size of a word.
#### Returns
### elementType
The type of which the elements in a collection will be. Depending on the kind
of collection, elements might require allocation. The `elementRequiresAlloc`
Expand All @@ -261,6 +253,9 @@ Specifies the kind of collection. See `collectionKind` for a more detailed
description of the available options.
### max
The maximum number of elements for a given collection type.
### requiresAlloc(type elementType)
#### elementType
#### Returns
### size()
#### Returns

Expand Down Expand Up @@ -549,9 +544,6 @@ Enables quick lookups of interface methods.
## interfaceVectorseq
Sequence of interfaceVector elements.

## invokeAction
Delegate used by replicators to forward calls.

## invokeEvent
Event used by delegates to forward calls.
### args
Expand Down Expand Up @@ -877,11 +869,20 @@ Base for classes that replicate data between datasources.
#### observable
### on_update
#### observable
### onDeclare
### onDelete
### onInvoke
### onRequest
### onUpdate
### onDeclare(object observable)
#### observable
### onDelete(object observable)
#### observable
### onInvoke(object instance,function proc,octetseq args)
#### instance
#### proc
#### args
### onRequest(string parent,string expr)
#### parent
#### expr
#### Returns
### onUpdate(object observable)
#### observable
### post(event e)
#### e
### query
Expand All @@ -890,8 +891,6 @@ Base for classes that replicate data between datasources.
#### expr
#### Returns

## requestAction

## result
### name
### parent
Expand Down Expand Up @@ -925,7 +924,6 @@ if (corto_define(i)) {
} else {
// ok: i is DEFINED
}
corto_delete(i);
// i is DESTRUCTED and may no longer point to valid memory
Expand Down
6 changes: 4 additions & 2 deletions packages/corto/lang/include/corto_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,14 @@ void* corto_llLast(corto_ll list);
/* Get listsize */
int corto_llSize(corto_ll list);

/* Obtain iterator */
/* Obtain regular iterator, not valid outside scope of origin. */
#define corto_llIter(list) _corto_llIter(list, alloca(sizeof(corto_llIter_s)));

corto_iter _corto_llIter(corto_ll, void *udata);

/* Obtain persistent iterator. Requries corto_iterRelease to be called */
corto_iter corto_llIterAlloc(corto_ll);

/* Iterator cleanup functions */
void corto_llIterRelease(corto_iter *iter);

/* Append one list to another */
Expand Down
1 change: 1 addition & 0 deletions packages/corto/lang/include/corto_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ void corto_scopeRelease(corto_objectseq scope);
corto_int16 corto_scopeWalk(corto_object o, corto_scopeWalkAction action, void *userData);
corto_string corto_fullname(corto_object o, corto_id buffer);
corto_string corto_relname(corto_object from, corto_object o, corto_id buffer);
corto_string corto_cleanpath(corto_id path);

/* Persistent data */
corto_object corto_ownerof(corto_object o);
Expand Down
8 changes: 4 additions & 4 deletions packages/corto/lang/include/corto_replicator.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ CORTO_LANG_EXPORT void _corto_replicator_onInvoke(corto_replicator _this, corto_
CORTO_LANG_EXPORT corto_void _corto_replicator_onInvoke_v(corto_replicator _this, corto_object instance, corto_function proc, corto_octetseq args);
#define corto_replicator_onInvoke_v(_this, instance, proc, args) _corto_replicator_onInvoke_v(corto_replicator(_this), instance, corto_function(proc), args)

/* virtual /corto/lang/replicator/onRequest(object parent,string expr) */
CORTO_LANG_EXPORT corto_resultIter _corto_replicator_onRequest(corto_replicator _this, corto_object parent, corto_string expr);
/* virtual /corto/lang/replicator/onRequest(string parent,string expr) */
CORTO_LANG_EXPORT corto_resultIter _corto_replicator_onRequest(corto_replicator _this, corto_string parent, corto_string expr);
#define corto_replicator_onRequest(_this, parent, expr) _corto_replicator_onRequest(corto_replicator(_this), parent, expr)

CORTO_LANG_EXPORT corto_resultIter _corto_replicator_onRequest_v(corto_replicator _this, corto_object parent, corto_string expr);
CORTO_LANG_EXPORT corto_resultIter _corto_replicator_onRequest_v(corto_replicator _this, corto_string parent, corto_string expr);
#define corto_replicator_onRequest_v(_this, parent, expr) _corto_replicator_onRequest_v(corto_replicator(_this), parent, expr)

/* virtual /corto/lang/replicator/onUpdate(object observable) */
Expand All @@ -69,7 +69,7 @@ CORTO_LANG_EXPORT corto_void _corto_replicator_onUpdate_v(corto_replicator _this
CORTO_LANG_EXPORT corto_void _corto_replicator_post(corto_replicator _this, corto_event e);
#define corto_replicator_post(_this, e) _corto_replicator_post(corto_replicator(_this), corto_event(e))

CORTO_LANG_EXPORT corto_resultIter _corto_replicator_request(corto_replicator _this, corto_object parent, corto_string expr);
CORTO_LANG_EXPORT corto_resultIter _corto_replicator_request(corto_replicator _this, corto_string parent, corto_string expr);
#define corto_replicator_request(_this, parent, expr) _corto_replicator_request(corto_replicator(_this), parent, expr)

#ifdef __cplusplus
Expand Down
4 changes: 2 additions & 2 deletions packages/corto/lang/src/corto__bootstrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -1023,9 +1023,9 @@ CORTO_CLASS_NOBASE_O(replicator, NULL, CORTO_DECLARED | CORTO_DEFINED, NULL, NUL
CORTO_METHOD_O(replicator, destruct, "()", void, FALSE, corto_replicator_destruct);
CORTO_METHOD_O(replicator, post, "(event e)", void, FALSE, corto_replicator_post);
CORTO_METHOD_O(replicator, invoke, "(object instance,function proc,octetseq args)", void, FALSE, corto_replicator_invoke);
CORTO_METHOD_O(replicator, request, "(object parent,string expr)", resultIter, FALSE, corto_replicator_request);
CORTO_METHOD_O(replicator, request, "(string parent,string expr)", resultIter, FALSE, corto_replicator_request);
CORTO_METHOD_O(replicator, onInvoke, "(object instance,function proc,octetseq args)", void, TRUE, corto_replicator_onInvoke_v);
CORTO_METHOD_O(replicator, onRequest, "(object parent,string expr)", resultIter, TRUE, corto_replicator_onRequest_v);
CORTO_METHOD_O(replicator, onRequest, "(string parent,string expr)", resultIter, TRUE, corto_replicator_onRequest_v);
CORTO_METHOD_O(replicator, onDeclare, "(object observable)", void, TRUE, corto_replicator_onDeclare_v);
CORTO_METHOD_O(replicator, onUpdate, "(object observable)", void, TRUE, corto_replicator_onUpdate_v);
CORTO_METHOD_O(replicator, onDelete, "(object observable)", void, TRUE, corto_replicator_onDelete_v);
Expand Down
18 changes: 9 additions & 9 deletions packages/corto/lang/src/corto__wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1154,8 +1154,8 @@ void __corto_replicator_onInvoke_v(corto_function f, void *result, void *args) {
*(corto_octetseq*)((intptr_t)args + sizeof(void*) + sizeof(corto_object) + sizeof(corto_function)));
}

/* virtual /corto/lang/replicator/onRequest(object parent,string expr) */
corto_resultIter _corto_replicator_onRequest(corto_replicator this, corto_object parent, corto_string expr) {
/* virtual /corto/lang/replicator/onRequest(string parent,string expr) */
corto_resultIter _corto_replicator_onRequest(corto_replicator this, corto_string parent, corto_string expr) {
static corto_uint32 _methodId;
corto_method _method;
corto_resultIter _result;
Expand All @@ -1165,13 +1165,13 @@ corto_resultIter _corto_replicator_onRequest(corto_replicator this, corto_object

/* Determine methodId once, then cache it for subsequent calls. */
if (!_methodId) {
_methodId = corto_interface_resolveMethodId(_abstract, "onRequest(object parent,string expr)");
_methodId = corto_interface_resolveMethodId(_abstract, "onRequest(string parent,string expr)");
}
corto_assert(_methodId, "virtual method 'onRequest(object parent,string expr)' not found in interface '%s'", corto_nameof(_abstract));
corto_assert(_methodId, "virtual method 'onRequest(string parent,string expr)' not found in interface '%s'", corto_nameof(_abstract));

/* Lookup method-object. */
_method = corto_interface_resolveMethodById(_abstract, _methodId);
corto_assert(_method != NULL, "unresolved method '%s::onRequest(object parent,string expr)@%d'", corto_nameof(this), _methodId);
corto_assert(_method != NULL, "unresolved method '%s::onRequest(string parent,string expr)@%d'", corto_nameof(this), _methodId);

corto_call(corto_function(_method), &_result, this, parent, expr);

Expand All @@ -1182,8 +1182,8 @@ void __corto_replicator_onRequest_v(corto_function f, void *result, void *args)
CORTO_UNUSED(f);
*(corto_resultIter*)result = _corto_replicator_onRequest_v(
corto_replicator(*(void**)args),
*(corto_object*)((intptr_t)args + sizeof(void*)),
*(corto_string*)((intptr_t)args + sizeof(void*) + sizeof(corto_object)));
*(corto_string*)((intptr_t)args + sizeof(void*)),
*(corto_string*)((intptr_t)args + sizeof(void*) + sizeof(corto_string)));
}

/* virtual /corto/lang/replicator/onUpdate(object observable) */
Expand Down Expand Up @@ -1227,8 +1227,8 @@ void __corto_replicator_request(corto_function f, void *result, void *args) {
CORTO_UNUSED(f);
*(corto_resultIter*)result = _corto_replicator_request(
corto_replicator(*(void**)args),
*(corto_object*)((intptr_t)args + sizeof(void*)),
*(corto_string*)((intptr_t)args + sizeof(void*) + sizeof(corto_object)));
*(corto_string*)((intptr_t)args + sizeof(void*)),
*(corto_string*)((intptr_t)args + sizeof(void*) + sizeof(corto_string)));
}

void __corto_sequence_construct(corto_function f, void *result, void *args) {
Expand Down
78 changes: 78 additions & 0 deletions packages/corto/lang/src/corto_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -1743,6 +1743,84 @@ corto_string corto_relname(corto_object from, corto_object o, corto_id buffer) {
return buffer;
}

static char *strsep(char **str, char delim) {
char *result = *str;
if (result) {
char *ptr = strchr(result, delim);
if (ptr) {
*ptr = 0;
(*str) = ptr + 1;
} else {
*str = NULL;
}
}
return result;
}

corto_string corto_cleanpath(corto_id path) {
corto_id work;
char *cp, *thisp, *nextp = work;
corto_id buf;

cp = strchr(path, '/');

/* no '/' characters - return as-is */
if (cp == NULL) {
strcpy(buf, (path[0] != '\0' ? path : "."));
strcpy(path, buf);
return path;
}

/* copy leading slash if present */
if (cp == path) {
strcpy(buf, "/");
} else {
buf[0] = '\0';
}

/* tokenization */
strcpy(work, path);
while ((thisp = strsep(&nextp, '/')) != NULL) {
if (*thisp == '\0') continue;

if (strcmp(thisp, ".") == 0) continue;

if (strcmp(thisp, "..") == 0) {
cp = strrchr(buf, '/');

/* "/" or "/foo" */
if (cp == buf) {
buf[1] = '\0';
continue;
}

/* "..", "foo", or "" */
else if (cp == NULL) {
if (buf[0] != '\0' && strcmp(buf, "..") != 0) {
buf[0] = '\0';
continue;
}
}
/* ".../foo" */
else {
*cp = '\0';
continue;
}
}

if (buf[0] != '\0' && buf[strlen(buf) - 1] != '/') {
strcat(buf, "/");
}

strcat(buf, thisp);
}

if (buf[0] == '\0') strcpy(buf, ".");
strcpy(path, buf);

return path;
}

corto_object corto_ownerof(corto_object o) {
corto__object* _o;
corto__persistent* persistent;
Expand Down
4 changes: 2 additions & 2 deletions packages/corto/lang/src/corto_replicator.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ corto_void _corto_replicator_onInvoke_v(corto_replicator this, corto_object inst
/* $end */
}

corto_resultIter _corto_replicator_onRequest_v(corto_replicator this, corto_object parent, corto_string expr) {
corto_resultIter _corto_replicator_onRequest_v(corto_replicator this, corto_string parent, corto_string expr) {
/* $begin(corto/lang/replicator/onRequest) */
corto_resultIter result;

Expand Down Expand Up @@ -181,7 +181,7 @@ corto_void _corto_replicator_post(corto_replicator this, corto_event e) {
/* $end */
}

corto_resultIter _corto_replicator_request(corto_replicator this, corto_object parent, corto_string expr) {
corto_resultIter _corto_replicator_request(corto_replicator this, corto_string parent, corto_string expr) {
/* $begin(corto/lang/replicator/request) */
return corto_replicator_onRequest(this, parent, expr);
/* $end */
Expand Down
Loading

0 comments on commit d5791ce

Please sign in to comment.