/*------------------------------------------------------------------------------
 * function: AttrProj::ReadRec
 * Read a record from the data source, and project it onto the attribute
 * combinations corresponding to this object.
 */
DevStatus
AttrProj::ReadRec(RecId recId, VectorArray &vecArray)
{
	DO_DEBUG(printf("AttrProj::ReadRec(%d)\n", (int) recId));

	int			dataSize;
	int			numRecs;
	DevStatus	result = StatusOk;

	TData::TDHandle handle = _tDataP->InitGetRecs(recId, recId);

	if (!_tDataP->GetRecs(handle, _recBuf, _recBufSize,
                              recId, numRecs, dataSize))
	{
		result = StatusFailed;
	}
	else
	{
		AttrList *	attrListP = _tDataP->GetAttrList();
		int		projNum = 0;
		Projection * projP = _projList.GetFirstProj();
		while (projP != NULL)
		{
			Vector *	vectorP = vecArray.GetVector(projNum);
			int		projAttrNum;
			for (projAttrNum = 0; projAttrNum < projP->attrCount;
				projAttrNum++)
			{
				int			attrNum = projP->attrList[projAttrNum];
				AttrInfo *	attrInfoP = attrListP->Get(attrNum);

				vectorP->value[projAttrNum] = AttrToDouble(attrInfoP->type,
					_recBuf + attrInfoP->offset);
			}

			projP = _projList.GetNextProj();
			projNum++;
		}
	}

        _tDataP->DoneGetRecs(handle);

	return result;
}
/*------------------------------------------------------------------------------
 * function: AttrProj::ParseProjection
 * Parse the attribute projection file and build up the corresponding
 * data structures.
 */
DevStatus
AttrProj::ParseProjection(char *attrProjFile)
{
	DO_DEBUG(printf("AttrProj::ParseProjection()\n"));

	DevStatus	result = StatusOk;

	FILE *		file = fopen(attrProjFile, "r");
	if (file == NULL)
	{
		fprintf(stderr, "Can't open attribute projection file\n");
		result = StatusFailed;
	}
	else
	{
		const int	bufSize = 4096;
		char		buf[bufSize];
		char		separators[] = " \t";

		/* Get each line in the attribute projection file. */
		while (fgets(buf, bufSize, file) != NULL)
		{
			DOASSERT(buf[strlen(buf)-1] == '\n',
				"Projection file line too long");

			/* TEMPTEMP -- we should look for some kind of comment char. */

			StripTrailingNewline(buf);
			DO_DEBUG(printf("%s\n", buf));

			Projection	projection;
			char *		token = strtok(buf, separators);
			if (token == NULL) continue;
			projection.attrCount = atoi(token);
			DO_DEBUG(printf("projection.attrCount = %d\n",
				projection.attrCount));
			projection.attrList = new int[projection.attrCount];

			AttrList *	attrListP = _tDataP->GetAttrList();
			int			attrCount = attrListP->NumAttrs();
			int			projAttrNum = 0;

			/* Find each attribute specified for this projection. */
			while ((token = strtok(NULL, separators)) != NULL)
			{
				projection.attrList[projAttrNum] = illegalAttr;
				DO_DEBUG(printf("  token = %s", token));

				int			attrNum;

				/* Now find the attribute in the TData corresponding to
				 * the name specified in the projection. */
				for (attrNum = 0; attrNum < attrCount; attrNum++)
				{
					AttrInfo *	attrInfoP = attrListP->Get(attrNum);

					if (!strcmp(token, attrInfoP->name))
					{
						DO_DEBUG(printf(" attrNum = %d\n", attrNum));
						projection.attrList[projAttrNum] = attrNum;
						break;
					}
				}
				DOASSERT(projection.attrList[projAttrNum] != illegalAttr,	
					"Illegal attribute name in attribute projection file");
				projAttrNum++;
			}
			DOASSERT(projAttrNum == projection.attrCount,
				"Incorrect number of attributes in projection file");


			_projList.AddProjection(projection);

		}

		fclose(file);
	}

	return result;
}