hewei.it 4 роки тому
батько
коміт
446c5edda1
9 змінених файлів з 123 додано та 18 видалено
  1. 12 0
      base/hbase.c
  2. 1 0
      base/hbase.h
  3. 15 0
      base/hplatform.h
  4. 5 1
      cpputil/hfile.h
  5. 12 0
      cpputil/hpath.cpp
  6. 1 0
      cpputil/hpath.h
  7. 56 2
      cpputil/hstring.cpp
  8. 9 1
      cpputil/hstring.h
  9. 12 14
      unittest/hstring_test.cpp

+ 12 - 0
base/hbase.c

@@ -260,6 +260,18 @@ bool hv_isfile(const char* path) {
     return S_ISREG(st.st_mode);
 }
 
+bool hv_islink(const char* path) {
+#ifdef OS_WIN
+    return hv_isdir(path) && (GetFileAttributes(path) & FILE_ATTRIBUTE_REPARSE_POINT);
+#else
+    if (access(path, 0) != 0) return false;
+    struct stat st;
+    memset(&st, 0, sizeof(st));
+    lstat(path, &st);
+    return S_ISLNK(st.st_mode);
+#endif
+}
+
 bool getboolean(const char* str) {
     if (str == NULL) return false;
     int len = strlen(str);

+ 1 - 0
base/hbase.h

@@ -77,6 +77,7 @@ HV_EXPORT int hv_rmdir_p(const char* dir);
 HV_EXPORT bool hv_exists(const char* path);
 HV_EXPORT bool hv_isdir(const char* path);
 HV_EXPORT bool hv_isfile(const char* path);
+HV_EXPORT bool hv_islink(const char* path);
 
 // 1 y on yes true enable
 HV_EXPORT bool getboolean(const char* str);

+ 15 - 0
base/hplatform.h

@@ -152,6 +152,21 @@
     #define hv_delay(ms)    hv_msleep(ms)
     #define hv_mkdir(dir)   mkdir(dir)
 
+    // access
+    #ifndef F_OK
+    #define F_OK            0       /* test for existence of file */
+    #endif
+    #ifndef X_OK
+    #define X_OK            (1<<0)  /* test for execute or search permission */
+    #endif
+    #ifndef W_OK
+    #define W_OK            (1<<1)  /* test for write permission */
+    #endif
+    #ifndef R_OK
+    #define R_OK            (1<<2)  /* test for read permission */
+    #endif
+
+    // stat
     #ifndef S_ISREG
     #define S_ISREG(st_mode) (((st_mode) & S_IFMT) == S_IFREG)
     #endif

+ 5 - 1
cpputil/hfile.h

@@ -43,13 +43,17 @@ public:
         return fwrite(ptr, 1, len, fp);
     }
 
