Skip to content
Browse files

tempCString utility

`tempCString` produces C string for given string. Result is wrapped
in CStringHolder record.

If input is already a C string, then input is simply stored in a
POD CStringHolder.

If input is a string but not a C string, then memory for C string
is allocated, string data is copied to that string, and allocated
C string is stored in CStringHolder record.  In this case CStringHolder
owns cstring reference and releases it on destroy.

tempCString is convenient to call C API functions that accept C
strings. Code example:

```
mysqlConnect(host: Pointer[Byte]) { ... }

[S when String?(S)]
myCode(host: S) = mysqlConnect(tempCString(host).ptr);
```

Currently memory is allocated using malloc. Later tempCString may
be rewritten to allocate memory in a thread-local fixed size memory
chunk pool (in this case the cost of memory allocation will be
comparable to `alloca`).
  • Loading branch information...
1 parent fa7b282 commit a20c2155f474578fae70f96a3c8f01cea5e664cc @stepancheg stepancheg committed Nov 10, 2012
Showing with 46 additions and 0 deletions.
  1. +46 −0 lib-clay/data/strings/tempcstrings/tempcstrings.clay
View
46 lib-clay/data/strings/tempcstrings/tempcstrings.clay
@@ -0,0 +1,46 @@
+import data.strings.*;
+
+
+[Owned when Type(Owned) == Bool]
+record CStringHolder[Owned] (
+ cstring: CStringRef,
+);
+
+[Owned]
+overload fieldRef(s: CStringHolder[Owned], #"ptr") = s.cstring.ptr;
+
+[Owned]
+overload PODType?(#CStringHolder[Owned]) = false;
+[Owned]
+overload RegularRecord?(#CStringHolder[Owned]) = false;
+[Owned]
+overload BitwiseMovedType?(#CStringHolder[Owned]) = true;
+
+[Owned]
+overload resetUnsafe(s: CStringHolder[Owned]) {
+ s.cstring = CStringRef();
+}
+
+[Owned]
+overload destroy(holder: CStringHolder[Owned]) {
+ if (#Owned) {
+ libc.free(holder.cstring.ptr);
+ }
+}
+
+staticassert( Movable?(CStringHolder[ #true]));
+staticassert(not Copyable?(CStringHolder[ #true]));
+staticassert( Movable?(CStringHolder[#false]));
+staticassert(not Copyable?(CStringHolder[#false]));
+
+[S when String?(S)]
+tempCString(s: S) {
+ if (#CCompatibleString?(S)) {
+ return CStringHolder[#false](CStringRef(s));
+ } else {
+ var string = String(s);
+ cstring(string); // add trailing \0
+ return CStringHolder[ #true](CStringRef(moveVectorBuffer(string)));
+ }
+}
+

0 comments on commit a20c215

Please sign in to comment.
Something went wrong with that request. Please try again.