Sindbad~EG File Manager

Current Path : /home/beeson/ThreeBody/ThreeBodyProblem/
Upload File :
Current File : //home/beeson/ThreeBody/ThreeBodyProblem/ThreeBody.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>  //  access()  and gethostname()
#include <math.h>

#include "uthash.h"
#include "ThreeBodyDoc.h"
#include "textwidth.h"
#include "svgGraph3.h"
#include "ode3.h"

void init_docData3(PDOCDATA3 pDocData, char *sessionId, char *param) {
    // The param string format is:
    // sessionId~pxmin~pxmax~pymin~pymax~border~background
    //        ~tmax
    //        ~integrationMethod    ("rk4" or "leapfrog")
    //        ~graphpaper           (index, -1 means no graph paper)
    //        ~numBodies
    //        ~body1~body2~...~bodyN
    // where each body is encoded as:
    // mass;R,G,B;radius;x0;y0;p0;q0
    pDocData->tmin = 0.0;  // without loss of generality
    char *saveptr1 = NULL;
    // 1st token: sessionId
    char *token = strtok_r(param, "~", &saveptr1);
    if (token == NULL) {
        fprintf(stderr, "init_docData3: Missing sessionId in param.\n");
        return;
    }
    // Copy sessionId into the structure (ensure no overflow)
    strncpy(pDocData->sessionId, token, MAX_SESSIONID);
    pDocData->sessionId[MAX_SESSIONID - 1] = '\0';

    // 2nd token: pxmin
    token = strtok_r(NULL, "~", &saveptr1);
    if (token == NULL) {
        fprintf(stderr, "init_docData3: Missing pxmin in param.\n");
        return;
    }
    pDocData->pxmin = atoi(token);

    // 3rd token: pxmax
    token = strtok_r(NULL, "~", &saveptr1);
    if (token == NULL) {
        fprintf(stderr, "init_docData3: Missing pxmax in param.\n");
        return;
    }
    pDocData->pxmax = atoi(token);

    // 4th token: pymin
    token = strtok_r(NULL, "~", &saveptr1);
    if (token == NULL) {
        fprintf(stderr, "init_docData3: Missing pymin in param.\n");
        return;
    }
    pDocData->pymin = atoi(token);

    // 5th token: pymax
    token = strtok_r(NULL, "~", &saveptr1);
    if (token == NULL) {
        fprintf(stderr, "init_docData3: Missing pymax in param.\n");
        return;
    }
    pDocData->pymax = atoi(token);

   pDocData->xmin = -4;
   pDocData->xmax = 4;
   double aspectratio = fabs( (pDocData->pymax - pDocData->pymin)/(double)(pDocData->pxmax-pDocData->pxmin));
   double height = (pDocData->xmax - pDocData->xmin) * aspectratio;
   pDocData->ymin = - height/2;
   pDocData->ymax = height/2;

    // 6th token: border
    token = strtok_r(NULL, "~", &saveptr1);
    if (token == NULL) {
        fprintf(stderr, "init_docData3: Missing border in param.\n");
        return;
    }
    pDocData->border = (unsigned)atoi(token);

    // 7th token: background
    token = strtok_r(NULL, "~", &saveptr1);
    if (token == NULL) {
        fprintf(stderr, "init_docData3: Missing background in param.\n");
        return;
    }
    pDocData->background = (unsigned)atoi(token);
    
     // 8th token: tmax
    token = strtok_r(NULL, "~", &saveptr1);
    if (token == NULL) {
        fprintf(stderr, "init_docData3: Missing tmax in param.\n");
        return;
    }
   int nfields = sscanf(token,"%lf",&pDocData->tmax);
   if(nfields != 1){
        fprintf(stderr, "init_docData3: tmax must be a number \n");
        return;
    }
   
    // 9th token: integrationMethod
    token = strtok_r(NULL, "~", &saveptr1);
    if (token == NULL) {
        fprintf(stderr, "init_docData3: Missing integration method in param.\n");
        return;
    }
   strncpy(pDocData->integrationMethod,token,32);
   
   // 10th token: graphpaper
   token = strtok_r(NULL, "~", &saveptr1);
   if (token == NULL) {
      fprintf(stderr, "init_docData3: Missing background in param.\n");
      return;
   }
   pDocData->graphpaper = (unsigned)atoi(token);
    
    // 11th token: number of bodies
    token = strtok_r(NULL, "~", &saveptr1);
    if (token == NULL) {
        fprintf(stderr, "init_docData3: Missing number of bodies in param.\n");
        return;
    }
    int nbodies = atoi(token);
    if (nbodies < 0)
        nbodies = 0;
    if (nbodies > MAXBODIES)
        nbodies = MAXBODIES;
    pDocData->nbodies = nbodies;

    // Now parse each body's data.
    for (int i = 0; i < nbodies; i++) {
        token = strtok_r(NULL, "~", &saveptr1);
        if (token == NULL) {
            fprintf(stderr, "init_docData3: Missing data for body %d.\n", i);
            break;
        }
        // token format: mass;R,G,B;radius;x0;y0;p0;q0
        char *saveptr2 = NULL;
        // mass
        char *part = strtok_r(token, ";", &saveptr2);
        if (part == NULL) continue;
        pDocData->bodies[i].mass = atof(part);
        pDocData->bodies[i].bodynumber = i;

        // color in R,G,B
        part = strtok_r(NULL, ";", &saveptr2);
        if (part == NULL) continue;
        int r, g, b;
        if (sscanf(part, "%d,%d,%d", &r, &g, &b) != 3) {
            fprintf(stderr, "init_docData3: Invalid color for body %d.\n", i);
            continue;
        }
        pDocData->bodies[i].color = RGB(r,g,b);

        // radius
        part = strtok_r(NULL, ";", &saveptr2);
        if (part == NULL) continue;
        pDocData->bodies[i].r = atof(part);

        // x0
        part = strtok_r(NULL, ";", &saveptr2);
        if (part == NULL) continue;
        pDocData->bodies[i].x0 = atof(part);

        // y0
        part = strtok_r(NULL, ";", &saveptr2);
        if (part == NULL) continue;
        pDocData->bodies[i].y0 = atof(part);

        // p0
        part = strtok_r(NULL, ";", &saveptr2);
        if (part == NULL) continue;
        pDocData->bodies[i].p0 = atof(part);

        // q0
        part = strtok_r(NULL, ";", &saveptr2);
        if (part == NULL) continue;
        pDocData->bodies[i].q0 = atof(part);
    }
}

