Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example_pointer_boundary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func ExampleTemporalFromPointer() {
// 3 <nil> Sequence <nil>
}

func ExampleTemporal_Pointer() {
func Example_temporalPointer() {
tb := NewTBoolSeq("{FALSE@2022-10-01, TRUE@2022-10-03}")
crossed := functions.TemporalFromPointer(unsafe.Pointer(tb.Inner()))

Expand Down
19 changes: 14 additions & 5 deletions example_types_io_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ package gomeos
// example_pointer_boundary_test.go does, through the pointer both share.

import (
"bytes"
"fmt"
"unsafe"

"github.com/MobilityDB/GoMEOS/types"
)
Expand All @@ -30,24 +30,33 @@ func ExampleTGeomPointFromEWKT() {

func ExampleTGeomPointFromHexEWKB() {
point, _ := types.TGeomPointFromEWKT("SRID=4326;Point(1 1)@2024-12-06")
var size uint64 // the size_t the writer states the length in
hex, _ := point.AsHexEWKB(0, unsafe.Pointer(&size))
hex, _ := point.AsHexEWKB(0)
read, err := types.TGeomPointFromHexEWKB(hex)
fmt.Println(read, err)
// Output:
// POINT(1 1)@2024-12-06 00:00:00+00 <nil>
}

func ExampleCbuffer_String() {
func Example_cbufferString() {
cbuffer, _ := types.CbufferFromText("Cbuffer(Point(1 1),0.5)")
fmt.Println(cbuffer)
// Output:
// Cbuffer(POINT(1 1),0.5)
}

func ExampleFloatSpan_String() {
func Example_floatSpanString() {
span, _ := types.FloatSpanFromText("[8, 10]")
fmt.Println(span)
// Output:
// [8, 10]
}

func Example_temporalEWKB() {
point, _ := types.TGeomPointFromEWKT("SRID=4326;Point(1 1)@2024-12-06")
wkb, err := point.AsEWKB(0)
read, _ := types.TGeomPointFromEWKB(wkb)
again, _ := read.AsEWKB(0)
fmt.Println(len(wkb) > 0, err, bytes.Equal(wkb, again), read)
// Output:
// true <nil> true POINT(1 1)@2024-12-06 00:00:00+00
}
19 changes: 18 additions & 1 deletion functions/cgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package functions
#cgo linux CFLAGS: -I/usr/include/h3

#include <stddef.h>
#include <stdlib.h>
#include "meos.h"
#include "meos_catalog.h"
#include "meos_cbuffer.h"
Expand Down Expand Up @@ -50,7 +51,23 @@ package functions
*/
import "C"

import "fmt"
import (
"fmt"
"unsafe"
)

// TakeBytes copies the n bytes a MEOS writer answered at p into Go memory and
// frees MEOS's buffer, as every wrapper answering a char * frees it once
// C.GoString has copied it (#_free_returned_string): the byte buffer of a WKB
// writer, whose length MEOS states through its size_t * out-parameter, becomes
// a []byte the caller owns. A nil buffer answers nil.
func TakeBytes(p unsafe.Pointer, n uint64) []byte {
if p == nil {
return nil
}
defer C.free(p)
return C.GoBytes(p, C.int(n))
}

// MeosError reports that the MEOS call behind a wrapper failed, carrying the
// error code MEOS recorded for it.
Expand Down
19 changes: 18 additions & 1 deletion tools/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -1166,11 +1166,28 @@ def _todo_stub(c_name: str, reason: str) -> str:
#cgo linux CFLAGS: -I/usr/include/h3

#include <stddef.h>
#include <stdlib.h>
@INCLUDES@
*/
import "C"

import "fmt"
import (
"fmt"
"unsafe"
)

// TakeBytes copies the n bytes a MEOS writer answered at p into Go memory and
// frees MEOS's buffer, as every wrapper answering a char * frees it once
// C.GoString has copied it (#_free_returned_string): the byte buffer of a WKB
// writer, whose length MEOS states through its size_t * out-parameter, becomes
// a []byte the caller owns. A nil buffer answers nil.
func TakeBytes(p unsafe.Pointer, n uint64) []byte {
if p == nil {
return nil
}
defer C.free(p)
return C.GoBytes(p, C.int(n))
}

// MeosError reports that the MEOS call behind a wrapper failed, carrying the
// error code MEOS recorded for it.
Expand Down
44 changes: 43 additions & 1 deletion tools/objectgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,42 @@ def method_for(self, cls: str, entry: dict) -> str | None:
if params and self.class_of_handle(params[0][1]) in family:
recv = params.pop(0)

# A byte buffer travels as a []byte, as MEOS.NET's method_for reads the
# catalog's shape: a `size_t *` the shape lists in `outParams` states the
# length of the buffer the call answers, so it leaves the signature and
# the buffer comes back as a []byte (functions.TakeBytes); a `uint8_t`
# array the shape lists in `inputArrays` is taken as a []byte, the
# parameter its length comes from filled with len().
shape = f.get("shape") or {}
length_out = next(
(codegen._go_param_name(p["name"]) for p in f.get("params", [])
if p["name"] in (shape.get("outParams") or [])
and p["cType"].replace(" ", "") == "size_t*"), None)
byte_inputs = {
codegen._go_param_name(a["param"]): codegen._go_param_name(a["lengthFrom"]["name"])
for a in shape.get("inputArrays") or []
if (a.get("element") or {}).get("c") == "uint8_t"
and (a.get("lengthFrom") or {}).get("kind") == "param"}
length_of = {length: arr for arr, length in byte_inputs.items()}
prelude = []

args, decl = [], []
for pname, ptype in params:
if pname == length_out:
prelude.append("\tvar _size uint64")
args.append("unsafe.Pointer(&_size)")
continue
if pname in byte_inputs:
local = f"_p_{pname}"
prelude.append(f"\tvar {local} unsafe.Pointer\n"
f"\tif len({ident(pname)}) > 0 {{\n"
f"\t\t{local} = unsafe.Pointer(&{ident(pname)}[0])\n\t}}")
decl.append(f"{ident(pname)} []byte")
args.append(local)
continue
if pname in length_of:
args.append(f"{self.qualify(ptype)}(len({ident(length_of[pname])}))")
continue
mapped = self.map_param(ptype, ident(pname))
if mapped is None:
self.deferred[cls].append(f"{oo}: parameter {pname} is {ptype}")
Expand Down Expand Up @@ -341,11 +375,19 @@ def method_for(self, cls: str, entry: dict) -> str | None:
folded = (len(sig.returns) == 2 and sig.returns[0] == "bool"
and f["returnType"]["c"].replace("const ", "").strip() == "bool")

rets, body = [], []
rets, body = [], list(prelude)
call = f"functions.{sig.go_name}({', '.join(args)})"
answers_bytes = (length_out is not None and sig.returns == ["unsafe.Pointer"]
and f["returnType"]["c"].replace("const ", "").replace(" ", "")
== "uint8_t*")

if not sig.returns:
body.append(f"\treturn {call}")
elif answers_bytes:
rets = ["[]byte"]
body.append(f"\t_r0, _err := {call}")
body.append("\tif _err != nil {\n\t\treturn nil, _err\n\t}")
body.append("\treturn functions.TakeBytes(_r0, _size), nil")
elif folded:
mapped = self.map_return(sig.returns[1], "_value")
if mapped is None:
Expand Down
4 changes: 2 additions & 2 deletions types/bigintset.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions types/bigintspan.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions types/bigintspanset.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 22 additions & 14 deletions types/cbuffer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions types/cbufferset.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions types/dateset.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions types/datespan.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions types/datespanset.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions types/floatset.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions types/floatspan.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions types/floatspanset.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading