Skip to content

Commit

Permalink
Frame serialization added
Browse files Browse the repository at this point in the history
  • Loading branch information
cpiker committed Aug 7, 2024
1 parent 1fcdf51 commit be8152b
Show file tree
Hide file tree
Showing 10 changed files with 508 additions and 277 deletions.
10 changes: 6 additions & 4 deletions das2/descriptor.c
Original file line number Diff line number Diff line change
Expand Up @@ -895,9 +895,10 @@ DasErrCode _DasDesc_encode(
return DAS_OKAY;

DasBuf_puts(pBuf, sIndent);
DasBuf_puts(pBuf, "<properties\n");
if(nVer > 2)
DasBuf_puts(pBuf, ">\n");
DasBuf_puts(pBuf, "<properties>\n");
else
DasBuf_puts(pBuf, "<properties\n");

DasErrCode nRet = DAS_OKAY;
for(u = 0; u < uProps; ++u){
Expand Down Expand Up @@ -968,10 +969,11 @@ DasErrCode _DasDesc_encode(
if(nRet != DAS_OKAY) return nRet;
}

DasBuf_puts(pBuf, sIndent);
if(nVer > 2)
return DasBuf_printf(pBuf, "%s/>\n", sIndent);
return DasBuf_puts(pBuf, "</properties>\n");
else
return DasBuf_printf(pBuf, "%s/>\n", sIndent);
return DasBuf_puts(pBuf, "/>\n");
}

DasErrCode DasDesc_encode2(DasDesc* pThis, DasBuf* pBuf, const char* sIndent)
Expand Down
149 changes: 140 additions & 9 deletions das2/frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,25 @@ const char* das_frametype2str( ubyte uFT)
if(ft == DASFRM_POLAR ) return "polar";
if(ft == DASFRM_SPHERE_SURFACE) return "sphere_surface";
if(ft == DASFRM_CYLINDRICAL ) return "cylindrical";
if(ft == DASFRM_CYLINDRICAL ) return "spherical";
if(ft == DASFRM_SPHERICAL ) return "spherical";
if(ft == DASFRM_CENTRIC ) return "planetocentric";
if(ft == DASFRM_DETIC ) return "planetodetic";
if(ft == DASFRM_GRAPHIC ) return "planetographic";

daslog_error_v("Unknown vector or coordinate frame type id: '%hhu'.", uFT);
return "";
}