int process_message3(PDOCDATA3 pDocData, char *message, char *param, char *outbuffer, int outbuffersize)
{ memset(outbuffer, 0, outbuffersize);
  reset_arrays();
  if(!strcmp(message,"newDocument") || !strcmp(message, "saveSVG"))
     { // pDocData has already been initialized
       // when the following code finishes, the SVG is in outbuffer,
       // ready either to be sent or saved.
       
        computeSolution(pDocData);
        rect r;
        int err;
        r.left = 0;
        r.top = 0;
        r.bottom = pDocData->pymax;
        r.right= pDocData->pxmax;
        set_svgDevice(outbuffer,outbuffersize, &r);
        svgDevice *theDevice = get_device();
        err = sendDocument3(pDocData);
        int byteswritten = (int) strlen(theDevice->next);
        theDevice->next += byteswritten;
        relinquish_device();
        return err;
     }
  return 1;
}

/*___________________________________________________________________*/
int saveAsSVG(char *outbuffer, char *filename, char *errmsg)
// filename is relative to the images directory, where to save the document as an SVG file.
// If filename doesn't end in .svg, add that at the end.
// The caller is supposed to make sure it has either no file extension or .svg,
// is not NULL, and is already trimmmed of beginning or ending whitespace.
// The PHP that sends the "saveAsSVG" message will save the document's data
// to ThreeBodyDatabase.db, so that is not done in the Engine.
// Return 0 for success, 1 for file error; errmsg will hold up to 128 chars.
// This function should not modify outbuffer,  which will subsequently be
// sent to the browser for display. 
{
    char images[256];
    int n;
    const char *imageDir;
    
    // Detect environment
    char hostname[256];
    gethostname(hostname, sizeof(hostname));
    printf("DEBUG: hostname = [%s]\n", hostname);
    // Choose image directory based on host
    if (strstr(hostname, "local"))
       imageDir = "/Users/beeson/Dropbox/Sites/WebMathXpert/ThreeBodyWeb/images/";
    else
       imageDir = "/home/beeson/public_html/WebMathXpert/ThreeBodyWeb/images/";
    // Build the full path using snprintf.
    n = snprintf(images, sizeof(images), "%s%s", imageDir, filename);
    if (n < 0 || n >= (int)sizeof(images)) {
        snprintf(errmsg, 128, "Filename too long or formatting error");
        return 1;
    }

    // Ensure the resulting filename ends with ".svg"
    size_t len = strlen(images);
    if (len < 4 || strcmp(images + len - 4, ".svg") != 0) {
        if (len + 4 >= sizeof(images)) {
            snprintf(errmsg, 128, "Not enough space for .svg extension");
            return 1;
        }
        strcat(images, ".svg");
    }

    // Check if the file already exists.
    if (access(images, F_OK) == 0) {
        snprintf(errmsg, 128, "File already exists: %.100s", images);
        return 1;
    }
    // Trim outbuffer to remove extra content after the closing </svg>
    char *closeTagPos = strstr(outbuffer, "</svg>");
    if (closeTagPos != NULL) {
        closeTagPos += strlen("</svg>");
        // Calculate new length up to and including the closing </svg>
        size_t newLen = closeTagPos - outbuffer;
        // Terminate the string at that point.
        outbuffer[newLen] = '\0';
    }
    // replace "mywidth" by "  width" and "myheight" by "  height"
    // so the browser can scale it
   char *marker = strstr(outbuffer, "mywidth");
   if (marker)
      memcpy(marker, "  width", 7);
      // exactly 7 bytes, no null terminator needed here
   marker = strstr(outbuffer, "myheight");
   if (marker)
      memcpy(marker, "  height", 7);  //
    // Open the file for writing.
    FILE *fp = fopen(images, "w");
    if (fp == NULL) {
        snprintf(errmsg, 128, "Unable to open file: %.100s", images);
        return 1;
    }

    // Write the outbuffer (SVG data) into the file.
    if (fputs(outbuffer, fp) == EOF) {
        snprintf(errmsg, 128, "Error writing to file: %.100s", images);
        fclose(fp);
        return 1;
    }

    fclose(fp);
    return 0;
}

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists