state = sec_asn1e_push_state (state->top, SEC_ASN1GetSubtemplate(state->theTemplate, state->src, PR_TRUE), state->src, PR_TRUE);
state = sec_asn1e_push_state (state->top, subt, state->src, PR_TRUE);
sec_asn1e_write_header (sec_asn1e_state *state){    unsigned long contents_length;    unsigned char tag_number, tag_modifiers;    PRBool noheader;    PORT_Assert (state->place == beforeHeader);    tag_number = state->tag_number;    tag_modifiers = state->tag_modifiers;    if (state->underlying_kind == SEC_ASN1_ANY) {	state->place = duringContents;	return;    }    if( state->underlying_kind & SEC_ASN1_CHOICE ) {      int indx = sec_asn1e_which_choice(state->src, state->theTemplate);      if( 0 == indx ) {        /* XXX set an error? "choice not found" */        state->top->status = encodeError;        return;      }      state->place = afterChoice;      state = sec_asn1e_push_state(state->top, &state->theTemplate[indx],                                   (char *)state->src - state->theTemplate->offset, 				   PR_TRUE);      if( (sec_asn1e_state *)NULL != state ) {        /*         * Do the "before" field notification.         */        sec_asn1e_notify_before (state->top, state->src, state->depth);        state = sec_asn1e_init_state_based_on_template (state);      }            return;    }    /*     * We are doing a definite-length encoding.  First we have to     * walk the data structure to calculate the entire contents length.     */    contents_length = sec_asn1e_contents_length (state->theTemplate,						 state->src,                                                  state->disallowStreaming,                                                 &noheader);    /*     * We might be told explicitly not to put out a header.     * But it can also be the case, via a pushed subtemplate, that     * sec_asn1e_contents_length could not know that this field is     * really optional.  So check for that explicitly, too.     */    if (noheader || (contents_length == 0 && state->optional)) {	state->place = afterContents;	if (state->top->streaming && state->may_stream && state->top->from_buf)	    /* we did not find an optional indefinite string, so we don't encode it.	     * However, if TakeFromBuf is on, we stop here anyway to give our caller	     * a chance to intercept at the same point where we would stop if the	     * field were present. */	    state->top->status = needBytes;	return;    }    if (state->top->streaming && state->may_stream			      && (state->top->from_buf || !state->is_string)) {	/*	 * We need to put out an indefinite-length encoding.	 */	state->indefinite = PR_TRUE;	/*	 * The only universal types that can be constructed are SETs,	 * SEQUENCEs, and strings; so check that it is one of those,	 * or that it is not universal (e.g. context-specific).	 */	PORT_Assert ((tag_number == SEC_ASN1_SET)		     || (tag_number == SEC_ASN1_SEQUENCE)		     || ((tag_modifiers & SEC_ASN1_CLASS_MASK) != 0)		     || state->is_string);	tag_modifiers |= SEC_ASN1_CONSTRUCTED;	contents_length = 0;    }    sec_asn1e_write_identifier_bytes (state, (unsigned char)(tag_number | tag_modifiers));    sec_asn1e_write_length_bytes (state, contents_length, state->indefinite);    if (contents_length == 0 && !state->indefinite) {	/*	 * If no real contents to encode, then we are done with this field.	 */	state->place = afterContents;	return;    }    /*     * An EXPLICIT is nothing but an outer header, which we have already     * written.  Now we need to do the inner header and contents.     */    if (state->isExplicit) {	state->place = afterContents;	state = sec_asn1e_push_state (state->top,				      SEC_ASN1GetSubtemplate(state->theTemplate,							     state->src,							     PR_TRUE),				      state->src, PR_TRUE);	if (state != NULL)	    state = sec_asn1e_init_state_based_on_template (state);	return;    }    switch (state->underlying_kind) {      case SEC_ASN1_SET_OF:      case SEC_ASN1_SEQUENCE_OF:	/*	 * We need to push a child to handle each member.	 */	{	    void **group;	    const SEC_ASN1Template *subt;	    group = *(void ***)state->src;	    if (group == NULL || *group == NULL) {		/*		 * Group is empty; we are done.		 */		state->place = afterContents;		return;	    }	    state->place = duringGroup;	    subt = SEC_ASN1GetSubtemplate (state->theTemplate, state->src,					   PR_TRUE);	    state = sec_asn1e_push_state (state->top, subt, *group, PR_TRUE);	    if (state != NULL)		state = sec_asn1e_init_state_based_on_template (state);	}	break;      case SEC_ASN1_SEQUENCE:      case SEC_ASN1_SET:	/*	 * We need to push a child to handle the individual fields.	 */	state->place = duringSequence;	state = sec_asn1e_push_state (state->top, state->theTemplate + 1,				      state->src, PR_TRUE);	if (state != NULL) {	    /*	     * Do the "before" field notification.	     */	    sec_asn1e_notify_before (state->top, state->src, state->depth);	    state = sec_asn1e_init_state_based_on_template (state);	}	break;      default:	/*	 * I think we do not need to do anything else.	 * XXX Correct?	 */	state->place = duringContents;	break;    }}