1+ /*
2+ * The MIT License
3+ *
4+ * Copyright (c) 2010 - 2011 Shuhei Tanuma
5+ *
6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7+ * of this software and associated documentation files (the "Software"), to deal
8+ * in the Software without restriction, including without limitation the rights
9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+ * THE SOFTWARE.
23+ */
24+
25+ #include "php_git.h"
26+ #include <spl/spl_array.h>
27+ #include <zend_interfaces.h>
28+ #include <string.h>
29+ #include <time.h>
30+
31+ PHPAPI zend_class_entry * git_reference_manager_class_entry ;
32+
33+ ZEND_BEGIN_ARG_INFO_EX (arginfo_git_reference_manager__construct , 0 , 0 , 1 )
34+ ZEND_ARG_INFO (0 , repository )
35+ ZEND_END_ARG_INFO ()
36+
37+ ZEND_BEGIN_ARG_INFO_EX (arginfo_git_reference_manager_lookup , 0 , 0 , 1 )
38+ ZEND_ARG_INFO (0 , name )
39+ ZEND_END_ARG_INFO ()
40+
41+ ZEND_BEGIN_ARG_INFO_EX (arginfo_git_reference_manager_create , 0 , 0 , 2 )
42+ ZEND_ARG_INFO (0 , name )
43+ ZEND_ARG_INFO (0 , oid )
44+ ZEND_END_ARG_INFO ()
45+
46+ static void php_git_reference_manager_free_storage (php_git_reference_manager_t * obj TSRMLS_DC )
47+ {
48+ zend_object_std_dtor (& obj -> zo TSRMLS_CC );
49+ obj -> repository = NULL ;
50+ efree (obj );
51+ }
52+
53+ zend_object_value php_git_reference_manager_new (zend_class_entry * ce TSRMLS_DC )
54+ {
55+ zend_object_value retval ;
56+ php_git_tree_entry_t * obj ;
57+ zval * tmp ;
58+
59+ obj = ecalloc (1 , sizeof (* obj ));
60+ zend_object_std_init ( & obj -> zo , ce TSRMLS_CC );
61+ zend_hash_copy (obj -> zo .properties , & ce -> default_properties , (copy_ctor_func_t ) zval_add_ref , (void * ) & tmp , sizeof (zval * ));
62+
63+ retval .handle = zend_objects_store_put (obj ,
64+ (zend_objects_store_dtor_t )zend_objects_destroy_object ,
65+ (zend_objects_free_object_storage_t )php_git_reference_manager_free_storage ,
66+ NULL TSRMLS_CC );
67+ retval .handlers = zend_get_std_object_handlers ();
68+ return retval ;
69+ }
70+
71+ PHP_METHOD (git_reference_manager , __construct )
72+ {
73+ php_git_reference_manager_t * this = (php_git_reference_manager_t * ) zend_object_store_get_object (getThis () TSRMLS_CC );
74+ zval * repository ;
75+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC ,
76+ "z" , & repository ) == FAILURE ){
77+ return ;
78+ }
79+ if (!instanceof_function (Z_OBJCE_P (repository ), git_repository_class_entry TSRMLS_CC )){
80+ zend_throw_exception_ex (spl_ce_InvalidArgumentException , 0 TSRMLS_CC ,
81+ "argument does not Git\\Repository" );
82+ RETURN_FALSE ;
83+ }
84+ php_git_repository_t * repo = (php_git_repository_t * ) zend_object_store_get_object (repository TSRMLS_CC );
85+ if (repo -> repository == NULL ){
86+ zend_throw_exception_ex (spl_ce_InvalidArgumentException , 0 TSRMLS_CC ,
87+ "repository didn't ready" );
88+ RETURN_FALSE ;
89+ }
90+ this -> repository = repo -> repository ;
91+ }
92+
93+ PHP_METHOD (git_reference_manager , getList )
94+ {
95+ php_git_reference_manager_t * this = (php_git_reference_manager_t * ) zend_object_store_get_object (getThis () TSRMLS_CC );
96+ git_strarray * list = malloc (sizeof (git_strarray ));
97+ int result ;
98+ int i = 0 ;
99+ git_reference * reference ;
100+ zval * references ;
101+ git_rtype type ;
102+ char out [GIT_OID_HEXSZ + 1 ] = {0 };
103+
104+ git_reference_listall (list ,this -> repository ,GIT_REF_LISTALL );
105+
106+ MAKE_STD_ZVAL (references );
107+ array_init (references );
108+ for (i = 0 ; i < list -> count ; i ++ ){
109+ zval * ref ;
110+
111+ // FIXME
112+ result = git_reference_lookup (& reference , this -> repository , list -> strings [i ]);
113+ if (result != GIT_SUCCESS ) {
114+ zend_throw_exception_ex (spl_ce_InvalidArgumentException , 0 TSRMLS_CC ,
115+ "Can't find specified reference." );
116+ RETURN_FALSE ;
117+ }
118+
119+ MAKE_STD_ZVAL (ref );
120+ object_init_ex (ref , git_reference_class_entry );
121+ php_git_reference_t * refobj = (php_git_reference_t * ) zend_object_store_get_object (ref TSRMLS_CC );
122+ refobj -> object = reference ;
123+
124+ add_property_string_ex (ref ,"name" , sizeof ("name" ), (char * )git_reference_name (reference ), 1 TSRMLS_CC );
125+
126+ type = git_reference_type (reference );
127+ if (type == GIT_REF_SYMBOLIC ) {
128+ const char * target = git_reference_target (reference );
129+ if (target != NULL ) {
130+ add_property_string_ex (ref ,"target" ,sizeof ("target" ),(char * )target , 1 TSRMLS_CC );
131+ }
132+ int rr = git_reference_resolve (& refobj -> object ,reference );
133+ if (rr != GIT_SUCCESS ){
134+ zend_throw_exception_ex (spl_ce_InvalidArgumentException , 0 TSRMLS_CC ,
135+ "something wrong" );
136+ RETURN_FALSE ;
137+ }
138+ }
139+
140+ git_oid_to_string (out ,GIT_OID_HEXSZ + 1 ,git_reference_oid (refobj -> object ));
141+ add_property_string_ex (ref ,"oid" ,sizeof ("oid" ),out , 1 TSRMLS_CC );
142+ memset (out ,'\0' ,GIT_OID_HEXSZ + 1 );
143+ //
144+
145+ add_next_index_zval (references , ref );
146+ }
147+
148+ git_strarray_free (list );
149+ RETURN_ZVAL (references ,0 ,0 );
150+ }
151+
152+ PHP_METHOD (git_reference_manager , pack )
153+ {
154+ php_git_reference_manager_t * this = (php_git_reference_manager_t * ) zend_object_store_get_object (getThis () TSRMLS_CC );
155+ int ret = git_reference_packall (this -> repository );
156+ if (ret != GIT_SUCCESS ){
157+ zend_throw_exception_ex (spl_ce_InvalidArgumentException , 0 TSRMLS_CC ,
158+ "an error occured while packing references. error_code: %d\n" ,ret );
159+ RETURN_FALSE ;
160+ }
161+ RETURN_TRUE ;
162+ }
163+
164+ PHP_METHOD (git_reference_manager , lookupRef )
165+ {
166+ php_git_reference_manager_t * this = (php_git_reference_manager_t * ) zend_object_store_get_object (getThis () TSRMLS_CC );
167+ char * name ;
168+ int name_len = 0 ;
169+ int result ;
170+ zval * ref ;
171+ char out [GIT_OID_HEXSZ + 1 ] = {0 };
172+ git_oid * oid ;
173+ git_rtype type ;
174+ git_reference * reference ;
175+
176+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC ,
177+ "s" , & name , & name_len ) == FAILURE ){
178+ return ;
179+ }
180+
181+ result = git_reference_lookup (& reference , this -> repository , name );
182+ if (result != GIT_SUCCESS ) {
183+ zend_throw_exception_ex (spl_ce_InvalidArgumentException , 0 TSRMLS_CC ,
184+ "Can't find specified reference." );
185+ RETURN_FALSE ;
186+ }
187+
188+ MAKE_STD_ZVAL (ref );
189+ object_init_ex (ref , git_reference_class_entry );
190+ php_git_reference_t * refobj = (php_git_reference_t * ) zend_object_store_get_object (ref TSRMLS_CC );
191+ refobj -> object = reference ;
192+
193+ add_property_string_ex (ref ,"name" , sizeof ("name" ), (char * )git_reference_name (reference ), 1 TSRMLS_CC );
194+
195+ type = git_reference_type (reference );
196+ if (type == GIT_REF_SYMBOLIC ) {
197+ const char * target = git_reference_target (reference );
198+ if (target != NULL ) {
199+ add_property_string_ex (ref ,"target" ,sizeof ("target" ),(char * )target , 1 TSRMLS_CC );
200+ }
201+ int rr = git_reference_resolve (& refobj -> object ,reference );
202+ if (rr != GIT_SUCCESS ){
203+ zend_throw_exception_ex (spl_ce_InvalidArgumentException , 0 TSRMLS_CC ,
204+ "something wrong" );
205+ RETURN_FALSE ;
206+ }
207+ }
208+
209+ git_oid_to_string (out ,GIT_OID_HEXSZ + 1 ,git_reference_oid (refobj -> object ));
210+ add_property_string_ex (ref ,"oid" ,sizeof ("oid" ),out , 1 TSRMLS_CC );
211+
212+ RETURN_ZVAL (ref ,0 ,0 );
213+ }
214+
215+ PHP_METHOD (git_reference_manager , create )
216+ {
217+ php_git_reference_manager_t * this = (php_git_reference_manager_t * ) zend_object_store_get_object (getThis () TSRMLS_CC );
218+ char * name ;
219+ int name_len = 0 ;
220+ char * oid ;
221+ int oid_len = 0 ;
222+ git_oid id ;
223+
224+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC ,
225+ "ss" , & name , & name_len , & oid , & oid_len ) == FAILURE ){
226+ return ;
227+ }
228+ if (oid_len != GIT_OID_HEXSZ ){
229+ zend_throw_exception_ex (spl_ce_InvalidArgumentException , 0 TSRMLS_CC ,
230+ "oid length seems illegal" );
231+ RETURN_FALSE ;
232+ }
233+
234+ git_oid_mkstr (& id , oid );
235+ git_odb * odb ;
236+ odb = git_repository_database (this -> repository );
237+
238+ if (!git_odb_exists (odb ,& id )){
239+ zend_throw_exception_ex (spl_ce_InvalidArgumentException , 0 TSRMLS_CC ,
240+ "specified oid not found" );
241+ RETURN_FALSE ;
242+ }
243+
244+ git_reference * reference ;
245+ int ret = git_reference_create_oid (& reference , this -> repository , name , & id );
246+ if (ret != GIT_SUCCESS ){
247+ zend_throw_exception_ex (spl_ce_InvalidArgumentException , 0 TSRMLS_CC ,
248+ "can't add reference" );
249+ RETURN_FALSE ;
250+ }
251+
252+ char out [GIT_OID_HEXSZ + 1 ] = {0 };
253+ git_rtype type ;
254+ zval * ref ;
255+ MAKE_STD_ZVAL (ref );
256+ object_init_ex (ref , git_reference_class_entry );
257+ php_git_reference_t * refobj = (php_git_reference_t * ) zend_object_store_get_object (ref TSRMLS_CC );
258+ refobj -> object = reference ;
259+
260+ add_property_string_ex (ref ,"name" , sizeof ("name" ), name , 1 TSRMLS_CC );
261+ type = git_reference_type (reference );
262+ if (type == GIT_REF_SYMBOLIC ) {
263+ const char * target = git_reference_target (reference );
264+ if (target != NULL ) {
265+ add_property_string_ex (ref ,"target" ,sizeof ("target" ),(char * )target , 1 TSRMLS_CC );
266+ }
267+ int rr = git_reference_resolve (& refobj -> object ,reference );
268+ if (rr != GIT_SUCCESS ){
269+ zend_throw_exception_ex (spl_ce_InvalidArgumentException , 0 TSRMLS_CC ,
270+ "something wrong" );
271+ RETURN_FALSE ;
272+ }
273+ }
274+ git_oid_to_string (out ,GIT_OID_HEXSZ + 1 ,git_reference_oid (refobj -> object ));
275+ add_property_string_ex (ref ,"oid" ,sizeof ("oid" ),out , 1 TSRMLS_CC );
276+ RETURN_ZVAL (ref ,0 ,0 );
277+ }
278+
279+ PHPAPI function_entry php_git_reference_manager_methods [] = {
280+ PHP_ME (git_reference_manager , __construct , arginfo_git_reference_manager__construct , ZEND_ACC_PUBLIC )
281+ PHP_ME (git_reference_manager , getList , NULL , ZEND_ACC_PUBLIC )
282+ PHP_ME (git_reference_manager , lookupRef , arginfo_git_reference_manager_lookup , ZEND_ACC_PUBLIC )
283+ PHP_ME (git_reference_manager , pack , NULL , ZEND_ACC_PUBLIC )
284+ PHP_ME (git_reference_manager , create , arginfo_git_reference_manager_create , ZEND_ACC_PUBLIC )
285+ {NULL , NULL , NULL }
286+ };
287+
288+ void git_init_reference_manager (TSRMLS_D )
289+ {
290+ zend_class_entry ce ;
291+ INIT_NS_CLASS_ENTRY (ce , ZEND_NS_NAME (PHP_GIT_NS ,"Reference" ),"Manager" , php_git_reference_manager_methods );
292+ git_reference_manager_class_entry = zend_register_internal_class (& ce TSRMLS_CC );
293+ git_reference_manager_class_entry -> create_object = php_git_reference_manager_new ;
294+
295+ }
0 commit comments