STATIC IElement DIR_ItrNext(Iterator * itr) { Win32DirIterator * w = CAST(itr,Win32DirIterator,common.itr); DirIterator * di = &w->common; /* this must succeed because we have preallocated the memory */ VERIFY(STRBUF_Copy(&di->fileName, w->data.cFileName)); if (w->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { di->entry.type = DTypeDir; } else { di->entry.type = DTypeFile; } /* find the next entry */ di->hasNext = False; while (FindNextFile(w->handle, &w->data)) { if (StrCmp(w->data.cFileName,TEXT(".")) && StrCmp(w->data.cFileName,TEXT(".."))) { /* preallocate space for the file name */ if (STRBUF_Alloc(&di->fileName, StrLen(w->data.cFileName))) { di->hasNext = True; } break; } } di->entry.dir = STRBUF_Text(&di->dirName); di->entry.name = STRBUF_Text(&di->fileName); return &di->entry; }
Bool DIR_ItrRemove(Iterator * itr) { Bool ok = False; DirIterator * di = CAST(itr,DirIterator,itr); DirType type = di->entry.type; size_t dirlen = STRBUF_Length(&di->dirName); if (STRBUF_Alloc(&di->dirName, dirlen+STRBUF_Length(&di->fileName)+1)) { Str fullName; Bool isDir; STRBUF_AppendChar(&di->dirName, FILE_SEPARATOR_CHAR); STRBUF_AppendBuf(&di->dirName, &di->fileName); fullName = STRBUF_Text(&di->dirName); if (type == DTypeUnknown) { isDir = FILE_IsDir(fullName); } else { isDir = BoolValue(type == DTypeDir); } if (isDir) { ok = FILE_RmDir(fullName, True); } else { ok = FILE_Delete(fullName); } STRBUF_SetLength(&di->dirName, dirlen); di->entry.dir = STRBUF_Text(&di->dirName); } return ok; }
/** * Creates a directory hierarhy. */ Bool FILE_MkDir(Str dir) { Bool ok = False; StrBuf64 entry; StrBuf* sb = &entry.sb; STRBUF_InitBufXXX(&entry); if (STRBUF_Copy(sb, dir)) { while (sb->len > 0 && FILE_IsFileSeparator(STRBUF_LastChar(sb))) { STRBUF_SetLength(sb, sb->len-1); } /* check if the directory already exists */ if (FILE_IsDir(STRBUF_Text(sb)) || FILE_CreateDir(STRBUF_Text(sb))) { ok = True; } else { /* directory does not exists, walk the hierarhy */ int pos = 0; int next = 0; while ((next = FILE_FindSeparator(dir+pos)) >= 0) { STRBUF_Clear(sb); if (next == 0) { pos++; continue; } else { if (!STRBUF_CopyN(sb,dir,pos+next) || !FILE_CreateDir(STRBUF_Text(sb))) { break; } pos += next + 1; } } /* final test */ if (STRBUF_Copy(sb, dir)) { while (sb->len && FILE_IsFileSeparator(STRBUF_LastChar(sb))) { STRBUF_SetLength(sb, sb->len-1); } if (FILE_IsDir(STRBUF_Text(sb)) || FILE_CreateDir(STRBUF_Text(sb))) { ok = True; } } } } STRBUF_Destroy(sb); return ok; }
/** * Parses Java version string. Also returns the number of digits in the * version string that have been successfully parsed. All non-parsed digits * are filled with zeros. The ndigits pointer may be NULL. */ Bool JVM_ParseVersion2(Str strVersion, JavaVersion * version, int* ndigits) { int i; Str p = strVersion; StrBuf16 buf; STRBUF_InitBufXXX(&buf); memset(version, 0, sizeof(*version)); for (i=0; i<JAVA_VERSION_SIZE; i++) { STRBUF_Clear(&buf.sb); while (*p && !IsDigit(*p)) p++; if (*p) { while (IsDigit(*p)) STRBUF_AppendChar(&buf.sb, *p++); if (STRBUF_Length(&buf.sb) > 0) { if (PARSE_Int(STRBUF_Text(&buf.sb),&(version->v[i]),10)) { continue; } } } break; } if (ndigits) *ndigits = i; STRBUF_Destroy(&buf.sb); return (i >= 2); }
STATIC void EXPAT_EndElement(void * ctx, XML_Str tag) { ExpatContext * expat = (ExpatContext *)ctx; if (expat->cb.endElem) { EXPAT_ConvertTag(&expat->sb, tag); (*expat->cb.endElem)(expat->ctx, STRBUF_Text(&expat->sb)); } }
STATIC void EXPAT_StartElement(void * ctx, XML_Str tag, XML_Str * atts) { ExpatContext * expat = (ExpatContext *)ctx; if (expat->cb.startElem) { XMLAttr aset; XML_Str * s = atts; BUFFER_Clear(&expat->buf); BUFFER_Clear(&expat->atts); while (*s) { wchar_t* ws; XML_Str xs = *s++; /* * store offset in the vector - later will be replaces with the * pointer. Cannot store the pointers now because buffer may be * reallocated during conversion. */ const int off = BUFFER_Size(&expat->buf)/sizeof(Char); BUFFER_Put(&expat->atts, &off, sizeof(off), False); /* Convert from UTF-8 XML_Str to Str */ ws = STRING_ToUnicode(xs); if (ws) { #ifdef UNICODE BUFFER_Put(&expat->buf,ws,(wcslen(ws)+1)*sizeof(ws[0]),False); #else char * mb = STRING_ToMultiByte(ws); if (mb) { BUFFER_Put(&expat->buf, mb, strlen(mb)+1, False); MEM_Free(mb); } else { BUFFER_Put(&expat->buf, xs, strlen(xs)+1, False); } #endif MEM_Free(ws); } } ASSERT(!((BUFFER_Size(&expat->atts)/sizeof(int))%2)); aset.storage = BUFFER_Access(&expat->buf); aset.size = BUFFER_Size(&expat->buf); aset.off = BUFFER_Access(&expat->atts); aset.n = BUFFER_Size(&expat->atts)/sizeof(int)/2; EXPAT_ConvertTag(&expat->sb, tag); (*expat->cb.startElem)(expat->ctx, STRBUF_Text(&expat->sb), &aset); } }
/** * The same as BASE64_Encode but stores encoded data into a string buffer. * Does not destroy the original contents of the string buffer. The * Base64 string is appended to it. Returns pointer to string buffer * data, NULL on memory allocation failure */ Str BASE64_EncodeStr(const void * data, size_t size, StrBuf * sb, int flags) { const char* encodeMap = ((flags & BASE64_URLSAFE) ? base64_safeEncodeMap : base64_encodeMap); size_t alloc = ((size+2)/3)*4; if (STRBUF_Alloc(sb, STRBUF_Length(sb)+alloc)) { const char * buf = (const char *)data; size_t off; /* encode the bulk of the data */ for (off=0; (off+3)<=size; off+=3) { STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_1(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_2(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_3(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_4(buf,off)]); } /* manage last one or two bytes */ switch (size%3) { case 0: break; case 1: STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_1(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_2_1(buf,off)]); if (flags & BASE64_PAD) { STRBUF_AppendChar(sb,'='); STRBUF_AppendChar(sb,'='); } break; case 2: STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_1(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_2(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE64_ENCODE_3_1(buf,off)]); if (flags & BASE64_PAD) STRBUF_AppendChar(sb,'='); break; } return STRBUF_Text(sb); } /* could not allocate memory */ return NULL; }
STATIC void EXPAT_StartElement(void * ctx, XML_Str tag, XML_Str * atts) { ExpatContext * expat = (ExpatContext *)ctx; if (expat->cb.startElem) { XMLAttr aset; XML_Str * s = atts; BUFFER_Clear(&expat->buf); VECTOR_Clear(&expat->atts); while (*s) { Char tmp; const XML_Char * c = (*s); /* * store offset in the vector - later will be replaces with the * pointer. Cannot store the pointers now because buffer may be * reallocated during conversion. */ int off = BUFFER_Size(&expat->buf)/sizeof(Char); VECTOR_Add(&expat->atts,(VElement)(PtrWord)off); /* * Pretty naive convertion of attribute names and values from * XML_Str to Str. This part may need some improvement... */ while (*c) { tmp = (Char)*c; BUFFER_Put(&expat->buf, &tmp, sizeof(tmp), False); c++; } tmp = 0; BUFFER_Put(&expat->buf, &tmp, sizeof(tmp), False); s++; } ASSERT(!(VECTOR_Size(&expat->atts)%2)); aset.storage = (Char*)BUFFER_Access(&expat->buf); aset.size = BUFFER_Size(&expat->buf); aset.off = (int*)VECTOR_GetElements(&expat->atts); aset.n = VECTOR_Size(&expat->atts)/2; EXPAT_ConvertTag(&expat->sb, tag); (*expat->cb.startElem)(expat->ctx, STRBUF_Text(&expat->sb), &aset); } }
/** * Discovers all available JVMs. If no JVMs are discovered, returns NULL. * In addition to the standard directories, also looks in the additional * directories specified by the dirs array. Note that this directory list * replaces the default list ("jre","../jre") used by JVM_Find, it does not * adds new directories to the list. */ JVMSet * JVM_Find2(const Str dirs[], int n) { JVMSet * jvms = MEM_New(JVMSet); if (jvms) { memset(jvms, 0, sizeof(*jvms)); if (VECTOR_Init(&jvms->found, 0, JVM_VectorEquals, JVM_VectorFree)) { /* Look for JVMs in the Windows registry */ JVM_Discover(jvms); /* Look for JVMs in the additional directories */ if (n > 0) { int i; StrBuf sb,sb2; Char* baseDir = NULL; STRBUF_Init(&sb); STRBUF_Init(&sb2); TRACE("JNILIB: checking special directories\n"); for (i=0; i<n; i++) { Str javaHome = NULL; JvmPathType pathType = JVM_GetPathType(dirs[i]); if (pathType == JvmPathRelative) { LPTSTR filePath; TRACE1("JNILIB: relative path: %s\n",dirs[i]); if (baseDir) { STRBUF_Copy(&sb, baseDir); } else { int separator; JVM_GetModuleFileName(NULL,&sb); STRBUF_Replace(&sb, '/', '\\'); separator = STRBUF_LastIndexOf(&sb,'\\'); STRBUF_SetLength(&sb,separator+1); baseDir = STRBUF_Dup(&sb); if (!baseDir) continue; TRACE1("JNILIB: base dir: %s\n",baseDir); } STRBUF_Append(&sb, dirs[i]); STRBUF_Replace(&sb, '/', '\\'); STRBUF_Alloc(&sb2, STRBUF_Length(&sb)); sb2.len = GetFullPathName(STRBUF_Text(&sb), sb2.alloc, sb2.s, &filePath); ASSERT(sb2.len && sb2.s[0]); javaHome = STRBUF_Text(&sb2); } else if (pathType == JvmPathAbsolute) { TRACE1("JNILIB: absolute path: %s\n",dirs[i]); javaHome = dirs[i]; } else if (pathType == JvmPathSystem) { /* directory on the system drive */ TRACE1("JNILIB: system path: %s\n",dirs[i]); STRBUF_Alloc(&sb,GetSystemDirectory(NULL,0)+1); STRBUF_SetLength(&sb,GetSystemDirectory(sb.s,sb.alloc)); STRBUF_Clear(&sb2); STRBUF_AppendChar(&sb2,STRBUF_CharAt(&sb,0)); STRBUF_AppendChar(&sb2,':'); STRBUF_Append(&sb2, dirs[i]); javaHome = STRBUF_Text(&sb2); } else { TRACE1("JNILIB: invalid path: %s\n",dirs[i]); continue; } if (javaHome) { TRACE1("JNILIB: Java home: %s\n",javaHome); if (FILE_IsDir(javaHome)) { JVM* jvm = JVM_CreateDirContext(javaHome); if (jvm) { jvm->flags |= JVM_FLAG_SPECIAL; if (JVM_Add(jvms, jvm) && !jvms->specialVM) { jvms->specialVM = jvm; } } } else { TRACE1("JNILIB: no such directory: %s\n",javaHome); } } } MEM_Free(baseDir); STRBUF_Destroy(&sb); STRBUF_Destroy(&sb2); } /* Did we find anything? */ if (!VECTOR_IsEmpty(&jvms->found)) { JVM_Sort(jvms, JVM_DefaultSort); TRACE1("JNILIB: found %d JVM(s)\n",VECTOR_Size(&jvms->found)); return jvms; } TRACE("JNILIB: found no JVMs\n, sorry"); VECTOR_Destroy(&jvms->found); } MEM_Free(jvms); } return NULL; }
/** * The same as BASE32_Encode but stores encoded data into a string buffer. * Does not destroy the original contents of the string buffer. The * Base32 string is appended to it. Returns pointer to string buffer * data, NULL on memory allocation failure */ Str BASE32_EncodeStr(const void * data, int n, StrBuf * sb, int flags) { const char* encodeMap = ((flags & BASE32_LOWERCASE) ? base32_lowerCaseEncodeMap : base32_upperCaseEncodeMap); int alloc = (n/ENCODE_CHUNK_SIZE+((n%ENCODE_CHUNK_SIZE)?1:0))* DECODE_CHUNK_SIZE+1; /* * +--- octet 0 ---+--- octet 1 ---+--- octet 2 ---+ * |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| * +---------+-----+---+---------+-+-------+-------+ * |4 3 2 1 0|4 3 2 1 0|4 3 2 1 0|4 3 2 1 0|4 3 2 1 * +-0.index-+-1.index-+-2.index-+-3.index-+-4.index * * +--- octet 3 ---+--- octet 4 ---+ * |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| * +-+---------+---+-----+---------+ * 0|4 3 2 1 0|4 3 2 1 0|4 3 2 1 0| * --+-5.index-+-6.index-+-7.index-+ */ if (STRBUF_Alloc(sb, STRBUF_Length(sb)+alloc)) { const char * buf = (const char *)data; int off; /* encode the bulk of the data */ for (off=0; (off+ENCODE_CHUNK_SIZE)<=n; off+=ENCODE_CHUNK_SIZE) { STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_1(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_2(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_3(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_4(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_5(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_6(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_7(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_8(buf,off)]); } /* manage the last few bytes */ switch (n % ENCODE_CHUNK_SIZE) { case 0: break; case 1: STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_1(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_2_1(buf,off)]); break; case 2: STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_1(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_2(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_3(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_4_1(buf,off)]); break; case 3: STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_1(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_2(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_3(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_4(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_5_1(buf,off)]); break; case 4: STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_1(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_2(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_3(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_4(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_5(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_6(buf,off)]); STRBUF_AppendChar(sb,encodeMap[BASE32_ENCODE_7_1(buf,off)]); break; } /* append padding characters */ if (flags & BASE32_PAD) { STRBUF_Append(sb, base32_pad[n % ENCODE_CHUNK_SIZE]); } return STRBUF_Text(sb); } /* could not allocate memory */ return NULL; }