forked from hdczsf/51degrees.go
-
Notifications
You must be signed in to change notification settings - Fork 3
/
lib.go
102 lines (84 loc) · 2.96 KB
/
lib.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
package fiftyonedegrees
/*
#cgo CFLAGS: -I . -Wimplicit-function-declaration
#cgo darwin LDFLAGS: -lm
#cgo linux LDFLAGS: -lm -lrt
#include "51Degrees.h"
#include <stdlib.h>
*/
import "C"
import (
"errors"
"fmt"
"unsafe"
)
type FiftyoneDegreesProvider struct {
provider *C.fiftyoneDegreesProvider
}
type FiftyoneDegreesDataSet struct {
dataSet *C.fiftyoneDegreesDataSet
}
func NewFiftyoneDegreesProvider(fileName string, properties string, poolSize int, cacheSize int) (*FiftyoneDegreesProvider, error) {
item := &FiftyoneDegreesProvider{
provider: new(C.fiftyoneDegreesProvider),
}
if poolSize == 0 {
poolSize = 10
}
if cacheSize == 0 {
cacheSize = 1000
}
var cFileName *C.char = C.CString(fileName)
defer C.free(unsafe.Pointer(cFileName))
var cProperties *C.char = C.CString(properties)
defer C.free(unsafe.Pointer(cProperties))
status := C.fiftyoneDegreesInitProviderWithPropertyString(cFileName, item.provider, cProperties, C.int(poolSize), C.int(cacheSize))
// e_fiftyoneDegrees_DataSetInitStatus.DATA_SET_INIT_STATUS_SUCCESS == 0
if status != 0 {
return nil, errors.New(fmt.Sprintln("InitWithPropertyString Error,Status:", status))
}
return item, nil
}
func (fdp *FiftyoneDegreesProvider) Close() {
C.fiftyoneDegreesProviderFree(fdp.provider)
}
func (fdp *FiftyoneDegreesProvider) Parse(userAgent string) string {
ws := C.fiftyoneDegreesProviderWorksetGet(fdp.provider)
defer C.fiftyoneDegreesWorksetRelease(ws)
// needs to be done outside of the inline function call so CGo explicitly frees the memory
var cUserAgent *C.char = C.CString(userAgent)
defer C.free(unsafe.Pointer(cUserAgent))
C.fiftyoneDegreesMatch(ws, cUserAgent)
resultLength := 50000
buff := make([]byte, resultLength)
length := int32(C.fiftyoneDegreesProcessDeviceJSON(ws, (*C.char)(unsafe.Pointer(&buff[0]))))
result := buff[:length]
return string(result)
}
func NewFiftyoneDegreesDataSet(fileName, properties string) (*FiftyoneDegreesDataSet, error) {
var cFileName *C.char = C.CString(fileName)
defer C.free(unsafe.Pointer(cFileName))
var cProperties *C.char = C.CString(properties)
defer C.free(unsafe.Pointer(cProperties))
fdds := &FiftyoneDegreesDataSet{dataSet: new(C.fiftyoneDegreesDataSet)}
status := C.fiftyoneDegreesInitWithPropertyString(cFileName, fdds.dataSet, cProperties)
if status != 0 {
return nil, errors.New(fmt.Sprintln("InitWithPropertyString Error,Status:", status))
}
return fdds, nil
}
func (fdds *FiftyoneDegreesDataSet) Close() {
C.fiftyoneDegreesDestroy(fdds.dataSet)
}
func (fdds *FiftyoneDegreesDataSet) Parse(userAgent string) string {
ws := C.fiftyoneDegreesCreateWorkset(fdds.dataSet)
defer C.fiftyoneDegreesFreeWorkset(ws)
var cUserAgent *C.char = C.CString(userAgent)
defer C.free(unsafe.Pointer(cUserAgent))
C.fiftyoneDegreesMatch(ws, cUserAgent)
resultLength := 50000
buff := make([]byte, resultLength)
length := int32(C.fiftyoneDegreesProcessDeviceJSON(ws, (*C.char)(unsafe.Pointer(&buff[0]))))
result := buff[:length]
return string(result)
}