forked from PhillP/golibrdf
/
uri.go
193 lines (146 loc) · 5.31 KB
/
uri.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*
*
* This file forms part of the golibrdf package containing go language bindings,
* tests and examples for the Redland RDF library.
*
* Please refer to http://librdf.org for copyright and licence information
* on the Redland libraries that this package wraps
*
* This golibrdf package is:
* Copyright (C) 2013, Phillip Pettit http://ppettit.net/
*
* This package is licensed under the following three licenses as alternatives:
* 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
* 2. GNU General Public License (GPL) V2 or any newer version
* 3. Apache License, V2.0 or any newer version
*
* You may not use this file except in compliance with at least one of
* the above three licenses.
*
*/
package golibrdf
// #cgo linux pkg-config: redland raptor2
// #cgo LDFLAGS: -lrdf
// #include <stdlib.h>
// #include <string.h>
// #include <strings.h>
// #include <librdf.h>
import "C"
import (
"errors"
"runtime"
"unsafe"
)
//Represents a URI
type Uri struct {
librdf_uri *C.librdf_uri
}
//NewUri constructs a new URI given a string
func NewUri(world *World, uriString string) (*Uri, error) {
uri, err := newUriWithoutFinaliser(world, uriString)
if uri != nil {
runtime.SetFinalizer(uri, (*Uri).Free)
}
return uri, err
}
//newUriWithoutFinaliser constructs a new URI given a string, but does not associate a finalizer for automatic free
func newUriWithoutFinaliser(world *World, uriString string) (*Uri, error) {
uri := new(Uri)
cUriString := C.CString(uriString)
defer C.free(unsafe.Pointer(cUriString))
uri.librdf_uri = C.librdf_new_uri(world.librdf_world, (*C.uchar)(unsafe.Pointer(cUriString)))
if uri.librdf_uri == nil {
return nil, errors.New("Unable to create URI for uri string")
}
return uri, nil
}
//Free cleans up memory resources held by the Uri
// Free will be automatically called when Uri instances are garbage collected
// however it is important to explicitly call Free to avoid issues that may result
// from freeing resources in an unexpected order
func (uri *Uri) Free() {
if uri.librdf_uri != nil {
C.librdf_free_uri(uri.librdf_uri)
uri.librdf_uri = nil
}
return
}
//ToString serializers a URI to string
func (uri Uri) ToString() string {
cUriString := C.librdf_uri_as_string(uri.librdf_uri)
defer C.free(unsafe.Pointer(cUriString))
return C.GoString((*C.char)(unsafe.Pointer(cUriString)))
}
//NewUriFromUri constructs a new URI given an existing URI
func NewUriFromUri(fromUri *Uri) (*Uri, error) {
var err error
uri := new(Uri)
uri.librdf_uri = C.librdf_new_uri_from_uri(fromUri.librdf_uri)
runtime.SetFinalizer(uri, (*Uri).Free)
return uri, err
}
//NewUriFromUri constructs a new URI given an existing URI and a localName
func NewUriFromUriLocalName(fromUri *Uri, localName string) (*Uri, error) {
var err error
cLocalName := C.CString(localName)
defer C.free(unsafe.Pointer(cLocalName))
uri := new(Uri)
uri.librdf_uri = C.librdf_new_uri_from_uri_local_name(fromUri.librdf_uri, (*C.uchar)(unsafe.Pointer(cLocalName)))
runtime.SetFinalizer(uri, (*Uri).Free)
return uri, err
}
//NewUriFromUri constructs a new URI given an existing URI normalised to the specified baseUri
func NewUriNormalisedBase(uriString string, sourceUri *Uri, baseUri *Uri) (*Uri, error) {
var err error
cUriString := C.CString(uriString)
defer C.free(unsafe.Pointer(cUriString))
uri := new(Uri)
uri.librdf_uri = C.librdf_new_uri_normalised_to_base((*C.uchar)(unsafe.Pointer(cUriString)), sourceUri.librdf_uri, baseUri.librdf_uri)
runtime.SetFinalizer(uri, (*Uri).Free)
return uri, err
}
//NewUriRelativeToBase constructs a new URI given a URI string made relative to the specified baseUri
func NewUriRelativeToBase(baseUri *Uri, uriString string) (*Uri, error) {
var err error
cUriString := C.CString(uriString)
defer C.free(unsafe.Pointer(cUriString))
uri := new(Uri)
uri.librdf_uri = C.librdf_new_uri_relative_to_base(baseUri.librdf_uri, (*C.uchar)(unsafe.Pointer(cUriString)))
runtime.SetFinalizer(uri, (*Uri).Free)
return uri, err
}
//NewUriFromFileName constructs a new URI for a file given a filename
func NewUriFromFileName(world *World, fileName string) (*Uri, error) {
var err error
cFileName := C.CString(fileName)
defer C.free(unsafe.Pointer(cFileName))
uri := new(Uri)
uri.librdf_uri = C.librdf_new_uri_from_filename(world.librdf_world, (*C.char)(unsafe.Pointer(cFileName)))
runtime.SetFinalizer(uri, (*Uri).Free)
return uri, err
}
//ToFileName converts a URI representing a file to a filename
func (uri *Uri) ToFileName() (string, error) {
var err error
cFileName := C.librdf_uri_to_filename(uri.librdf_uri)
defer C.free(unsafe.Pointer(cFileName))
fileName := C.GoString((*C.char)(unsafe.Pointer(cFileName)))
return fileName, err
}
//IsFileUri tests whether a URI represents a file or not.
func (uri *Uri) IsFileUri() bool {
cIsFileUri := int(C.librdf_uri_is_file_uri(uri.librdf_uri))
return cIsFileUri == 0
}
//Equals compares 2 URIs and returns true if they are equal
func (uri *Uri) Equals(other *Uri) bool {
cEquals := int(C.librdf_uri_equals(uri.librdf_uri, other.librdf_uri))
return cEquals == 0
}
//Compare compares 2 URIs
// Returns <0 if the URI instance is less than other
// Returns >0 if the URI instance is greater than other
// Returns 0 if the URIs are equal
func (uri *Uri) Compare(other *Uri) int {
return int(C.librdf_uri_compare(uri.librdf_uri, other.librdf_uri))
}