Преглед изворни кода

ncd/NCDVal: add NCDVal_StringContinuize() and friends

ambrop7 пре 13 година
родитељ
комит
fec5568333
2 измењених фајлова са 70 додато и 0 уклоњено
  1. 40 0
      ncd/NCDVal.c
  2. 30 0
      ncd/NCDVal.h

+ 40 - 0
ncd/NCDVal.c

@@ -1183,6 +1183,46 @@ void NCDValNullTermString_Free (NCDValNullTermString *o)
     }
 }
 
+int NCDVal_StringContinuize (NCDValRef string, NCDValContString *out)
+{
+    ASSERT(NCDVal_IsString(string))
+    ASSERT(out)
+    
+    if (NCDVal_IsContinuousString(string)) {
+        out->data = NCDVal_StringData(string);
+        out->is_allocated = 0;
+        return 1;
+    }
+    
+    size_t length = NCDVal_StringLength(string);
+    
+    char *data = BAlloc(length);
+    if (!data) {
+        return 0;
+    }
+    
+    NCDVal_StringCopyOut(string, 0, length, data);
+    
+    out->data = data;
+    out->is_allocated = 1;
+    return 1;
+}
+
+NCDValContString NCDValContString_NewDummy (void)
+{
+    NCDValContString cts;
+    cts.data = NULL;
+    cts.is_allocated = 0;
+    return cts;
+}
+
+void NCDValContString_Free (NCDValContString *o)
+{
+    if (o->is_allocated) {
+        BFree(o->data);
+    }
+}
+
 void NCDVal_IdStringGet (NCDValRef idstring, NCD_string_id_t *out_string_id,
                          NCDStringIndex **out_string_index)
 {

+ 30 - 0
ncd/NCDVal.h

@@ -180,6 +180,11 @@ typedef struct {
     int is_allocated;
 } NCDValNullTermString;
 
+typedef struct {
+    char *data;
+    int is_allocated;
+} NCDValContString;
+
 //
 
 #define NCDVAL_STRING 1
@@ -538,6 +543,31 @@ NCDValNullTermString NCDValNullTermString_NewDummy (void);
  */
 void NCDValNullTermString_Free (NCDValNullTermString *o);
 
+/**
+ * Produces a continuous version of a String. On success, the result is stored into an
+ * {@link NCDValContString} structure, and the continuous string is available via its
+ * 'data' member. This function may either simply pass through the data pointer (if the
+ * string is known to be continuous) or produce a continuous dynamically allocated copy.
+ * On success, {@link NCDValContString_Free} should be called to release any allocated
+ * memory when the continuous string is no longer needed. This must be called before
+ * the memory object is freed, because it may point to data inside the memory object.
+ * It is guaranteed that *out is not modified on failure.
+ * Returns 1 on success and 0 on failure.
+ */
+int NCDVal_StringContinuize (NCDValRef string, NCDValContString *out) WARN_UNUSED;
+
+/**
+ * Returns a dummy {@link NCDValContString} which can be freed using
+ * {@link NCDValContString_Free}, but need not be.
+ */
+NCDValContString NCDValContString_NewDummy (void);
+
+/**
+ * Releases any memory which was dynamically allocated by {@link NCDVal_StringContinuize}
+ * to continuize a string.
+ */
+void NCDValContString_Free (NCDValContString *o);
+
 /**
  * Returns the string ID and the string index of an IdString.
  * Both the \a out_string_id and \a out_string_index pointers must be non-NULL.