/*
This product contains certain software code or other information
("AT&T Software") proprietary to AT&T Corp. ("AT&T").  The AT&T
Software is provided to you "AS IS".  YOU ASSUME TOTAL RESPONSIBILITY
AND RISK FOR USE OF THE AT&T SOFTWARE.  AT&T DOES NOT MAKE, AND
EXPRESSLY DISCLAIMS, ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND
WHATSOEVER, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, WARRANTIES OF
TITLE OR NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS, ANY
WARRANTIES ARISING BY USAGE OF TRADE, COURSE OF DEALING OR COURSE OF
PERFORMANCE, OR ANY WARRANTY THAT THE AT&T SOFTWARE IS "ERROR FREE" OR
WILL MEET YOUR REQUIREMENTS.

Unless you accept a license to use the AT&T Software, you shall not
reverse compile, disassemble or otherwise reverse engineer this
product to ascertain the source code for any AT&T Software.

(c) AT&T Corp. All rights reserved.  AT&T is a registered trademark of AT&T Corp.

***********************************************************************

History:

      11/30/99  - initial release by Hartmut Liefke, liefke@seas.upenn.edu
                                     Dan Suciu,      suciu@research.att.com
*/

#include "stdafx.h"

void Session::DecodeTreeBlock(UncompressContainer *treecont,UncompressContainer *whitespacecont,UncompressContainer *specialcont,XMLOutput *output)
{
   char              *strptr;
   unsigned char     isattrib;
   int               mystrlen;

   unsigned char     *curptr,*endptr;
   long              id;
   char              isneg;

   curptr=treecont->GetDataPtr();
   endptr=curptr+treecont->GetSize();

   while(curptr<endptr)
   {
		id=Load::SInt32(curptr,&isneg);

      if(isneg==0)   // Do we have a label ID ?
      {
			if(id>=32768L) {
            throw new XMillException(XMILL_ERR_DECOMPRESS, "Label ID too large");
         }

			switch(id) {
				case TREETOKEN_ENDLABEL:  // An end-of-label token (i.e. id==0) ?
					mystrlen=globaldlabeldict->LookupCompressLabel(curpath->RemoveLabel(),&strptr,&isattrib);

					if(isattrib==0)
						output->endElement(strptr,mystrlen);
					else
						output->endAttribute(strptr,mystrlen);
					break;

				case TREETOKEN_EMPTYENDLABEL:  // An end-of-label token for an empty element
					curpath->RemoveLabel();
					output->endEmptyElement();
					break;
	         
				case TREETOKEN_WHITESPACE:  // A white-space token ?
					mystrlen=whitespacecont->LoadUInt32();
					output->whitespaces((char *)whitespacecont->GetDataPtr(mystrlen),mystrlen);
					break;

				case TREETOKEN_ATTRIBWHITESPACE:  // A attrib white-space token ?
					mystrlen=whitespacecont->LoadUInt32();
					output->attribWhitespaces((char *)whitespacecont->GetDataPtr(mystrlen),mystrlen);
					break;

				case TREETOKEN_SPECIAL:    // A special token
					strptr=(char *)(specialcont->myLoadString((unsigned *)&mystrlen));
					output->characters(strptr,mystrlen);
					break;

				default: // Do we have a start label token?
					id-=LABELIDX_TOKENOFFS;
					mystrlen=globaldlabeldict->LookupCompressLabel((TLabelID)id,&strptr,&isattrib);

					if(isattrib==0)
						output->startElement(strptr,mystrlen);
					else
						output->startAttribute(strptr,mystrlen);

					curpath->AddLabel((TLabelID)id);
         }
      }
      else  // We have a block ID ==> I.e. we have some text
         uncomprcont->GetContBlock(id)->UncompressText(output);
   }
}
