Davi Souza / Mbed 2 deprecated pymite

Dependencies:   TSI mbed

Fork of pymite by Norimasa Okamoto

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bytearray.c Source File

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         if ((((pPmInt_t)pobj)->val > 255) || (((pPmInt_t)pobj)->val < 0)) {
00057             PM_RAISE(retval, PM_RET_EX_VAL);
00058             return retval;
00059         }
00060 
00061         *b = (uint8_t)((pPmInt_t)pobj)->val;
00062     }
00063 
00064     else if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_STR) {
00065         if (((pPmString_t)pobj)->length != 1) {
00066             PM_RAISE(retval, PM_RET_EX_VAL);
00067             return retval;
00068         }
00069         *b = ((pPmString_t)pobj)->val[0];
00070     }
00071 
00072     else {
00073         PM_RAISE(retval, PM_RET_EX_TYPE);
00074     }
00075     return retval;
00076 }
00077 
00078 
00079 PmReturn_t
00080 bytearray_new(pPmObj_t pobj, pPmObj_t *r_pobj)
00081 {
00082     PmReturn_t retval = PM_RET_OK;
00083     pPmBytearray_t pba = C_NULL;
00084     pPmBytes_t pb = C_NULL;
00085     pPmObj_t pitem;
00086     int32_t i;
00087     int16_t n;
00088     uint8_t b;
00089     uint8_t objid;
00090 
00091     /* If object is an instance, get the thing it is containing */
00092     if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_CLI) {
00093         retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs,
00094                               PM_NONE,
00095                               (pPmObj_t *)&pba);
00096         PM_RETURN_IF_ERROR(retval);
00097         pobj = (pPmObj_t)pba;
00098     }
00099 
00100     /* Get the requested length of the new bytearray */
00101     switch (OBJ_GET_TYPE(pobj)) {
00102         case OBJ_TYPE_INT:
00103             i = ((pPmInt_t)pobj)->val;
00104             if ((i < 0) || (i > 65535)) {
00105                 PM_RAISE(retval, PM_RET_EX_VAL);
00106                 return retval;
00107             }
00108             n = i;
00109             break;
00110 
00111         case OBJ_TYPE_STR:
00112             n = ((pPmString_t)pobj)->length;
00113             break;
00114 
00115         case OBJ_TYPE_LST:
00116             n = ((pPmList_t)pobj)->length;
00117             break;
00118 
00119         case OBJ_TYPE_TUP:
00120             n = ((pPmTuple_t)pobj)->length;
00121             break;
00122 
00123         case OBJ_TYPE_BYA:
00124             n = ((pPmBytearray_t)pobj)->length;
00125             break;
00126 
00127         default:
00128             PM_RAISE(retval, PM_RET_EX_TYPE);
00129             return retval;
00130     }
00131 
00132     /* Allocate a bytearray */
00133     retval = heap_getChunk(sizeof(PmBytearray_t), (uint8_t **)&pba);
00134     PM_RETURN_IF_ERROR(retval);
00135     OBJ_SET_TYPE(pba, OBJ_TYPE_BYA);
00136     pba->length = n;
00137     pba->val = C_NULL;
00138 
00139     /* Allocate the bytes container */
00140     heap_gcPushTempRoot((pPmObj_t)pba, &objid);
00141     retval = bytes_new(n, (pPmObj_t *)&pb);
00142     heap_gcPopTempRoot(objid);
00143     PM_RETURN_IF_ERROR(retval);
00144     pba->val = pb;
00145 
00146     /* Fill the bytes */
00147     switch (OBJ_GET_TYPE(pobj)) {
00148         case OBJ_TYPE_INT:
00149             sli_memset((unsigned char *)&(pb->val), '\0', n);
00150             break;
00151 
00152         case OBJ_TYPE_BYA:
00153             pitem = (pPmObj_t)((pPmBytearray_t)pobj)->val;
00154             sli_memcpy(&(pb->val[0]), &(((pPmBytes_t)pitem)->val[0]), n);
00155             break;
00156 
00157         case OBJ_TYPE_STR:
00158             sli_memcpy(&(pb->val[0]), &(((pPmString_t)pobj)->val[0]), n);
00159             break;
00160 
00161         case OBJ_TYPE_LST:
00162         case OBJ_TYPE_TUP:
00163             for (i = 0; i < n; i++) {
00164                 retval = seq_getSubscript(pobj, i, &pitem);
00165                 PM_RETURN_IF_ERROR(retval);
00166                 retval = bytes_getByteFromObj(pitem, &b);
00167                 PM_RETURN_IF_ERROR(retval);
00168                 pb->val[i] = b;
00169             }
00170             break;
00171     }
00172 
00173     *r_pobj = (pPmObj_t)pba;
00174     return retval;
00175 }
00176 
00177 
00178 PmReturn_t
00179 bytearray_getItem(pPmObj_t pobj, int16_t index, pPmObj_t *r_pobj)
00180 {
00181     PmReturn_t retval = PM_RET_OK;
00182     pPmBytearray_t pba;
00183     pPmBytes_t pb;
00184     int32_t n;
00185 
00186     pba = (pPmBytearray_t)pobj;
00187 
00188     /* Adjust a negative index */
00189     if (index < 0) {
00190         index += pba->length;
00191     }
00192 
00193     /* Check the bounds of the index */
00194     if ((index < 0) || (index >= pba->length)) {
00195         PM_RAISE(retval, PM_RET_EX_INDX);
00196         return retval;
00197     }
00198 
00199     /* Create int from byte at index */
00200     pb = pba->val;
00201     n = (int32_t)pb->val[index];
00202     retval = int_new(n, r_pobj);
00203 
00204     return retval;
00205 }
00206 
00207 
00208 PmReturn_t
00209 bytearray_setItem(pPmObj_t pba, int16_t index, pPmObj_t pobj)
00210 {
00211     PmReturn_t retval;
00212     pPmBytes_t pb;
00213     uint8_t b = 0;
00214 
00215     /* Adjust a negative index */
00216     if (index < 0) {
00217         index += ((pPmBytearray_t)pba)->length;
00218     }
00219 
00220     /* Check the bounds of the index */
00221     if ((index < 0) || (index >= ((pPmBytearray_t)pba)->length)) {
00222         PM_RAISE(retval, PM_RET_EX_INDX);
00223         return retval;
00224     }
00225 
00226     /* Set the item */
00227     retval = bytes_getByteFromObj(pobj, &b);
00228     pb = ((pPmBytearray_t)pba)->val;
00229     pb->val[index] = b;
00230 
00231     return retval;
00232 }
00233 
00234 
00235 #ifdef HAVE_PRINT
00236 PmReturn_t
00237 bytearray_print(pPmObj_t pobj)
00238 {
00239     PmReturn_t retval;
00240     pPmBytes_t pb;
00241 
00242     obj_print(PM_BYTEARRAY_STR, C_FALSE, C_FALSE);
00243     plat_putByte('(');
00244     plat_putByte('b');
00245     pb = ((pPmBytearray_t)pobj)->val;
00246     retval = string_printFormattedBytes(&(pb->val[0]),
00247                                         C_TRUE,
00248                                         ((pPmBytearray_t)pobj)->length);
00249     plat_putByte(')');
00250     return retval;
00251 }
00252 #endif /* HAVE_PRINT */
00253 #endif /* HAVE_BYTEARRAY */