-    size_t size() {
+    static size_t size(const char* filepath) {
         struct stat st;
         memset(&st, 0, sizeof(st));
         stat(filepath, &st);
         return st.st_size;
     }
 
+    size_t size() {
+        return HFile::size(filepath);
+    }
+
     size_t readall(HBuf& buf) {
         size_t filesize = size();
         buf.resize(filesize);

+ 12 - 0
cpputil/hpath.cpp

@@ -22,6 +22,18 @@ bool HPath::isfile(const char* path) {
     return S_ISREG(st.st_mode);
 }
 
+bool HPath::islink(const char* path) {
+#ifdef OS_WIN
+    return HPath::isdir(path) && (GetFileAttributes(path) & FILE_ATTRIBUTE_REPARSE_POINT);
+#else
+    if (access(path, 0) != 0) return false;
+    struct stat st;
+    memset(&st, 0, sizeof(st));
+    lstat(path, &st);
+    return S_ISLNK(st.st_mode);
+#endif
+}
+
 std::string HPath::basename(const std::string& filepath) {
     std::string::size_type pos1 = filepath.find_last_not_of("/\\");
     if (pos1 == std::string::npos) {

+ 1 - 0
cpputil/hpath.h

@@ -10,6 +10,7 @@ public:
     static bool exists(const char* path);
     static bool isdir(const char* path);
     static bool isfile(const char* path);
+    static bool islink(const char* path);
 
     // filepath = /mnt/share/image/test.jpg
     // basename = test.jpg

+ 56 - 2
cpputil/hstring.cpp

@@ -5,12 +5,66 @@
 #include <string.h>
 #include <stdarg.h>
 
+namespace hv {
+
+std::string& toupper(std::string& str) {
+    // std::transform(str.begin(), str.end(), str.begin(), ::toupper);
+    char* p = (char*)str.c_str();
+    while (*p != '\0') {
+        if (*p >= 'a' && *p <= 'z') {
+            *p &= ~0x20;
+        }
+        ++p;
+    }
+    return str;
+}
+
+std::string& tolower(std::string& str) {
+    // std::transform(str.begin(), str.end(), str.begin(), ::tolower);
+    char* p = (char*)str.c_str();
+    while (*p != '\0') {
+        if (*p >= 'A' && *p <= 'Z') {
+            *p |= 0x20;
+        }
+        ++p;
+    }
+    return str;
+}
+
+std::string& reverse(std::string& str) {
+    // std::reverse(str.begin(), str.end());
+    char* b = (char*)str.c_str();
+    char* e = b + str.length() - 1;
+    char tmp;
+    while (e > b) {
+        tmp = *e;
+        *e = *b;
+        *b = tmp;
+        --e;
+        ++b;
+    }
+    return str;
+}
+
+bool startswith(const std::string& str, const std::string& start) {
+    if (str.length() < start.length()) return false;
+    return str.compare(0, start.length(), start) == 0;
+}
+
+bool endswith(const std::string& str, const std::string& end) {
+    if (str.length() < end.length()) return false;
+    return str.compare(str.length() - end.length(), end.length(), end) == 0;
+}
+
+bool contains(const std::string& str, const std::string& sub) {
+    if (str.length() < sub.length()) return false;
+    return str.find(sub) != std::string::npos;
+}
+
 static inline int vscprintf(const char* fmt, va_list ap) {
     return vsnprintf(NULL, 0, fmt, ap);
 }
 
-namespace hv {
-
 std::string asprintf(const char* fmt, ...) {
     va_list ap;
     va_start(ap, fmt);

+ 9 - 1
cpputil/hstring.h

@@ -40,10 +40,18 @@ HV_INLINE T from_string(const std::string& str) {
     return t;
 }
 
+HV_EXPORT std::string& toupper(std::string& str);
+HV_EXPORT std::string& tolower(std::string& str);
+HV_EXPORT std::string& reverse(std::string& str);
+
+HV_EXPORT bool startswith(const std::string& str, const std::string& start);
+HV_EXPORT bool endswith(const std::string& str, const std::string& end);
+HV_EXPORT bool contains(const std::string& str, const std::string& sub);
+
 HV_EXPORT std::string asprintf(const char* fmt, ...);
 // x,y,z
 HV_EXPORT StringList split(const std::string& str, char delim = ',');
-// user=amdin&pswd=123456
+// k1=v1&k2=v2
 HV_EXPORT hv::KeyValue splitKV(const std::string& str, char kv_kv = '&', char k_v = '=');
 HV_EXPORT std::string trim(const std::string& str, const char* chars = SPACE_CHARS);
 HV_EXPORT std::string trimL(const std::string& str, const char* chars = SPACE_CHARS);

+ 12 - 14
unittest/hstring_test.cpp

@@ -2,20 +2,18 @@
 using namespace hv;
 
 int main(int argc, char** argv) {
-    /*
-    char str1[] = "a1B2*C3d4==";
-    char str2[] = "a1B2*C3d4==";
-    printf("strupper %s\n", strupper(str1));
-    printf("strlower %s\n", strlower(str2));
-    char str3[] = "abcdefg";
-    printf("strreverse %s\n", strreverse(str3));
-
-    char str4[] = "123456789";
-    printf("strstartswith=%d\nstrendswith=%d\nstrcontains=%d\n",
-        (int)strstartswith(str4, "123"),
-        (int)strendswith(str4, "789"),
-        (int)strcontains(str4, "456"));
-    */
+    std::string str1 = "a1B2*C3d4==";
+    std::string str2 = "a1B2*C3d4==";
+    printf("toupper %s\n", toupper(str1).c_str());
+    printf("tolower %s\n", tolower(str2).c_str());
+    std::string str3 = "abcdefg";
+    printf("reverse %s\n", reverse(str3).c_str());
+
+    std::string str4 = "123456789";
+    printf("startswith=%d\nendswith=%d\ncontains=%d\n",
+        (int)startswith(str4, "123"),
+        (int)endswith(str4, "789"),
+        (int)contains(str4, "456"));
 
     std::string str5 = asprintf("%s%d", "hello", 5);
     printf("asprintf %s\n", str5.c_str());