home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / modules / libfont / src / wfMisc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  9.8 KB  |  525 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /* 
  19.  *
  20.  * All function that are of general use in libfont/ are implemented here.
  21.  *
  22.  * dp Suresh <dp@netscape.com>
  23.  */
  24.  
  25.  
  26. #include "libfont.h"
  27. #include "nf.h"
  28. #include "wfMisc.h"
  29. #include "Mnffmi.h"
  30.  
  31. #ifdef NSPR20
  32. #ifdef XP_MAC
  33. #include "probslet.h"
  34. #else
  35. #include "obsolete/probslet.h"
  36. #endif
  37. #endif
  38.  
  39.  
  40. // The logic we are using to merge these is brute force.
  41. // For each size in newSizes list, if it is already in the oldSizes,
  42. // then we wont add it. If not we will add it in.
  43. // We should make sure the we are using the public memory allocator
  44. // here because this memory is expected to be freed by the caller.
  45. #define INTS_AT_A_TIME 128
  46. void
  47. MergeSizes(jdouble * &oldSizes, int &oldLenMax, jdouble *newSizes)
  48. {
  49.     int newlen = 0;
  50.     
  51.     if (!newSizes)
  52.       {
  53.         return;
  54.       }
  55.     
  56.     while (newSizes[newlen] >= 0)
  57.       {
  58.         int i = 0;
  59.         int found = 0;
  60.         if (oldSizes == NULL)
  61.           {
  62.             oldSizes = (jdouble *) WF_ALLOC(sizeof(*oldSizes) * INTS_AT_A_TIME);
  63.             if (!oldSizes) return;
  64.             oldSizes[0] = -1;
  65.             oldLenMax = INTS_AT_A_TIME;
  66.           }
  67.         for (;oldSizes[i] >= 0; i++)
  68.           {
  69.             if (newSizes[newlen] == oldSizes[i])
  70.               {
  71.                 found++;
  72.                 break;
  73.               }
  74.           }
  75.         if (!found)
  76.           {
  77.             // Add newSizes[newlen] to oldSizes
  78.             if (i >= oldLenMax-1)
  79.               {
  80.                 // Need more memory.
  81.                 oldSizes = (jdouble *)
  82.                   WF_REALLOC(oldSizes,
  83.                              sizeof(*oldSizes) * (oldLenMax + INTS_AT_A_TIME));
  84.                 if (!oldSizes) return;
  85.                 oldLenMax += INTS_AT_A_TIME;
  86.               }
  87.             oldSizes[i++] = newSizes[newlen];
  88.             oldSizes[i++] = -1;
  89.           }
  90.         newlen++;
  91.       }
  92. }
  93.  
  94. //
  95. // CopyString
  96. //
  97. // Make a copy of the input C-String and return a new C++ allocated
  98. // C-String.
  99. //
  100. char *
  101. CopyString(const char *str)
  102. {
  103.     char *newStr = NULL;
  104.     int len = 0;
  105.     const char *tmp1;
  106.     char *tmp2;
  107.  
  108.     if (str && *str)
  109.       {
  110.         for (tmp1=str; *tmp1; len++, tmp1++);
  111.         newStr = new char[len+1];
  112.         if (newStr)
  113.           {
  114.             for (tmp1=str, tmp2=newStr; *tmp1; *tmp2++ = *tmp1++);
  115.             *tmp2 = '\0';
  116.           }
  117.       }
  118.     return (newStr);
  119. }
  120.  
  121.  
  122. //
  123. // Returns a newly allocated string that Escapes characters {:-*\}
  124. // in the input str.
  125. // For eg.
  126. //    input string    : string-to*be-escaped\n
  127. //    return        : string\-to\*be\-escaped\\n
  128. //
  129. // WARNING: Caller must delete the return string.
  130.  
  131. char *
  132. EscapeString(const char *str, const char *escapeThese)
  133. {
  134.     if (!str || !*str)
  135.     {
  136.         return NULL;
  137.     }
  138.     char *newstr = new char [2*strlen(str)+1];
  139.     if (!newstr)
  140.     {
  141.         // ERROR: No memory
  142.         return (NULL);
  143.     }
  144.     char* t = newstr;
  145.     while (*str)
  146.     {
  147.         if (strchr(escapeThese, *str))
  148.             *t++ = '\\';
  149.         *t++ = *str++;
  150.     }
  151.     *t = '\0';
  152.     return (newstr);
  153. }
  154.  
  155. //
  156. // ScanToken
  157. //  Scans a token delimited by 'stopChars' from 'str' and copies it out
  158. //    into 'buf'
  159. //    By default this compresses multiple spaces in the token to a single space.
  160. //    If 'noSpacesOnOutput' is set, all spaces, leading/trailing/intermediate
  161. //    spaces are stripped.
  162. //
  163. //    Returns a pointer to the character after the token in 'str'
  164. //
  165. const char *
  166. wf_scanToken(const char *str, char *buf, int len, char *stopChars,
  167.             int noSpacesOnOutput)
  168. {
  169.     int pos = 0;
  170.  
  171.     str = wf_skipSpaces(str);
  172.  
  173.     while (*str != '\0')
  174.     {
  175.         while (*str != '\0' && ! isspace(*str) &&
  176.             (stopChars == NULL || strchr(stopChars, *str) == NULL))
  177.         {
  178.             buf[pos++] = *str++;
  179.         }
  180.  
  181.         str = wf_skipSpaces(str);
  182.         if (*str == '\0' || stopChars == NULL ||
  183.             strchr(stopChars, *str) != NULL)
  184.         {
  185.             break;
  186.         }
  187.         if (! noSpacesOnOutput)
  188.         {
  189.             buf[pos++] = ' ';
  190.         }
  191.     }
  192.     buf[pos] = '\0';
  193.     return str;
  194. }
  195.  
  196. //
  197. // wf_scanVariableAndValue
  198. // Modifies buf such that variable and value point to the the LHS and RHS of
  199. // a buf of the format " variable = value "
  200. // Leading and trailing spaces for both variable and value are trimmed.
  201. //
  202. int
  203. wf_scanVariableAndValue(char *buf, int buflen, char *&variable, char *&value)
  204. {
  205.     variable = buf;
  206.     value = NULL;
  207.     while (*buf && *buf != '=')
  208.     {
  209.         buf ++;
  210.     }
  211.     if ('=' == *buf)
  212.     {
  213.         *buf = '\0';
  214.         buf++;
  215.         value = buf;
  216.     }
  217.     variable = wf_trimSpaces(variable);
  218.     value = wf_trimSpaces(value);
  219.     return (0);
  220. }
  221.  
  222. /*
  223.  * wf_StringEndsWith
  224.  *
  225.  * returns nonzero if string 's' ends with string 'endstr'
  226.  * else returns zero
  227.  */
  228. int
  229. wf_stringEndsWith(const char *s, const char *endstr)
  230. {
  231.   int l, lend;
  232.   int retval = 0;
  233.  
  234.   if (!endstr)
  235.   {
  236.       /* All strings ends in NULL */
  237.       retval = 1;
  238.   }
  239.   else if (!s)
  240.   {
  241.       /* NULL strings will never have endstr at its end */
  242.       retval = 0;
  243.   }
  244.   else
  245.   {
  246.       lend = strlen(endstr);
  247.       l = strlen(s);
  248. #ifdef XP_WIN
  249.       if (l >= lend && !stricmp(s+l-lend, endstr))  /* ignore case for windows */
  250. #else
  251.       if (l >= lend && !strcmp(s+l-lend, endstr))
  252. #endif
  253.       {
  254.           retval = 1;
  255.       }
  256.   }
  257.   return (retval);
  258. }
  259.  
  260.  
  261. //
  262. // wf_skipSpaces
  263. // Returns a pointer to the first non-space character in 'str'
  264. //
  265. const char *
  266. wf_skipSpaces(const char *str)
  267. {
  268.     while (*str != '\0' && isspace(*str))
  269.     {
  270.         str++;
  271.     }
  272.     return str;
  273. }       
  274.  
  275.  
  276. //
  277. // wf_trimSpaces
  278. // Trims initial and trailing spaces from the input string.
  279. //
  280. char *
  281. wf_trimSpaces(char *inputString)
  282. {
  283.     char *str = inputString;
  284.  
  285.     if (!str || !*str)
  286.     {
  287.         return (str);
  288.     }
  289.  
  290.     // Fix trailing spaces
  291.     int nstr = strlen(str);
  292.     int len = nstr;
  293.     while (len && isspace(str[len-1]))
  294.     {
  295.         --len;
  296.     }
  297.     if (len < nstr)
  298.     {
  299.         str[len] = '\0';
  300.         nstr = len+1;
  301.     }
  302.  
  303.     // Fix leading spaces
  304.     while (*str && isspace(*str))
  305.     {
  306.         str++;
  307.         nstr--;
  308.     }
  309.     if (str != inputString)
  310.     {
  311.         memmove(inputString, str, nstr+1);
  312.     }
  313.     
  314.     return (inputString);
  315. }
  316.  
  317. //
  318. // Returns
  319. // 0    : if both strings are the same on a case insensitive compare
  320. // -1    : if any of the string were NULL
  321. // 1    : if string 'two' is a case insensitive substring of string 'one'
  322. // 2    : if string 'one' is a case insensitive substring of string 'two'
  323. // 3    : if case insensitive compare failed
  324. //
  325. int
  326. wf_strcasecmp(const char *one, const char *two)
  327. {
  328.     if (!one || !two)
  329.     {
  330.         return (-1);
  331.     }
  332.  
  333.     for(; *one && *two; one++, two++)
  334.     {
  335.         if ((*one != *two) && (tolower(*one) != tolower(*two)))
  336.             return (3);
  337.     }
  338.     if (*one)
  339.         return (1);
  340.     if (*two)
  341.         return (2);
  342.     return 0;
  343. }
  344.  
  345. //
  346. // return 0 if the 2 strings are same on case insensitive compare upto
  347. //        atmost n bytes
  348. // else -1
  349. //
  350. int
  351. wf_strncasecmp(const char *one, const char *two, int n)
  352. {
  353.     if (!one || !two)
  354.     {
  355.         return (-1);
  356.     }
  357.  
  358.     for(; *one && *two && n-- > 0; one++, two++)
  359.     {
  360.         if ((*one != *two) && (tolower(*one) != tolower(*two)))
  361.             return (-1);
  362.     }
  363.  
  364.     if (n <= 0 || (*one == '\0' && *two == '\0'))
  365.         return (0);
  366.     else
  367.         return (-1);
  368. }
  369.  
  370.  
  371. // returns a pointer to the extension part of the input string
  372. const char *wf_getExtension(const char *fullname)
  373. {
  374.     const char *ext = NULL;
  375.     if (!fullname || !*fullname)
  376.     {
  377.         return (ext);
  378.     }
  379.  
  380.     while (*fullname)
  381.     {
  382.         if (*fullname == '.')
  383.         {
  384.             ext = fullname+1;
  385.         }
  386.         fullname++;
  387.     }
  388.     return(ext);
  389. }
  390.  
  391. int wf_addToString(char **str, int *len, int *maxlen, const char *s)
  392. {
  393.     if (!s || !*s)
  394.     {
  395.         return (0);
  396.     }
  397.  
  398.     if (!maxlen || !str)
  399.     {
  400.         // Invalid params.
  401.         return (-1);
  402.     }
  403.  
  404.     int slen = strlen(s);
  405.     int curlen = 0;
  406.     if (!len)
  407.     {
  408.         curlen = strlen(*str);
  409.     }
  410.     else
  411.     {
  412.         curlen = *len;
  413.     }
  414.  
  415.     if (curlen + slen + 1 > *maxlen)
  416.     {
  417.         int newlen = WF_ROUND_INT(curlen+slen+1, WF_STRING_ALLOCATION_STEP);
  418.         *str = (char *)WF_REALLOC(*str, sizeof(char)*newlen);
  419.         if (!*str)
  420.         {
  421.             // No memory
  422.             return (-1);
  423.         }
  424.         *maxlen = newlen;
  425.     }
  426.     memcpy((*str)+curlen, s, slen+1);
  427.  
  428.     if (len)
  429.     {
  430.         *len += slen;
  431.     }
  432.  
  433.     return (0);
  434. }
  435.  
  436. //
  437. // Webfont related miscellaneous routines
  438. //
  439.  
  440. int
  441. wf_releaseFmis(struct nffmi **fmis)
  442. {
  443.     if (!fmis)
  444.     {
  445.         return (-1);
  446.     }
  447.     while (*fmis)
  448.     {
  449.         nffmi_release(*fmis, NULL);
  450.         fmis++;
  451.     }
  452.     return (0);    
  453. }
  454.  
  455.  
  456. //-----------------
  457. // File operations
  458. //-----------------
  459.  
  460. int wf_isFileReadable(const char *filename)
  461. {
  462.     if (!filename || !*filename)
  463.         return (-1);
  464.  
  465.     FILE *fp = fopen(filename, "r");
  466.     int readable = (fp != NULL);
  467.     fclose(fp);
  468.  
  469.     return (readable);
  470. }
  471.  
  472. int wf_isFileDirectory(const char *filename)
  473. {
  474.     if (!filename || !*filename)
  475.         return (0);
  476.  
  477.     PRFileInfo finfo;
  478.  
  479.     if (PR_GetFileInfo(filename, &finfo) == PR_FAILURE)
  480.         return (0);
  481.  
  482.     return (finfo.type == PR_FILE_DIRECTORY);
  483. }
  484.  
  485.  
  486. //
  487. // expandFileName:
  488. //
  489. // expands the following in the filename
  490. // beginning ~    : HOME
  491. //
  492. // Returns the no: of expansions done. If none was done, returns 0.
  493. // Returns -ve if there was no space to do the expansion.
  494. //
  495. extern int wf_expandFilename(char *filename, int maxlen)
  496. {
  497.     int ret = 0;
  498.  
  499.     // Expand initial ~ to HOME
  500.     if (*filename == '~')
  501.     {
  502.         const char *home = getenv("HOME");
  503.         if (home && *home)
  504.         {
  505.             // Insert home into filename
  506.             int homelen = strlen(home);
  507.             int len = strlen(filename);
  508.             
  509.             if (len+homelen <= maxlen)
  510.             {
  511.                 // Shift all characters in filename by homelen bytes
  512.                 memmove(filename+homelen, filename+1, len);
  513.                 // Copy home into filename
  514.                 memcpy(filename, home, homelen);
  515.                 ret ++;
  516.             }
  517.             else
  518.             {
  519.                 ret = -1;
  520.             }
  521.         }
  522.     }
  523.     return (ret);
  524. }
  525.