Back to index

lightning-sunbird  0.9+nobinonly
stdlib.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is mozilla.org code, released
00017  * Jan 28, 2003.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 2003
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   Garrett Arch Blythe, 28-January-2003
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either the GNU General Public License Version 2 or later (the "GPL"), or
00029  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 #include <string.h>
00041 #include <stdio.h>
00042 
00043 #include <windows.h>
00044 #include <aygshell.h>
00045 
00046 #include "mozce_internal.h"
00047 
00048 #define _MAX_FNAME          256
00049 #define _MAX_DIR            _MAX_FNAME
00050 #define _MAX_EXT            _MAX_FNAME
00051 
00052 
00053 extern "C" {
00054 #if 0
00055 }
00056 #endif
00057 
00058 // #define LOG_CALLS
00059 
00060 MOZCE_SHUNT_API char *mozce_fullpath(char *absPath, const char *relPath, size_t maxLength)
00061 {
00062     MOZCE_PRECHECK
00063         
00064 #ifdef LOG_CALLS
00065 #ifdef DEBUG
00066         mozce_printf("mozce_fullpath called\n");
00067 #endif
00068 #endif
00069     
00070     if (relPath[0] != '\\') 
00071     {
00072         int i;
00073         unsigned short dir[MAX_PATH];
00074         GetModuleFileName(GetModuleHandle (NULL), dir, MAX_PATH);
00075         for (i = _tcslen(dir); i && dir[i] != TEXT('\\'); i--) {}
00076         
00077         dir[i + 1] = TCHAR('\0');
00078         
00079         w2a_buffer(dir, -1, absPath, maxLength);
00080     }
00081     strcat(absPath, relPath);
00082     
00083     return absPath;
00084 }
00085 
00086 MOZCE_SHUNT_API void mozce_splitpath(const char* inPath, char* outDrive, char* outDir, char* outFname, char* outExt)
00087 {
00088     MOZCE_PRECHECK
00089         
00090 #ifdef LOG_CALLS
00091 #ifdef DEBUG
00092         mozce_printf("mozce_splitpath called\n");
00093 #endif
00094 #endif
00095     if(NULL != outDrive)
00096     {
00097         *outDrive = '\0';
00098     }
00099     if(NULL != outDir)
00100     {
00101         *outDir = '\0';
00102     }
00103     if(NULL != outFname)
00104     {
00105         *outFname = '\0';
00106     }
00107     if(NULL != outExt)
00108     {
00109         *outExt = '\0';
00110     }
00111     
00112     if(NULL != inPath && '\0' != *inPath)
00113     {
00114         char* dup = (char*) malloc(strlen(inPath)+1);
00115         if(NULL != dup)
00116         {
00117             strcpy(dup, inPath);
00118             /*
00119             **  Change all forward slashes to back.
00120             */
00121             char* convert = dup;
00122             do
00123             {
00124                 if('/' == *convert)
00125                 {
00126                     *convert = '\\';
00127                 }
00128                 convert++;
00129             }
00130             while(*convert);
00131             
00132             /*
00133             **  Find last slash first.
00134             */
00135             char* slash = strrchr(dup, '\\');
00136             
00137             /*
00138             **  Find extension, must be after any slash.
00139             */
00140             char* ext = NULL;
00141             if(NULL == slash)
00142             {
00143                 ext = strchr(dup, '.');
00144             }
00145             else
00146             {
00147                 ext = strchr(slash, '.');
00148             }
00149             
00150             /*
00151             **  Reap extension.
00152             */
00153             if(NULL != ext)
00154             {
00155                 if(NULL != outExt)
00156                 {
00157                     strncpy(outExt, ext, _MAX_EXT);
00158                 }
00159                 
00160                 *ext = '\0';
00161             }
00162             
00163             /*
00164             **  Reap filename.
00165             */
00166             char* fname = NULL;
00167             if(NULL == slash)
00168             {
00169                 fname = dup;
00170             }
00171             else
00172             {
00173                 fname = slash + 1;
00174             }
00175             
00176             if(NULL != outFname)
00177             {
00178                 strncpy(outFname, fname, _MAX_FNAME);
00179             }
00180             
00181             *fname = '\0';
00182             
00183             /*
00184             **  Reap directory.
00185             */
00186             if(NULL != slash && NULL != outDir)
00187             {
00188                 strncpy(outDir, dup, _MAX_DIR);
00189             }
00190             
00191             free(dup);
00192         }
00193     }
00194 }
00195 
00196 
00197 MOZCE_SHUNT_API void mozce_makepath(char* outPath, const char* inDrive, const char* inDir, const char* inFname, const char* inExt)
00198 {
00199     MOZCE_PRECHECK
00200         
00201 #ifdef LOG_CALLS
00202 #ifdef DEBUG
00203         mozce_printf("mozce_makepath called\n");
00204 #endif
00205 #endif
00206     if(NULL != outPath)
00207     {
00208         int dirLen = 0;
00209         if(NULL != inDir)
00210         {
00211             dirLen = strlen(inDir);
00212             if(dirLen)
00213             {
00214                 dirLen--;
00215             }
00216         }
00217         _snprintf(outPath, _MAX_PATH, "%s%s%s%s%s",
00218                   (NULL != inDir) ? inDir : "",
00219                   (NULL != inDir && '\\' != inDir[dirLen] && '/' != inDir[dirLen]) ? "\\" : "",
00220                   (NULL != inFname) ? inFname : "",
00221                   (NULL != inExt && '.' != inExt[0]) ? "." : "",
00222                   (NULL != inExt) ? inExt : ""
00223                   );
00224     }
00225 }
00226 
00227 MOZCE_SHUNT_API int mozce_strcmpi(const char *dest, const char *src)
00228 {
00229     MOZCE_PRECHECK
00230         
00231 #ifdef LOG_CALLS
00232 #ifdef DEBUG
00233         mozce_printf("mozce_strcmpi called\n");
00234 #endif
00235 #endif
00236     int f,l;
00237     
00238     do {
00239         if ( ((f = (unsigned char)(*(dest++))) >= 'A') && (f <= 'Z') )
00240             f -= ('A' - 'a');
00241         
00242         if ( ((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z') )
00243             l -= ('A' - 'a');
00244     } while ( f && (f == l) );
00245     
00246     return(f - l);
00247 }
00248 
00249 
00250 
00251 static int gDelayBeforeResending = 1000;
00252 static int gFirstRun = 1;
00253 static unsigned long gTotalMemoryAllocated = 0;
00254 static unsigned long gTotalMemoryAllowed = 0;
00255 static unsigned long gLastTickCount = 0;
00256 
00257 static void setAllocationUpperLimit()
00258 {
00259     MEMORYSTATUS mst;
00260     mst.dwLength  = sizeof(MEMORYSTATUS);
00261     GlobalMemoryStatus(&mst);
00262 
00263     gTotalMemoryAllowed = mst.dwAvailPhys / 2; /* XXX should be configurable */
00264 
00265     gLastTickCount = GetTickCount() - gDelayBeforeResending;
00266 }
00267 
00268 
00269 void SendOOMPending()
00270 {
00271 
00272     DWORD lastTickCount = GetTickCount();
00273 
00274     if (lastTickCount >= gLastTickCount + gDelayBeforeResending)
00275     {
00276         char buffer[4] = "OOM";
00277         COPYDATASTRUCT cds = { 0, 4, buffer };
00278         
00279         // XXX The name of this window is Minimo specific.
00280         // Probably should generalize.
00281         
00282         HWND a = FindWindowW(L"MINIMO_LISTENER", NULL);
00283         PostMessage(a, WM_COPYDATA, NULL, (LPARAM)&cds); 
00284 
00285         gLastTickCount = GetTickCount();
00286     }
00287 }
00288 
00289 static void memoryCheck()
00290 {
00291     if (gFirstRun)
00292     {
00293         setAllocationUpperLimit();
00294         gFirstRun = 0;
00295     }
00296 
00297     if (gTotalMemoryAllocated > gTotalMemoryAllowed)
00298     {
00299         SendOOMPending();
00300     }
00301 }
00302 
00303 static void oom()
00304 {
00305     // We can't really do anything else.
00306     SendOOMPending();
00307 }
00308 
00309 MOZCE_SHUNT_API void *mozce_malloc(unsigned a)
00310 {
00311     gTotalMemoryAllocated += a;
00312     memoryCheck();
00313 
00314     void *buffer = malloc(a);
00315     if (!buffer)
00316     {
00317         SHCloseApps(a);
00318         buffer = malloc(a);
00319 
00320         if (!buffer)
00321             oom();
00322     }
00323     return buffer;
00324 }
00325 
00326 MOZCE_SHUNT_API void  mozce_free(void* a)
00327 {
00328     if (!a)
00329         return;
00330 
00331     gTotalMemoryAllocated -= _msize(a);
00332     memoryCheck();
00333 
00334     free(a);
00335 }
00336 
00337 MOZCE_SHUNT_API void *mozce_realloc(void* a, unsigned b)
00338 {
00339     gTotalMemoryAllocated += b;
00340     gTotalMemoryAllocated -= _msize(a);
00341     memoryCheck();
00342     
00343     void *buffer = realloc(a,b);
00344     if (!buffer)
00345     {
00346         SHCloseApps(b);
00347         buffer = realloc(a,b);
00348 
00349         if (!buffer)
00350             oom();
00351     }
00352     return buffer;
00353 }
00354 
00355 
00356 MOZCE_SHUNT_API void *mozce_calloc(size_t n, size_t nelem)
00357 {
00358     gTotalMemoryAllocated += n*nelem;
00359     memoryCheck();
00360 
00361     void* buffer = calloc(n, nelem);
00362     if (!buffer)
00363     {
00364         SHCloseApps(n*nelem);
00365         buffer = calloc(n, nelem);
00366 
00367         if (!buffer)
00368             oom();
00369     }
00370     return buffer;
00371 }
00372 
00373 #if 0
00374 {
00375 #endif
00376 } /* extern "C" */