uint64_t CECTag::GetInt() const { if (m_tagData == NULL) { // Empty tag - This is NOT an error. EC_ASSERT(m_dataType == EC_TAGTYPE_UNKNOWN); return 0; } switch (m_dataType) { case EC_TAGTYPE_UINT8: return PeekUInt8(m_tagData); case EC_TAGTYPE_UINT16: return ENDIAN_NTOHS( RawPeekUInt16( m_tagData ) ); case EC_TAGTYPE_UINT32: return ENDIAN_NTOHL( RawPeekUInt32( m_tagData ) ); case EC_TAGTYPE_UINT64: return ENDIAN_NTOHLL( RawPeekUInt64( m_tagData ) ); case EC_TAGTYPE_UNKNOWN: // Empty tag - This is NOT an error. return 0; default: EC_ASSERT(0); return 0; } }
std::string CECTag::GetStringDataSTL() const { if (m_dataType != EC_TAGTYPE_STRING) { EC_ASSERT(m_dataType == EC_TAGTYPE_UNKNOWN); return std::string(); } else if (m_tagData == NULL) { EC_ASSERT(false); return std::string(); } return std::string(m_tagData); }
static EC_OBJ string_setitem( EC_OBJ obj, EC_OBJ index, EC_OBJ value ) { if (! EC_INUMP(index)) { /* TODO: Throw an exception */ EC_ASSERT( FALSE ); return Ec_ERROR; } if (! EC_CHARP(value)) { /* TODO: Throw an exception */ EC_ASSERT( FALSE ); return Ec_ERROR; } if (EC_INUM(index) >= EC_USTRLEN(obj)) { /* expand the string */ EcInt newlen, i; char *newdata; newlen = EC_INUM(index) + 1; newdata = ec_realloc( EC_USTRDATA(obj), newlen + 1 ); if (! newdata) return EcMemoryError(); for (i = EC_USTRLEN(obj); i < newlen; i++) newdata[i] = '\0'; newdata[newlen] = '\0'; EC_USTRDATA(obj) = newdata; EC_USTRLEN(obj) = newlen; } if ((EC_INUM(index) < 0) || (EC_INUM(index) >= EC_USTRLEN(obj))) { ec_string ds; ec_string_init( &ds, NULL ); ec_sprintf( &ds, "Index %ld out of bounds for object %w", EC_INUM(index), obj ); EcMakeExceptionWithArgs( EcIndexErrorClass, ec_strdata( &ds ), 2, index, obj ); ec_string_cleanup( &ds ); return Ec_ERROR; } EC_USTRDATA(obj)[EC_INUM(index)] = EC_CHAR(value); return obj; }
CMD4Hash CECTag::GetMD4Data() const { if (m_dataType != EC_TAGTYPE_HASH16) { EC_ASSERT(m_dataType == EC_TAGTYPE_UNKNOWN); return CMD4Hash(); } EC_ASSERT(m_tagData != NULL); // Doesn't matter if m_tagData is NULL in CMD4Hash(), // that'll just result in an empty hash. return CMD4Hash((const unsigned char *)m_tagData); }
/** * Returns an EC_IPv4_t class. * * This function takes care of the endianness of the port number. * * @return EC_IPv4_t class. * * @see CECTag(ec_tagname_t, const EC_IPv4_t&) */ EC_IPv4_t CECTag::GetIPv4Data() const { EC_IPv4_t p(0, 0); if (m_dataType != EC_TAGTYPE_IPV4) { EC_ASSERT(m_dataType == EC_TAGTYPE_UNKNOWN); } else if (m_tagData == NULL) { EC_ASSERT(false); } else { RawPokeUInt32( p.m_ip, RawPeekUInt32( reinterpret_cast<EC_IPv4_t *>(m_tagData)->m_ip ) ); p.m_port = ENDIAN_NTOHS(reinterpret_cast<EC_IPv4_t *>(m_tagData)->m_port); } return p; }
/* Private */ static EC_OBJ ustring_copy( EC_OBJ obj, EcCopyType type ) { EC_ASSERT( EC_USTRINGP(obj) ); return EcMakeUString( EC_USTRDATA(obj), EC_USTRLEN(obj) , EcTrue ); } static void ustring_mark( EC_OBJ obj ) { EC_ASSERT( EC_USTRINGP(obj) ); } static void ustring_free( EC_OBJ obj ) { EC_ASSERT( EC_USTRINGP(obj) ); ec_free( EC_USTRDATA(obj) ); EC_USTRDATA(obj) = NULL; EC_USTRLEN(obj) = 0; } static EcInt ustring_print( ec_string *str, EC_OBJ obj, EcBool detailed ) { EcInt res = 0; EC_ASSERT( EC_USTRINGP(obj) ); { ec_strcat( str, "<unicode string>", sizeof("<unicode string>") - 1 ); res += sizeof("<unicode string>") - 1; } return res; } #if 0 /* unimplemented */ static EC_OBJ ustring_getitem( EC_OBJ obj, EC_OBJ index ) { if (! EC_INUMP(index)) { /* TODO: Throw an exception */ EC_ASSERT( FALSE ); return Ec_ERROR; } if ((EC_INUM(index) < 0) || (EC_INUM(index) >= EC_USTRLEN(obj))) { ec_string ds; ec_string_init( &ds, NULL ); ec_sprintf( &ds, "Index %ld out of bounds for object %w", EC_INUM(index), obj ); EcMakeExceptionWithArgs( EcIndexErrorClass, ec_strdata( &ds ), 2, index, obj ); ec_string_cleanup( &ds ); return Ec_ERROR; } return EcMakeUChar( EC_USTRDATA(obj)[EC_INUM(index)] ); }
/** * Returns a double value. * * @note The returned value is what we get by converting the string form * of the number to a double. * * @return The double value of the tag. * * @see CECTag(ec_tagname_t, double) */ double CECTag::GetDoubleData(void) const { if (m_dataType != EC_TAGTYPE_DOUBLE) { EC_ASSERT(m_dataType == EC_TAGTYPE_UNKNOWN); return 0; } else if (m_tagData == NULL) { EC_ASSERT(false); return 0; } std::istringstream double_str(m_tagData); double data; double_str >> data; return data; }
static void ustring_free( EC_OBJ obj ) { EC_ASSERT( EC_USTRINGP(obj) ); ec_free( EC_USTRDATA(obj) ); EC_USTRDATA(obj) = NULL; EC_USTRLEN(obj) = 0; }
static EC_OBJ ustring_radd( EC_OBJ obj1, EC_OBJ obj2 ) { /* ec_string str; */ EC_OBJ res; EcInt len; if (! EC_USTRINGP(obj2)) return EcTypeError( EC_NIL, EC_NIL, 2, tc_string, obj2, TRUE, "string radd" ); EC_ASSERT( EC_USTRINGP(obj1) ); EC_ASSERT( EC_USTRINGP(obj2) ); len = EC_USTRLEN(obj1) + EC_USTRLEN(obj2); res = EcMakeUString( EC_USTRDATA(obj2), len , EcTrue ); u_strcat(EC_USTRDATA(res), EC_USTRDATA(obj1) ); EC_USTRLEN(res) = len; return res; }
bool CECTag::AssignIfExist(ec_tagname_t tagname, uint8_t &target) const { const CECTag *tag = GetTagByName(tagname); if (tag) { EC_ASSERT((tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)); target = tag->GetInt(); return true; } return false; }
static EcInt ustring_print( ec_string *str, EC_OBJ obj, EcBool detailed ) { EcInt res = 0; EC_ASSERT( EC_USTRINGP(obj) ); { ec_strcat( str, "<unicode string>", sizeof("<unicode string>") - 1 ); res += sizeof("<unicode string>") - 1; } return res; }
/** * Creates a new CECTag instance from the given data * * @param name TAG name * @param length length of data buffer * @param data TAG data * */ CECTag::CECTag(ec_tagname_t name, unsigned int length, const void *data) : m_tagName(name) { if (data) { m_dataLen = length; NewData(); memcpy(m_tagData, data, m_dataLen); } else { EC_ASSERT(length == 0); m_dataLen = 0; m_tagData = NULL; } m_dataType = EC_TAGTYPE_CUSTOM; }
uint8_t CECTag::AssignIfExist(ec_tagname_t tagname, uint8_t *target) const { uint8_t ret = 0; const CECTag *tag = GetTagByName(tagname); if (tag) { EC_ASSERT((tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)); ret = tag->GetInt(); if (target) { *target = ret; } } return ret; }
static EC_OBJ string_int( EC_OBJ obj ) { EcInt val; char *endptr; EC_ASSERT( EC_USTRINGP(obj) ); val = strtol( EC_USTRDATA(obj), &endptr, 0 ); if (((val == LONG_MIN) || (val == LONG_MAX)) && (errno == ERANGE)) return EcTypeError( EC_NIL, EC_NIL, 1, tc_none, obj, TRUE, "string int: undeflow or overflow" ); if (endptr == EC_USTRDATA(obj)) return EcTypeError( EC_NIL, EC_NIL, 1, tc_none, obj, TRUE, "string int: bad integer number" ); return EcMakeInt( val ); }
static EC_OBJ string_float( EC_OBJ obj ) { EcFloat val; char *endptr; EC_ASSERT( EC_USTRINGP(obj) ); val = strtod( EC_USTRDATA(obj), &endptr ); if (((val == HUGE_VAL) || (val == -HUGE_VAL)) && (errno == ERANGE)) return EcTypeError( EC_NIL, EC_NIL, 1, tc_none, obj, TRUE, "string float: undeflow or overflow" ); if (endptr == EC_USTRDATA(obj)) return EcTypeError( EC_NIL, EC_NIL, 1, tc_none, obj, TRUE, "string float: bad decimal number" ); return EcMakeFloat( val ); }
static EC_OBJ ustring_add( EC_OBJ obj1, EC_OBJ obj2 ) { /* ec_string str; */ EC_OBJ res; EcInt len; /* add chars later */ if (/* (! EC_CHARP(obj2)) && */(! EC_USTRINGP(obj2))) return EcTypeError( EC_NIL, EC_NIL, 2, tc_none, obj2, TRUE, "string add" ); EC_ASSERT( EC_USTRINGP(obj1) ); len = EC_USTRLEN(obj1) + EC_USTRLEN(obj2); res = EcMakeUString( EC_USTRDATA(obj1), len , EcTrue ); u_strcat(EC_USTRDATA(res), EC_USTRDATA(obj2) ); EC_USTRLEN(res) = len; return res; }
static EC_OBJ ustring_mul( EC_OBJ obj1, EC_OBJ obj2 ) { ec_string str; EC_OBJ res; EcInt i; if (! EC_INUMP(obj2)) return EcTypeError( EC_NIL, EC_NIL, 2, tc_inum, obj2, TRUE, "string mul" ); EC_ASSERT( EC_USTRINGP(obj1) ); ec_string_init( &str, NULL ); for (i = 0; i < EC_INUM(obj2); i++) ec_strcat( &str, EC_USTRDATA(obj1), EC_USTRLEN(obj1) ); res = EcMakeString( ec_strdata( &str ), ec_strlen( &str ) ); ec_string_cleanup( &str ); return res; }
static EC_OBJ string_promote( EC_OBJ obj1, EC_OBJ obj2 ) { ec_string str; EC_OBJ repr2; EC_OBJ res; EC_ASSERT( EC_USTRINGP(obj1 ) ); ec_string_init( &str, NULL ); ec_sprintf( &str, "%w", obj2 ); repr2 = EcMakeString( ec_strdata( &str ), ec_strlen( &str ) ); ec_string_cleanup( &str ); res = EcMakeArray( 2 ); if (EC_ERRORP(res)) return res; EcArrayPush( res, obj1 ); EcArrayPush( res, repr2 ); return res; }
static EC_OBJ string_delitem( EC_OBJ obj, EC_OBJ index ) { EcInt idx; if (! EC_INUMP(index)) { /* TODO: Throw an exception */ EC_ASSERT( FALSE ); return Ec_ERROR; } if ((EC_INUM(index) < 0) || (EC_INUM(index) >= EC_USTRLEN(obj))) { ec_string ds; ec_string_init( &ds, NULL ); ec_sprintf( &ds, "Index %ld out of bounds for object %w", EC_INUM(index), obj ); EcMakeExceptionWithArgs( EcIndexErrorClass, ec_strdata( &ds ), 2, index, obj ); ec_string_cleanup( &ds ); return Ec_ERROR; } idx = EC_INUM(index); if (idx < EC_USTRLEN(obj) - 1) { memcpy( EC_USTRDATA(obj) + idx, EC_USTRDATA(obj) + idx + 1, EC_USTRLEN(obj) - idx - 1 ); EC_USTRLEN(obj) -= 1; } else { EC_USTRDATA(obj)[idx] = '\0'; /* unnecessary */ EC_USTRLEN(obj) -= 1; } return obj; }
bool CECTag::WriteTag(CECSocket& socket) const { ec_tagname_t tmp_tagName = (m_tagName << 1) | (m_tagList.empty() ? 0 : 1); ec_tagtype_t type = m_dataType; ec_taglen_t tagLen = GetTagLen(); EC_ASSERT(type != EC_TAGTYPE_UNKNOWN); if (!socket.WriteNumber(&tmp_tagName, sizeof(ec_tagname_t))) return false; if (!socket.WriteNumber(&type, sizeof(ec_tagtype_t))) return false; if (!socket.WriteNumber(&tagLen, sizeof(ec_taglen_t))) return false; if (!m_tagList.empty()) { if (!WriteChildren(socket)) return false; } if (m_dataLen > 0) { if (m_tagData != NULL) { // This is here only to make sure everything, it should not be NULL at this point if (!socket.WriteBuffer(m_tagData, m_dataLen)) return false; } } return true; }
EC_OBJ ec_unicode_init( void ) { EC_OBJ pkg; EcSequenceCallbacks sequence_cb = { /* getitem */ NULL /* ustring_getitem */, /* setitem */ NULL /* ustring_setitem */, /* delitem */ NULL /* ustring_delitem */, /* length */ ustring_length }; EcNumericCallbacks numeric_cb = { /* promote */ NULL /* ustring_promote */, /* add */ ustring_add, /* radd */ ustring_radd, /* sub */ NULL, /* rsub */ NULL, /* mul */ NULL /* ustring_mul */, /* rmul */ NULL, /* div */ NULL, /* rdiv */ NULL, /* mod */ NULL, /* rmod */ NULL, /* pow */ NULL, /* rpow */ NULL, /* lshift */ NULL, /* rlshift */ NULL, /* rshift */ NULL, /* rrshift */ NULL, /* and */ NULL, /* rand */ NULL, /* or */ NULL, /* ror */ NULL, /* xor */ NULL, /* rxor */ NULL, /* neg */ NULL, /* pos */ NULL, /* abs */ NULL, /* invert */ NULL, /* int */ NULL /* ustring_int */, /* float */ NULL /* ustring_float */, /* true */ ustring_true }; EcTypespec ustringspec = { /* type */ 0, /* name */ "ustring", /* copy */ ustring_copy, /* mark */ ustring_mark, /* free */ ustring_free, /* print */ ustring_print, /* hash */ ustring_hash, /* compare */ ustring_compare, /* check */ NULL, /* sequence */ &sequence_cb, /* numeric */ &numeric_cb }; tc_ustring = EcAddType( &ustringspec ); EC_ASSERT (tc_ustring != 0); /* Register package */ pkg = EcPackageIntroduce( "unicode" ); EcAddPrimitive( "unicode.utf8_to_uc", EcUnicode_UTF8ToUnicode ); EcAddPrimitive( "unicode.uc_to_utf8", EcUnicode_UnicodeToUTF8 ); return pkg; }
static void ustring_mark( EC_OBJ obj ) { EC_ASSERT( EC_USTRINGP(obj) ); }
static EC_OBJ ustring_copy( EC_OBJ obj, EcCopyType type ) { EC_ASSERT( EC_USTRINGP(obj) ); return EcMakeUString( EC_USTRDATA(obj), EC_USTRLEN(obj) , EcTrue ); }
static EcUInt ustring_hash( EC_OBJ obj, EcInt recur ) { EC_ASSERT( EC_USTRINGP(obj) ); return ec_hash_pjw_string( (char *)EC_USTRDATA(obj) ); }