Embed:
(wiki syntax)
Show/hide line numbers
bytearray.c
Go to the documentation of this file.
00001 /* 00002 # This file is Copyright 2010 Dean Hall. 00003 # 00004 # This file is part of the PyMite VM. 00005 # The PyMite VM is free software: you can redistribute it and/or modify 00006 # it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2. 00007 # 00008 # The PyMite VM is distributed in the hope that it will be useful, 00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00011 # A copy of the GNU GENERAL PUBLIC LICENSE Version 2 00012 # is seen in the file COPYING in this directory. 00013 */ 00014 00015 00016 #undef __FILE_ID__ 00017 #define __FILE_ID__ 0x19 00018 00019 00020 /** 00021 * \file 00022 * \brief VM Bytearray Type 00023 * 00024 * VM Bytearray object type operations. 00025 */ 00026 00027 #include "pm.h" 00028 #ifdef HAVE_BYTEARRAY 00029 00030 00031 #define ROUND_UP_TO_MUL_OF_FOUR(n) n = (((n) + 3) & ~3) 00032 00033 00034 /* Returns a container that can hold at least n bytes */ 00035 static 00036 PmReturn_t 00037 bytes_new(int16_t n, pPmObj_t *r_pobj) 00038 { 00039 PmReturn_t retval = PM_RET_OK; 00040 pPmBytes_t pb = C_NULL; 00041 00042 ROUND_UP_TO_MUL_OF_FOUR(n); 00043 00044 /* Allocate a container */ 00045 retval = heap_getChunk(sizeof(PmBytes_t) + n, (uint8_t **)&pb); 00046 PM_RETURN_IF_ERROR(retval); 00047 OBJ_SET_TYPE(pb, OBJ_TYPE_BYS); 00048 pb->length = n; 00049 00050 *r_pobj = (pPmObj_t)pb; 00051 return retval; 00052 } 00053 00054 00055 /* Returns the int or one-char string as a byte */ 00056 static 00057 PmReturn_t 00058 bytes_getByteFromObj(pPmObj_t pobj, uint8_t *b) 00059 { 00060 PmReturn_t retval = PM_RET_OK; 00061 00062 if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_INT) 00063 { 00064 if ((((pPmInt_t)pobj)->val > 255) || (((pPmInt_t)pobj)->val < 0)) 00065 { 00066 PM_RAISE(retval, PM_RET_EX_VAL); 00067 return retval; 00068 } 00069 00070 *b = (uint8_t)((pPmInt_t)pobj)->val; 00071 } 00072 00073 else if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_STR) 00074 { 00075 if (((pPmString_t)pobj)->length != 1) 00076 { 00077 PM_RAISE(retval, PM_RET_EX_VAL); 00078 return retval; 00079 } 00080 *b = ((pPmString_t)pobj)->val[0]; 00081 } 00082 00083 else 00084 { 00085 PM_RAISE(retval, PM_RET_EX_TYPE); 00086 } 00087 return retval; 00088 } 00089 00090 00091 PmReturn_t 00092 bytearray_new(pPmObj_t pobj, pPmObj_t *r_pobj) 00093 { 00094 PmReturn_t retval = PM_RET_OK; 00095 pPmBytearray_t pba = C_NULL; 00096 pPmBytes_t pb = C_NULL; 00097 pPmObj_t pitem; 00098 int32_t i; 00099 int16_t n; 00100 uint8_t b; 00101 00102 /* If object is an instance, get the thing it is containing */ 00103 if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_CLI) 00104 { 00105 retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs, 00106 PM_NONE, 00107 (pPmObj_t *)&pba); 00108 PM_RETURN_IF_ERROR(retval); 00109 pobj = (pPmObj_t)pba; 00110 } 00111 00112 /* Get the requested length of the new bytearray */ 00113 switch (OBJ_GET_TYPE(pobj)) 00114 { 00115 case OBJ_TYPE_INT: 00116 i = ((pPmInt_t)pobj)->val; 00117 if ((i < 0) || (i > 65535)) 00118 { 00119 PM_RAISE(retval, PM_RET_EX_VAL); 00120 return retval; 00121 } 00122 n = i; 00123 break; 00124 00125 case OBJ_TYPE_STR: 00126 n = ((pPmString_t)pobj)->length; 00127 break; 00128 00129 case OBJ_TYPE_LST: 00130 n = ((pPmList_t)pobj)->length; 00131 break; 00132 00133 case OBJ_TYPE_TUP: 00134 n = ((pPmTuple_t)pobj)->length; 00135 break; 00136 00137 case OBJ_TYPE_BYA: 00138 n = ((pPmBytearray_t)pobj)->length; 00139 break; 00140 00141 default: 00142 PM_RAISE(retval, PM_RET_EX_TYPE); 00143 return retval; 00144 } 00145 00146 /* Allocate a bytearray */ 00147 retval = heap_getChunk(sizeof(PmBytearray_t), (uint8_t **)&pba); 00148 PM_RETURN_IF_ERROR(retval); 00149 OBJ_SET_TYPE(pba, OBJ_TYPE_BYA); 00150 pba->length = n; 00151 00152 /* Allocate the bytes container */ 00153 retval = bytes_new(n, (pPmObj_t *)&pb); 00154 PM_RETURN_IF_ERROR(retval); 00155 pba->val = pb; 00156 00157 /* Fill the bytes */ 00158 switch (OBJ_GET_TYPE(pobj)) 00159 { 00160 case OBJ_TYPE_INT: 00161 sli_memset((unsigned char *)&(pb->val), '\0', n); 00162 break; 00163 00164 case OBJ_TYPE_BYA: 00165 pitem = (pPmObj_t)((pPmBytearray_t)pobj)->val; 00166 sli_memcpy(&(pb->val[0]), &(((pPmBytes_t)pitem)->val[0]), n); 00167 break; 00168 00169 case OBJ_TYPE_STR: 00170 sli_memcpy(&(pb->val[0]), &(((pPmString_t)pobj)->val[0]), n); 00171 break; 00172 00173 case OBJ_TYPE_LST: 00174 case OBJ_TYPE_TUP: 00175 for (i = 0; i < n; i++) 00176 { 00177 retval = seq_getSubscript(pobj, i, &pitem); 00178 PM_RETURN_IF_ERROR(retval); 00179 retval = bytes_getByteFromObj(pitem, &b); 00180 PM_RETURN_IF_ERROR(retval); 00181 pb->val[i] = b; 00182 } 00183 break; 00184 } 00185 00186 *r_pobj = (pPmObj_t)pba; 00187 return retval; 00188 } 00189 00190 00191 PmReturn_t 00192 bytearray_getItem(pPmObj_t pobj, int16_t index, pPmObj_t *r_pobj) 00193 { 00194 PmReturn_t retval = PM_RET_OK; 00195 pPmBytearray_t pba; 00196 pPmBytes_t pb; 00197 int32_t n; 00198 00199 pba = (pPmBytearray_t)pobj; 00200 00201 /* Adjust a negative index */ 00202 if (index < 0) 00203 { 00204 index += pba->length; 00205 } 00206 00207 /* Check the bounds of the index */ 00208 if ((index < 0) || (index >= pba->length)) 00209 { 00210 PM_RAISE(retval, PM_RET_EX_INDX); 00211 return retval; 00212 } 00213 00214 /* Create int from byte at index */ 00215 pb = pba->val; 00216 n = (int32_t)pb->val[index]; 00217 retval = int_new(n, r_pobj); 00218 00219 return retval; 00220 } 00221 00222 00223 PmReturn_t 00224 bytearray_setItem(pPmObj_t pba, int16_t index, pPmObj_t pobj) 00225 { 00226 PmReturn_t retval; 00227 pPmBytes_t pb; 00228 uint8_t b = 0; 00229 00230 /* Adjust a negative index */ 00231 if (index < 0) 00232 { 00233 index += ((pPmBytearray_t)pba)->length; 00234 } 00235 00236 /* Check the bounds of the index */ 00237 if ((index < 0) || (index >= ((pPmBytearray_t)pba)->length)) 00238 { 00239 PM_RAISE(retval, PM_RET_EX_INDX); 00240 return retval; 00241 } 00242 00243 /* Set the item */ 00244 retval = bytes_getByteFromObj(pobj, &b); 00245 pb = ((pPmBytearray_t)pba)->val; 00246 pb->val[index] = b; 00247 00248 return retval; 00249 } 00250 00251 00252 PmReturn_t 00253 bytearray_print(pPmObj_t pobj) 00254 { 00255 PmReturn_t retval; 00256 pPmBytes_t pb; 00257 uint8_t pclassname[] = "bytearray"; 00258 uint8_t *pc; 00259 00260 pb = ((pPmBytearray_t)pobj)->val; 00261 00262 pc = &pclassname[0]; 00263 while (*pc != C_NULL) 00264 { 00265 plat_putByte(*pc); 00266 pc++; 00267 } 00268 00269 plat_putByte('('); 00270 plat_putByte('b'); 00271 retval = string_printFormattedBytes(&(pb->val[0]), 00272 C_TRUE, 00273 ((pPmBytearray_t)pobj)->length); 00274 plat_putByte(')'); 00275 return retval; 00276 } 00277 #endif /* HAVE_BYTEARRAY */
Generated on Tue Jul 12 2022 17:07:01 by
1.7.2