ubyte das_str2frametype(const char* sFT)
{
if( strcasecmp(sFT, "cartesian") == 0) return DASFRM_CARTESIAN;
if( strcasecmp(sFT, "polar") == 0) return DASFRM_POLAR;
if( strcasecmp(sFT, "cartesian") == 0) return DASFRM_CARTESIAN;
if( strcasecmp(sFT, "polar") == 0) return DASFRM_POLAR;
if( strcasecmp(sFT, "sphere_surface") == 0) return DASFRM_SPHERE_SURFACE;
if( strcasecmp(sFT, "cylindrical") == 0) return DASFRM_CYLINDRICAL;
if( strcasecmp(sFT, "spherical") == 0) return DASFRM_CYLINDRICAL;
if( strcasecmp(sFT, "cylindrical") == 0) return DASFRM_CYLINDRICAL;
if( strcasecmp(sFT, "spherical") == 0) return DASFRM_CYLINDRICAL;
if( strcasecmp(sFT, "planetocentric") == 0) return DASFRM_CENTRIC;
if( strcasecmp(sFT, "planetodetic") == 0) return DASFRM_DETIC;
if( strcasecmp(sFT, "planetographic") == 0) return DASFRM_GRAPHIC;

daslog_error_v("Unknown vector or coordinate frame type: '%s'.", sFT);
return 0;
Expand Down Expand Up @@ -81,6 +87,34 @@ DasFrame* new_DasFrame(DasDesc* pParent, ubyte id, const char* sName, const char
return NULL;
}

DasFrame* new_DasFrame2(DasDesc* pParent, ubyte id, const char* sName, ubyte uType)
{
DasFrame* pThis = (DasFrame*) calloc(1, sizeof(DasFrame));
DasDesc_init(&(pThis->base), FRAME);

if(sName != NULL) strncpy(pThis->name, sName, DASFRM_NAME_SZ-1);

if(id == 0){
das_error(DASERR_FRM, "Frame IDs must be in the range 1 to 255");
goto ERROR;
}

pThis->flags |= (uType & DASFRM_TYPE_MASK);
const char* sType = das_frametype2str(uType);
if(sType[0] == '\0')
goto ERROR;

strncpy(pThis->type, sType, DASFRM_TYPE_SZ-1);

if( DasFrame_setName(pThis, sName) != DAS_OKAY)
goto ERROR;

return pThis;
ERROR:
free(pThis);
return NULL;
}

DasFrame* copy_DasFrame(const DasFrame* pThis){

DasFrame* pCopy = (DasFrame*) calloc(1, sizeof(DasFrame));
Expand Down Expand Up @@ -131,11 +165,14 @@ char* DasFrame_info(const DasFrame* pThis, char* sBuf, int nLen)
/* Type and inertial */
if(nLen < 40) return pWrite;
switch(pThis->flags & DASFRM_TYPE_MASK){
case DASFRM_CARTESIAN : nWritten = snprintf(pWrite, nLen - 1, " | cartesian"); break;
case DASFRM_POLAR : nWritten = snprintf(pWrite, nLen - 1, " | polar"); break;
case DASFRM_CARTESIAN : nWritten = snprintf(pWrite, nLen - 1, " | cartesian"); break;
case DASFRM_POLAR : nWritten = snprintf(pWrite, nLen - 1, " | polar"); break;
case DASFRM_SPHERE_SURFACE: nWritten = snprintf(pWrite, nLen - 1, " | sphere_surface"); break;
case DASFRM_CYLINDRICAL : nWritten = snprintf(pWrite, nLen - 1, " | cylindrical"); break;
case DASFRM_SPHERICAL : nWritten = snprintf(pWrite, nLen - 1, " | spherical"); break;
case DASFRM_CYLINDRICAL : nWritten = snprintf(pWrite, nLen - 1, " | cylindrical"); break;
case DASFRM_SPHERICAL : nWritten = snprintf(pWrite, nLen - 1, " | spherical"); break;
case DASFRM_CENTRIC : nWritten = snprintf(pWrite, nLen - 1, " | planetocentric"); break;
case DASFRM_DETIC : nWritten = snprintf(pWrite, nLen - 1, " | planetodetic"); break;
case DASFRM_GRAPHIC : nWritten = snprintf(pWrite, nLen - 1, " | planetographic"); break;
default: nWritten = 0;
}

Expand Down Expand Up @@ -214,6 +251,72 @@ DasErrCode DasFrame_addDir(DasFrame* pThis, const char* sDir)
return DAS_OKAY;
}

/* Were going to go with ISO 31-11 on this */
DasErrCode DasFrame_setDefDirs(DasFrame* pThis)
{
switch(pThis->flags & DASFRM_TYPE_MASK){
case DASFRM_CARTESIAN:
strcpy(pThis->dirs[0], "x"); strcpy(pThis->dirs[1], "y"); strcpy(pThis->dirs[2], "z");
pThis->ndirs = 3;
break;
case DASFRM_POLAR:
strcpy(pThis->dirs[0], "r"); strcpy(pThis->dirs[1], "φ");
pThis->ndirs = 2;
break;
case DASFRM_SPHERE_SURFACE:
strcpy(pThis->dirs[0], "θ"); strcpy(pThis->dirs[1], "φ");
DasDesc_set((DasDesc*)pThis, "string", "description",
"θ is the angle from the north pole, φ is eastward angle"
);
pThis->ndirs = 2;
break;
case DASFRM_CYLINDRICAL:
strcpy(pThis->dirs[0], "ρ"); strcpy(pThis->dirs[1], "φ"); strcpy(pThis->dirs[2], "z");
DasDesc_set((DasDesc*)pThis, "string", "description",
"ρ is distance to the z-axis, φ is eastward angle"
);
pThis->ndirs = 3;
break;
case DASFRM_SPHERICAL:
strcpy(pThis->dirs[0], "r"); strcpy(pThis->dirs[1], "θ"); strcpy(pThis->dirs[2], "φ");
DasDesc_set((DasDesc*)pThis, "string", "description",
"θ is zero at the north pole (colatitude), φ is the eastward angle"
);
pThis->ndirs = 3;
break;
case DASFRM_CENTRIC:
strcpy(pThis->dirs[0], "r"); strcpy(pThis->dirs[1], "θ"); strcpy(pThis->dirs[2], "φ");
DasDesc_set((DasDesc*)pThis, "string", "description",
"θ is zero at the equator (latitude), φ is the eastward angle"
);
pThis->ndirs = 3;
break;

case DASFRM_DETIC:
strcpy(pThis->dirs[0], "r"); strcpy(pThis->dirs[1], "θ"); strcpy(pThis->dirs[2], "φ");
DasDesc_set((DasDesc*)pThis, "string", "description",
"Ellipsoidal coordinates, surface normals ususally do not intersect the origin. "
"θ is zero at the equator (latitude), φ is the eastward angle"
);
pThis->ndirs = 3;
break;
case DASFRM_GRAPHIC:
strcpy(pThis->dirs[0], "r"); strcpy(pThis->dirs[1], "θ"); strcpy(pThis->dirs[2], "φ");
DasDesc_set((DasDesc*)pThis, "string", "description",
"Ellipsoidal coordinates, surface normals ususally do not intersect the origin. "
"θ is zero at the equator (latitude), φ is the westward angle"
);
pThis->ndirs = 3;
break;

default:
return das_error(DASERR_FRM,
"Frame type %s has no default set of directions", pThis->name
);
}
return DAS_OKAY;
}

const char* DasFrame_dirByIdx(const DasFrame* pThis, int iIndex)
{
if(iIndex >= pThis->ndirs){
Expand All @@ -234,6 +337,34 @@ int8_t DasFrame_idxByDir(const DasFrame* pThis, const char* sDir)
return -1;
}

DasErrCode DasFrame_encode(
const DasFrame* pThis, DasBuf* pBuf, const char* sIndent, int nDasVer
){
char aIndent[24] = {'\0'};
strncpy(aIndent, sIndent, 21);
char* pWrite = strlen(sIndent) < 21 ? aIndent + strlen(sIndent) : aIndent + 21;
strcpy(pWrite, " ");

if(nDasVer != 3)
return das_error(DASERR_FRM, "Currently dasStream version %d is not supported", nDasVer);

DasBuf_puts(pBuf, sIndent);
DasBuf_printf(pBuf, "<frame name=\"%s\" type=\"%s\" >\n", pThis->name, pThis->type);

DasErrCode nRet = DasDesc_encode3((DasDesc*)pThis, pBuf, aIndent);
if(nRet != 0) return nRet;

/* Now handle my directions */
for(int i = 0; i < pThis->ndirs; ++i){
DasBuf_puts(pBuf, sIndent);
DasBuf_puts(pBuf, sIndent);
DasBuf_printf(pBuf, "<dir name=\"%s\"/>\n", pThis->dirs[i]);
}
DasBuf_puts(pBuf, sIndent);
DasBuf_puts(pBuf, "</frame>\n");
return DAS_OKAY;
}

void del_DasFrame(DasFrame* pThis)
{
// We have no sub-pointers, so this is just a type safe wrapper on free
Expand Down
50 changes: 44 additions & 6 deletions das2/frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,20 @@ extern "C" {
#endif

#define DASFRM_NAME_SZ 64
#define DASFRM_DNAM_SZ 32
#define DASFRM_DNAM_SZ 32 /* Direction name size */
#define DASFRM_TYPE_SZ 32
#define DASFRM_MAX_DIRS 4

#define DASFRM_TYPE_MASK 0x0000000F
#define DASFRM_UNKNOWN 0x00000000
#define DASFRM_CARTESIAN 0x00000001
#define DASFRM_POLAR 0x00000003
#define DASFRM_SPHERE_SURFACE 0x00000002
#define DASFRM_POLAR 0x00000002
#define DASFRM_SPHERE_SURFACE 0x00000003
#define DASFRM_CYLINDRICAL 0x00000004
#define DASFRM_SPHERICAL 0x00000005
#define DASFRM_SPHERICAL 0x00000005 /* ISO spherical using colatitude 0 = north pole */
#define DASFRM_CENTRIC 0x00000006 /* Spherical, but with 90 = north pole */
#define DASFRM_DETIC 0x00000007 /* Ellipsoidal, same angles as centric */
#define DASFRM_GRAPHIC 0x00000008 /* Ellipsoidal, longitude reversed */

#define DASFRM_INERTIAL 0x00000010

Expand Down Expand Up @@ -91,13 +94,25 @@ typedef struct frame_descriptor{
/** @} */

/** Create a new empty frame definition
* @param A coordinate name type string, such as "cartesian"
* @param sType A coordinate name type string, such as "cartesian"
* @memberof DasFrame
*/
DAS_API DasFrame* new_DasFrame(
DasDesc* pParent, ubyte id, const char* sName, const char* sType
);

/** Create a new empty frame definition, alternate interface
*
* @param uType A coordinate ID, one of: DASFRM_CARTESIAN, DASFRM_POLAR,
* DASFRM_SPHERE_SURFACE, DASFRM_CYLINDRICAL, DASFRM_SPHERICAL,
* DASFRM_CENTRIC, DASFRM_DETIC, DASFRM_GRAPHIC
*
* @memberof DasFrame
*/
DAS_API DasFrame* new_DasFrame2(
DasDesc* pParent, ubyte id, const char* sName, ubyte uType
);

/** Create a deepcopy of a DasFrame descriptor and all it's properties */
DAS_API DasFrame* copy_DasFrame(const DasFrame* pThis);

Expand Down Expand Up @@ -146,20 +161,43 @@ DAS_API ubyte DasFrame_getType(const DasFrame* pThis);
*/
DAS_API DasErrCode DasFrame_addDir(DasFrame* pThis, const char* sDir);

/** Set default direction names and descriptions based on the frame type.
*
* @return 0 if successful, non-zero if the frame type is not one of the
* builtin defaults.
*
* @memberof DasFrame
*/
DAS_API DasErrCode DasFrame_setDefDirs(DasFrame* pThis);

/** Given the index of a frame direction, return it's name
*
* @memberof DasFrame
*/
DAS_API const char* DasFrame_dirByIdx(const DasFrame* pThis, int iIndex);

/** Givin the name of a frame direction, return it's index
/** Given the name of a frame direction, return it's index
*
* @return A signed byte. If the value is less then 0 then that direction is not defined
*
* @memberof DasFrame
*/
DAS_API int8_t DasFrame_idxByDir(const DasFrame* pThis, const char* sDir);

/** Encode a frame definition into a buffer
*
* @param pThis The vector frame to encode
* @param pBuf A buffer object to receive the XML data
* @param sIndent An indent level for the frame
* @param nDasVer expects 3 or higher
* @return 0 if the operation succeeded, a non-zero return code otherwise.
* @memberof DasDesc
*/
DAS_API DasErrCode DasFrame_encode(
const DasFrame* pThis, DasBuf* pBuf, const char* sIndent, int nDasVer
);


/** Free a frame definition that was allocated on the heap
*
* @memberof DasFrame
Expand Down
Loading

0 comments on commit be8152b

Please sign in to comment.