summaryrefslogtreecommitdiff
path: root/rawobject.nobj.lua
blob: 6f1415683f38560145f80543e7dbff4b61fb6b7a (plain)
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
-- Copyright (c) 2010 by Robert G. Jakabosky <bobby@sharedrealm.com>
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-- THE SOFTWARE.

c_source [[
typedef struct RawObject {
	git_rawobj git;
	int ref;
} RawObject;

static void RawObject_set_data_and_ref(lua_State *L, RawObject *raw, const char *data, int len, int idx) {
	/* Release old reference. */
	if(raw->ref != LUA_REFNIL) {
		luaL_unref(L, LUA_REGISTRYINDEX, raw->ref);
	}
	raw->git.data = (void *)data;
	raw->git.len = len;
	if(data) {
		/* Get a reference to the Lua string. */
		lua_pushvalue(L, idx);
		raw->ref = luaL_ref(L, LUA_REGISTRYINDEX);
	} else {
		raw->ref = LUA_REFNIL;
	}
}

static void RawObject_from_git_rawobj(lua_State *L, RawObject *raw, const git_rawobj *git) {
  /* push raw object's data onto stack. */
  lua_pushlstring(L, git->data, git->len);
  /* get Lua's pointer to the string. */
  raw->git.data = (void *)lua_tolstring(L, -1, &(raw->git.len));
  raw->git.type = git->type;
  /* get reference to string. */
  raw->ref = luaL_ref(L, LUA_REGISTRYINDEX);
}

]]

object "RawObject" {
	userdata_type = 'embed',
	default = 'NULL',
	constructor {
		var_in{"const char *", "type"},
		var_in{"const char *", "data"},
		c_source [[
	RawObject raw; /* temp. storage, this gets copied. */
	${this} = &(raw);
	raw.git.type = git_object_string2type(${type});
	raw.ref = LUA_REFNIL;
	RawObject_set_data_and_ref(L, &raw, ${data}, ${data}_len, ${data::idx});
]],
	},
	destructor "close" {
		c_source [[
	luaL_unref(L, LUA_REGISTRYINDEX, ${this}->ref);
	${this}->ref = LUA_REFNIL;
	${this}->git.data = NULL;
	${this}->git.len = 0;
	RawObject_set_data_and_ref(L, ${this}, NULL, 0, 0);
]],
	},
	method "data" {
		var_out{"const char *", "data", has_length = true},
		c_source [[
	/* push Lua string. */
	// TODO: add support to directly push Lua values.
	//lua_rawgeti(L, LUA_REGISTRYINDEX, ${this}->ref);
	${data} = ${this}->git.data;
	${data}_len = ${this}->git.len;
]],
	},
	method "set_data" {
		var_in{"const char *", "data"},
		c_source [[
	RawObject_set_data_and_ref(L, ${this}, ${data}, ${data}_len, ${data::idx});
]],
	},
	method "len" {
		var_out{"size_t", "len"},
		c_source [[
	${len} = ${this}->git.len;
]],
	},
	method "type" {
		var_out{"const char *", "type"},
		c_source "${type} = git_object_type2string(${this}->git.type);"
	},
	method "set_type" {
		var_in{"const char *", "type"},
		c_source "${this}->git.type = git_object_string2type(${type});"
	},
	method "hash" {
		var_out{"OID", "id"},
		var_out{"GitError", "err"},
		c_source [[
	${err} = git_rawobj_hash(&(${id}), &(${this}->git));
]],
	},
}