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