Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
bytearray.c
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