*
* hbytes range VALUE START SIZE => substring (or error)
* hbytes overwrite VAR START VALUE
- * hbytes trimleft VALUE removes any leading 0 octets
+ * hbytes trimleft VAR removes any leading 0 octets
* hbytes repeat VALUE COUNT => COUNT copies of VALUE
*
* hbytes clockincrement VAR INTEGER adds INTEGER to VAR mod 256^|VAR|
typedef struct {
HBytes_Value *hb;
Tcl_Obj *obj, *var;
+ int copied;
} HBytes_Var;
void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg);
static void enum_nt_dup(Tcl_Obj *src, Tcl_Obj *dup) {
dup->internalRep= src->internalRep;
+ dup->typePtr= src->typePtr;
}
static void enum_nt_ustr(Tcl_Obj *o) {
}
static void hbytes_t_dup(Tcl_Obj *src, Tcl_Obj *dup) {
- objfreeir(dup);
hbytes_array(OBJ_HBYTES(dup),
hbytes_data(OBJ_HBYTES(src)),
hbytes_len(OBJ_HBYTES(src)));
+ dup->typePtr= &hbytes_type;
}
static void hbytes_t_free(Tcl_Obj *o) {
int rc;
Tcl_Obj *val;
- Tcl_IncrRefCount(var);
agg->var= var;
val= Tcl_ObjGetVar2(ip,var,0,TCL_LEAVE_ERR_MSG);
if (!val) return TCL_ERROR;
- if (Tcl_IsShared(val)) val= Tcl_DuplicateObj(val);
- Tcl_IncrRefCount(val);
- agg->obj= val;
-
+
rc= Tcl_ConvertToType(ip,val,&hbytes_type);
if (rc) return rc;
- agg->hb= OBJ_HBYTES(val); return TCL_OK; }
+ Tcl_InvalidateStringRep(val);
+ if (Tcl_IsShared(val)) {
+ val= Tcl_DuplicateObj(val);
+ agg->copied= 1;
+ }
+ agg->obj= val;
+
+ agg->hb= OBJ_HBYTES(val);
+ return TCL_OK;
+}
void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg) {
Tcl_Obj *ro;
- if (agg->obj) Tcl_InvalidateStringRep(agg->obj);
if (!rc) {
assert(agg->obj);
ro= Tcl_ObjSetVar2(ip,agg->var,0,agg->obj,TCL_LEAVE_ERR_MSG);
if (!ro) rc= TCL_ERROR;
}
- if (agg->obj) Tcl_DecrRefCount(agg->obj);
- if (agg->var) Tcl_DecrRefCount(agg->var);
+ if (rc && agg->copied)
+ Tcl_DecrRefCount(agg->obj);
}
int pat_hb(Tcl_Interp *ip, Tcl_Obj *obj, HBytes_Value *val) {
Init hb hbytes_sentinel(&@);
Type hbv: HBytes_Var @
-Init hbv @.hb=0; @.obj=0; @.var=0;
+Init hbv @.hb=0; @.obj=0; @.var=0; @.copied=0;
Fini hbv fini_hbv(ip, rc, &@);
Type sockaddr: SockAddr_Value @
$pa_vars .= " const char *e;\n";
$pa_fini .= "\n";
$pa_fini .= "e_err:\n";
- $pa_fini .= " setstringresult(ip,e);";
+ $pa_fini .= " setstringresult(ip,e);\n";
$pa_fini .= " rc= TCL_ERROR; goto rc_err;\n";
}
$pa_vars .= "\n";
memcpy(dup->value, src->value, src->valuelen);
noalg(dup);
dup_obj->internalRep.otherValuePtr= dup;
+ dup_obj->typePtr= &blockcipherkey_type;
}
static void key_t_ustr(Tcl_Obj *o) {
Tcl_IncrRefCount(invoke);
rc= Tcl_ListObjReplace(ip,invoke,sock->script_llength,0,3,args);
+ for (i=0; i<3; i++) { Tcl_DecrRefCount(args[i]); args[i]= 0; }
if (rc) goto x_rc;
rc= Tcl_EvalObjEx(ip,invoke,TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
- for (i=0; i<3; i++) Tcl_DecrRefCount(args[i]);
- Tcl_DecrRefCount(invoke);
-
- hbytes_free(&message_val);
- sockaddr_free(&peer_val);
-
x_rc:
+ if (invoke) Tcl_DecrRefCount(invoke);
+
if (rc)
Tcl_BackgroundError(ip);
}
static void sockid_t_dup(Tcl_Obj *src, Tcl_Obj *dup) {
dup->internalRep= src->internalRep;
+ dup->typePtr= &dgramsockid_type;
}
static void sockid_t_ustr(Tcl_Obj *o) {
/* Sockaddr Tcl type */
static void sockaddr_t_dup(Tcl_Obj *src, Tcl_Obj *dup) {
- objfreeir(dup);
sockaddr_create(OBJ_SOCKADDR(dup),
sockaddr_addr(OBJ_SOCKADDR(src)),
sockaddr_len(OBJ_SOCKADDR(src)));
+ dup->typePtr= &hbytes_type;
}
static void sockaddr_t_free(Tcl_Obj *o) {
*
* hbytes range VALUE START SIZE => substring (or error)
* hbytes overwrite VAR START VALUE
- * hbytes trimleft VALUE removes any leading 0 octets
+ * hbytes trimleft VAR removes any leading 0 octets
* hbytes repeat VALUE COUNT => COUNT copies of VALUE
*
* hbytes clockincrement VAR INTEGER adds INTEGER to VAR mod 256^|VAR|
typedef struct {
HBytes_Value *hb;
Tcl_Obj *obj, *var;
+ int copied;
} HBytes_Var;
void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg);
}
static void hbytes_t_dup(Tcl_Obj *src, Tcl_Obj *dup) {
- objfreeir(dup);
hbytes_array(OBJ_HBYTES(dup),
hbytes_data(OBJ_HBYTES(src)),
hbytes_len(OBJ_HBYTES(src)));
+ dup->typePtr= &hbytes_type;
}
static void hbytes_t_free(Tcl_Obj *o) {
int rc;
Tcl_Obj *val;
- Tcl_IncrRefCount(var);
agg->var= var;
val= Tcl_ObjGetVar2(ip,var,0,TCL_LEAVE_ERR_MSG);
if (!val) return TCL_ERROR;
- if (Tcl_IsShared(val)) val= Tcl_DuplicateObj(val);
- Tcl_IncrRefCount(val);
- agg->obj= val;
-
+
rc= Tcl_ConvertToType(ip,val,&hbytes_type);
if (rc) return rc;
- agg->hb= OBJ_HBYTES(val); return TCL_OK; }
+ Tcl_InvalidateStringRep(val);
+ if (Tcl_IsShared(val)) {
+ val= Tcl_DuplicateObj(val);
+ agg->copied= 1;
+ }
+ agg->obj= val;
+
+ agg->hb= OBJ_HBYTES(val);
+ return TCL_OK;
+}
void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg) {
Tcl_Obj *ro;
- if (agg->obj) Tcl_InvalidateStringRep(agg->obj);
if (!rc) {
assert(agg->obj);
ro= Tcl_ObjSetVar2(ip,agg->var,0,agg->obj,TCL_LEAVE_ERR_MSG);
if (!ro) rc= TCL_ERROR;
}
- if (agg->obj) Tcl_DecrRefCount(agg->obj);
- if (agg->var) Tcl_DecrRefCount(agg->var);
+ if (rc && agg->copied)
+ Tcl_DecrRefCount(agg->obj);
}
int pat_hb(Tcl_Interp *ip, Tcl_Obj *obj, HBytes_Value *val) {
static void ulong_t_dup(Tcl_Obj *src, Tcl_Obj *dup) {
dup->internalRep= src->internalRep;
+ dup->typePtr= &ulong_type;
}
static void ulong_t_ustr(Tcl_Obj *o) {