class AutoC::CString
Value
type string wrapper of the plain C string
Constants
- Range
Public Class Methods
new(type = :CString, char = :char, parallel: nil, **kws)
click to toggle source
Calls superclass method
AutoC::Association::new
# File lib/autoc/cstring.rb, line 23 def initialize(type = :CString, char = :char, parallel: nil, **kws) super(type, char, :size_t, **kws) dependencies << STRING_H @parallel = parallel end
Public Instance Methods
configure()
click to toggle source
Calls superclass method
AutoC::Sequential#configure
# File lib/autoc/cstring.rb, line 77 def configure super method(:void, :create, { target: lvalue, source: const_rvalue }, instance: :custom_create, constraint:-> { custom_constructible? }).configure do header %{ @brief Create string @param[out] target string to be created @param[in] source string to be copied This function creates & initializes a new string by making an independent of the source string. This specifically means that the supplied source string may be any C string, either const or mutable, including string literal. Previous contents of `*target` is overwritten. Once constructed, the string is to be destroyed with @ref #{destroy}. @since 2.0 } inline_code %{ size_t size; assert(target); assert(source); size = strlen(source); *target = #{memory.allocate(element, 'size+1', atomic: true)}; assert(*target); memcpy(*target, source, size*sizeof(#{element})); (*target)[size] = '\\0'; } end method(:int, :create_format, { target: lvalue, format: const_rvalue }, variadic: true ).configure do code %{ int r; va_list args; #if defined(HAVE_VSNPRINTF) || __STDC_VERSION__ >= 199901L || __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER >= 1900) || defined(__POCC__) va_start(args, format); r = vsnprintf(NULL, 0, format, args); va_end(args); if(r < 0) return 0; *target = #{memory.allocate(element, 'r+1', atomic: true)}; assert(*target); va_start(args, format); r = vsnprintf(*target, r+1, format, args); va_end(args); return r >= 0; #else #if defined(_MSC_VER) #pragma message("WARNING: this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #else #warning("this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #endif va_start(args, format); #{element.lvalue} t = #{memory.allocate(element, :AUTOC_BUFFER_SIZE, atomic: true)}; assert(t); r = vsprintf(t, format, args); if(r >= 0) { if(r > AUTOC_BUFFER_SIZE-1) { /* the output spilled out of the preallocated buffer - perfer to bail out right away rather than to get likely heap corruption */ abort(); } /* prefer precision over performance and make a copy instead of returning a (possibly excessive) buffer */ #{default_create.(target, :t)}; } /* FIXME handle the case of simultaneous (r < 0 && buffer overrun) */ #{memory.free(:t)}; va_end(args); return r >= 0; #endif } header %{ @brief Create formatted string @param[out] target string to be created @param[in] format format template @param[in] ... format parameters @result non-zero value on successful construction and zero value otherwise This function employs a standard C function from the s*printf() family to create new formatted string. @note No `*target` is modified on function failure. @since 2.0 } end destroy.configure do inline_code %{ assert(target); #{memory.free('*target')}; } end copy.configure do dependencies << custom_create inline_code %{ #{custom_create.(*parameters)}; } end get.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return target[index]; } end set.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); target[index] = value; } end view.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return &target[index]; } end equal.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right) == 0; } end compare.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right); } end hash_code.configure do code %{ /* djb2 algorithm: http://www.cse.yorku.ca/~oz/hash.html */ size_t c; size_t hash; #{element.lvalue} s; assert(target); hash = 5381; s = target; while((c = *s++)) hash = hash*33 ^ c; return hash; } end contains.configure do inline_code %{ assert(target); return strchr(target, value) != NULL; } end find_first.configure do inline_code %{ assert(target); return strchr(target, value); } end check.configure do dependencies << size inline_code %{ assert(target); return index < #{size.(target)}; } end empty.configure do inline_code %{ assert(target); return *target == '\\0'; } end size.configure do inline_code %{ assert(target); return strlen(target); } end end
const_lvalue(= @clv ||= Value.new(self, reference: true, constant: true))
click to toggle source
# File lib/autoc/cstring.rb, line 35 def const_lvalue = @clv ||= Value.new(self, reference: true, constant: true) def render_interface(stream) if public? stream << %{ /** #{defgroup} @brief Value type wrapper of the plain C string This type represents a (paper thin) wrapper around the plain C string (char *) with proper value semantics. @since 2.0 */ } else stream << PRIVATE end stream << %{ typedef #{element.lvalue} #{signature}; } end def storage(target) = target # Return C pointer to contiguous storage def render_forward_declarations(stream) stream << %{ #include <stdio.h> #include <malloc.h> #include <stdarg.h> /* overridable internal buffer size (in chars, not bytes) for *sprintf() operations */ #ifndef AUTOC_BUFFER_SIZE #define AUTOC_BUFFER_SIZE 1024 #endif } super end def type_tag = "#{signature}<#{element}>" private def configure super method(:void, :create, { target: lvalue, source: const_rvalue }, instance: :custom_create, constraint:-> { custom_constructible? }).configure do header %{ @brief Create string @param[out] target string to be created @param[in] source string to be copied This function creates & initializes a new string by making an independent of the source string. This specifically means that the supplied source string may be any C string, either const or mutable, including string literal. Previous contents of `*target` is overwritten. Once constructed, the string is to be destroyed with @ref #{destroy}. @since 2.0 } inline_code %{ size_t size; assert(target); assert(source); size = strlen(source); *target = #{memory.allocate(element, 'size+1', atomic: true)}; assert(*target); memcpy(*target, source, size*sizeof(#{element})); (*target)[size] = '\\0'; } end method(:int, :create_format, { target: lvalue, format: const_rvalue }, variadic: true ).configure do code %{ int r; va_list args; #if defined(HAVE_VSNPRINTF) || __STDC_VERSION__ >= 199901L || __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER >= 1900) || defined(__POCC__) va_start(args, format); r = vsnprintf(NULL, 0, format, args); va_end(args); if(r < 0) return 0; *target = #{memory.allocate(element, 'r+1', atomic: true)}; assert(*target); va_start(args, format); r = vsnprintf(*target, r+1, format, args); va_end(args); return r >= 0; #else #if defined(_MSC_VER) #pragma message("WARNING: this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #else #warning("this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #endif va_start(args, format); #{element.lvalue} t = #{memory.allocate(element, :AUTOC_BUFFER_SIZE, atomic: true)}; assert(t); r = vsprintf(t, format, args); if(r >= 0) { if(r > AUTOC_BUFFER_SIZE-1) { /* the output spilled out of the preallocated buffer - perfer to bail out right away rather than to get likely heap corruption */ abort(); } /* prefer precision over performance and make a copy instead of returning a (possibly excessive) buffer */ #{default_create.(target, :t)}; } /* FIXME handle the case of simultaneous (r < 0 && buffer overrun) */ #{memory.free(:t)}; va_end(args); return r >= 0; #endif } header %{ @brief Create formatted string @param[out] target string to be created @param[in] format format template @param[in] ... format parameters @result non-zero value on successful construction and zero value otherwise This function employs a standard C function from the s*printf() family to create new formatted string. @note No `*target` is modified on function failure. @since 2.0 } end destroy.configure do inline_code %{ assert(target); #{memory.free('*target')}; } end copy.configure do dependencies << custom_create inline_code %{ #{custom_create.(*parameters)}; } end get.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return target[index]; } end set.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); target[index] = value; } end view.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return &target[index]; } end equal.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right) == 0; } end compare.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right); } end hash_code.configure do code %{ /* djb2 algorithm: http://www.cse.yorku.ca/~oz/hash.html */ size_t c; size_t hash; #{element.lvalue} s; assert(target); hash = 5381; s = target; while((c = *s++)) hash = hash*33 ^ c; return hash; } end contains.configure do inline_code %{ assert(target); return strchr(target, value) != NULL; } end find_first.configure do inline_code %{ assert(target); return strchr(target, value); } end check.configure do dependencies << size inline_code %{ assert(target); return index < #{size.(target)}; } end empty.configure do inline_code %{ assert(target); return *target == '\\0'; } end size.configure do inline_code %{ assert(target); return strlen(target); } end end end # CString CString::Range = ContiguousRange # Range
const_rvalue(= @crv ||= Value.new(self, constant: true))
click to toggle source
# File lib/autoc/cstring.rb, line 33 def const_rvalue = @crv ||= Value.new(self, constant: true) def const_lvalue = @clv ||= Value.new(self, reference: true, constant: true) def render_interface(stream) if public? stream << %{ /** #{defgroup} @brief Value type wrapper of the plain C string This type represents a (paper thin) wrapper around the plain C string (char *) with proper value semantics. @since 2.0 */ } else stream << PRIVATE end stream << %{ typedef #{element.lvalue} #{signature}; } end def storage(target) = target # Return C pointer to contiguous storage def render_forward_declarations(stream) stream << %{ #include <stdio.h> #include <malloc.h> #include <stdarg.h> /* overridable internal buffer size (in chars, not bytes) for *sprintf() operations */ #ifndef AUTOC_BUFFER_SIZE #define AUTOC_BUFFER_SIZE 1024 #endif } super end def type_tag = "#{signature}<#{element}>" private def configure super method(:void, :create, { target: lvalue, source: const_rvalue }, instance: :custom_create, constraint:-> { custom_constructible? }).configure do header %{ @brief Create string @param[out] target string to be created @param[in] source string to be copied This function creates & initializes a new string by making an independent of the source string. This specifically means that the supplied source string may be any C string, either const or mutable, including string literal. Previous contents of `*target` is overwritten. Once constructed, the string is to be destroyed with @ref #{destroy}. @since 2.0 } inline_code %{ size_t size; assert(target); assert(source); size = strlen(source); *target = #{memory.allocate(element, 'size+1', atomic: true)}; assert(*target); memcpy(*target, source, size*sizeof(#{element})); (*target)[size] = '\\0'; } end method(:int, :create_format, { target: lvalue, format: const_rvalue }, variadic: true ).configure do code %{ int r; va_list args; #if defined(HAVE_VSNPRINTF) || __STDC_VERSION__ >= 199901L || __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER >= 1900) || defined(__POCC__) va_start(args, format); r = vsnprintf(NULL, 0, format, args); va_end(args); if(r < 0) return 0; *target = #{memory.allocate(element, 'r+1', atomic: true)}; assert(*target); va_start(args, format); r = vsnprintf(*target, r+1, format, args); va_end(args); return r >= 0; #else #if defined(_MSC_VER) #pragma message("WARNING: this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #else #warning("this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #endif va_start(args, format); #{element.lvalue} t = #{memory.allocate(element, :AUTOC_BUFFER_SIZE, atomic: true)}; assert(t); r = vsprintf(t, format, args); if(r >= 0) { if(r > AUTOC_BUFFER_SIZE-1) { /* the output spilled out of the preallocated buffer - perfer to bail out right away rather than to get likely heap corruption */ abort(); } /* prefer precision over performance and make a copy instead of returning a (possibly excessive) buffer */ #{default_create.(target, :t)}; } /* FIXME handle the case of simultaneous (r < 0 && buffer overrun) */ #{memory.free(:t)}; va_end(args); return r >= 0; #endif } header %{ @brief Create formatted string @param[out] target string to be created @param[in] format format template @param[in] ... format parameters @result non-zero value on successful construction and zero value otherwise This function employs a standard C function from the s*printf() family to create new formatted string. @note No `*target` is modified on function failure. @since 2.0 } end destroy.configure do inline_code %{ assert(target); #{memory.free('*target')}; } end copy.configure do dependencies << custom_create inline_code %{ #{custom_create.(*parameters)}; } end get.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return target[index]; } end set.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); target[index] = value; } end view.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return &target[index]; } end equal.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right) == 0; } end compare.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right); } end hash_code.configure do code %{ /* djb2 algorithm: http://www.cse.yorku.ca/~oz/hash.html */ size_t c; size_t hash; #{element.lvalue} s; assert(target); hash = 5381; s = target; while((c = *s++)) hash = hash*33 ^ c; return hash; } end contains.configure do inline_code %{ assert(target); return strchr(target, value) != NULL; } end find_first.configure do inline_code %{ assert(target); return strchr(target, value); } end check.configure do dependencies << size inline_code %{ assert(target); return index < #{size.(target)}; } end empty.configure do inline_code %{ assert(target); return *target == '\\0'; } end size.configure do inline_code %{ assert(target); return strlen(target); } end end end # CString CString::Range = ContiguousRange
default_constructible?(= false)
click to toggle source
# File lib/autoc/cstring.rb, line 19 def default_constructible? = false def range = @range ||= Range.new(self, visibility: visibility, parallel: @parallel) def initialize(type = :CString, char = :char, parallel: nil, **kws) super(type, char, :size_t, **kws) dependencies << STRING_H @parallel = parallel end def rvalue = @rv ||= Value.new(self) def lvalue = @lv ||= Value.new(self, reference: true) def const_rvalue = @crv ||= Value.new(self, constant: true) def const_lvalue = @clv ||= Value.new(self, reference: true, constant: true) def render_interface(stream) if public? stream << %{ /** #{defgroup} @brief Value type wrapper of the plain C string This type represents a (paper thin) wrapper around the plain C string (char *) with proper value semantics. @since 2.0 */ } else stream << PRIVATE end stream << %{ typedef #{element.lvalue} #{signature}; } end def storage(target) = target # Return C pointer to contiguous storage def render_forward_declarations(stream) stream << %{ #include <stdio.h> #include <malloc.h> #include <stdarg.h> /* overridable internal buffer size (in chars, not bytes) for *sprintf() operations */ #ifndef AUTOC_BUFFER_SIZE #define AUTOC_BUFFER_SIZE 1024 #endif } super end def type_tag = "#{signature}<#{element}>" private def configure super method(:void, :create, { target: lvalue, source: const_rvalue }, instance: :custom_create, constraint:-> { custom_constructible? }).configure do header %{ @brief Create string @param[out] target string to be created @param[in] source string to be copied This function creates & initializes a new string by making an independent of the source string. This specifically means that the supplied source string may be any C string, either const or mutable, including string literal. Previous contents of `*target` is overwritten. Once constructed, the string is to be destroyed with @ref #{destroy}. @since 2.0 } inline_code %{ size_t size; assert(target); assert(source); size = strlen(source); *target = #{memory.allocate(element, 'size+1', atomic: true)}; assert(*target); memcpy(*target, source, size*sizeof(#{element})); (*target)[size] = '\\0'; } end method(:int, :create_format, { target: lvalue, format: const_rvalue }, variadic: true ).configure do code %{ int r; va_list args; #if defined(HAVE_VSNPRINTF) || __STDC_VERSION__ >= 199901L || __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER >= 1900) || defined(__POCC__) va_start(args, format); r = vsnprintf(NULL, 0, format, args); va_end(args); if(r < 0) return 0; *target = #{memory.allocate(element, 'r+1', atomic: true)}; assert(*target); va_start(args, format); r = vsnprintf(*target, r+1, format, args); va_end(args); return r >= 0; #else #if defined(_MSC_VER) #pragma message("WARNING: this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #else #warning("this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #endif va_start(args, format); #{element.lvalue} t = #{memory.allocate(element, :AUTOC_BUFFER_SIZE, atomic: true)}; assert(t); r = vsprintf(t, format, args); if(r >= 0) { if(r > AUTOC_BUFFER_SIZE-1) { /* the output spilled out of the preallocated buffer - perfer to bail out right away rather than to get likely heap corruption */ abort(); } /* prefer precision over performance and make a copy instead of returning a (possibly excessive) buffer */ #{default_create.(target, :t)}; } /* FIXME handle the case of simultaneous (r < 0 && buffer overrun) */ #{memory.free(:t)}; va_end(args); return r >= 0; #endif } header %{ @brief Create formatted string @param[out] target string to be created @param[in] format format template @param[in] ... format parameters @result non-zero value on successful construction and zero value otherwise This function employs a standard C function from the s*printf() family to create new formatted string. @note No `*target` is modified on function failure. @since 2.0 } end destroy.configure do inline_code %{ assert(target); #{memory.free('*target')}; } end copy.configure do dependencies << custom_create inline_code %{ #{custom_create.(*parameters)}; } end get.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return target[index]; } end set.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); target[index] = value; } end view.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return &target[index]; } end equal.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right) == 0; } end compare.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right); } end hash_code.configure do code %{ /* djb2 algorithm: http://www.cse.yorku.ca/~oz/hash.html */ size_t c; size_t hash; #{element.lvalue} s; assert(target); hash = 5381; s = target; while((c = *s++)) hash = hash*33 ^ c; return hash; } end contains.configure do inline_code %{ assert(target); return strchr(target, value) != NULL; } end find_first.configure do inline_code %{ assert(target); return strchr(target, value); } end check.configure do dependencies << size inline_code %{ assert(target); return index < #{size.(target)}; } end empty.configure do inline_code %{ assert(target); return *target == '\\0'; } end size.configure do inline_code %{ assert(target); return strlen(target); } end end end # CString
lvalue(= @lv ||= Value.new(self, reference: true))
click to toggle source
# File lib/autoc/cstring.rb, line 31 def lvalue = @lv ||= Value.new(self, reference: true) def const_rvalue = @crv ||= Value.new(self, constant: true) def const_lvalue = @clv ||= Value.new(self, reference: true, constant: true) def render_interface(stream) if public? stream << %{ /** #{defgroup} @brief Value type wrapper of the plain C string This type represents a (paper thin) wrapper around the plain C string (char *) with proper value semantics. @since 2.0 */ } else stream << PRIVATE end stream << %{ typedef #{element.lvalue} #{signature}; } end def storage(target) = target # Return C pointer to contiguous storage def render_forward_declarations(stream) stream << %{ #include <stdio.h> #include <malloc.h> #include <stdarg.h> /* overridable internal buffer size (in chars, not bytes) for *sprintf() operations */ #ifndef AUTOC_BUFFER_SIZE #define AUTOC_BUFFER_SIZE 1024 #endif } super end def type_tag = "#{signature}<#{element}>" private def configure super method(:void, :create, { target: lvalue, source: const_rvalue }, instance: :custom_create, constraint:-> { custom_constructible? }).configure do header %{ @brief Create string @param[out] target string to be created @param[in] source string to be copied This function creates & initializes a new string by making an independent of the source string. This specifically means that the supplied source string may be any C string, either const or mutable, including string literal. Previous contents of `*target` is overwritten. Once constructed, the string is to be destroyed with @ref #{destroy}. @since 2.0 } inline_code %{ size_t size; assert(target); assert(source); size = strlen(source); *target = #{memory.allocate(element, 'size+1', atomic: true)}; assert(*target); memcpy(*target, source, size*sizeof(#{element})); (*target)[size] = '\\0'; } end method(:int, :create_format, { target: lvalue, format: const_rvalue }, variadic: true ).configure do code %{ int r; va_list args; #if defined(HAVE_VSNPRINTF) || __STDC_VERSION__ >= 199901L || __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER >= 1900) || defined(__POCC__) va_start(args, format); r = vsnprintf(NULL, 0, format, args); va_end(args); if(r < 0) return 0; *target = #{memory.allocate(element, 'r+1', atomic: true)}; assert(*target); va_start(args, format); r = vsnprintf(*target, r+1, format, args); va_end(args); return r >= 0; #else #if defined(_MSC_VER) #pragma message("WARNING: this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #else #warning("this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #endif va_start(args, format); #{element.lvalue} t = #{memory.allocate(element, :AUTOC_BUFFER_SIZE, atomic: true)}; assert(t); r = vsprintf(t, format, args); if(r >= 0) { if(r > AUTOC_BUFFER_SIZE-1) { /* the output spilled out of the preallocated buffer - perfer to bail out right away rather than to get likely heap corruption */ abort(); } /* prefer precision over performance and make a copy instead of returning a (possibly excessive) buffer */ #{default_create.(target, :t)}; } /* FIXME handle the case of simultaneous (r < 0 && buffer overrun) */ #{memory.free(:t)}; va_end(args); return r >= 0; #endif } header %{ @brief Create formatted string @param[out] target string to be created @param[in] format format template @param[in] ... format parameters @result non-zero value on successful construction and zero value otherwise This function employs a standard C function from the s*printf() family to create new formatted string. @note No `*target` is modified on function failure. @since 2.0 } end destroy.configure do inline_code %{ assert(target); #{memory.free('*target')}; } end copy.configure do dependencies << custom_create inline_code %{ #{custom_create.(*parameters)}; } end get.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return target[index]; } end set.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); target[index] = value; } end view.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return &target[index]; } end equal.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right) == 0; } end compare.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right); } end hash_code.configure do code %{ /* djb2 algorithm: http://www.cse.yorku.ca/~oz/hash.html */ size_t c; size_t hash; #{element.lvalue} s; assert(target); hash = 5381; s = target; while((c = *s++)) hash = hash*33 ^ c; return hash; } end contains.configure do inline_code %{ assert(target); return strchr(target, value) != NULL; } end find_first.configure do inline_code %{ assert(target); return strchr(target, value); } end check.configure do dependencies << size inline_code %{ assert(target); return index < #{size.(target)}; } end empty.configure do inline_code %{ assert(target); return *target == '\\0'; } end size.configure do inline_code %{ assert(target); return strlen(target); } end end end # CString CString::Range =
range(= @range ||= Range.new(self, visibility: visibility, parallel: @parallel))
click to toggle source
# File lib/autoc/cstring.rb, line 21 def range = @range ||= Range.new(self, visibility: visibility, parallel: @parallel) def initialize(type = :CString, char = :char, parallel: nil, **kws) super(type, char, :size_t, **kws) dependencies << STRING_H @parallel = parallel end def rvalue = @rv ||= Value.new(self) def lvalue = @lv ||= Value.new(self, reference: true) def const_rvalue = @crv ||= Value.new(self, constant: true) def const_lvalue = @clv ||= Value.new(self, reference: true, constant: true) def render_interface(stream) if public? stream << %{ /** #{defgroup} @brief Value type wrapper of the plain C string This type represents a (paper thin) wrapper around the plain C string (char *) with proper value semantics. @since 2.0 */ } else stream << PRIVATE end stream << %{ typedef #{element.lvalue} #{signature}; } end def storage(target) = target # Return C pointer to contiguous storage def render_forward_declarations(stream) stream << %{ #include <stdio.h> #include <malloc.h> #include <stdarg.h> /* overridable internal buffer size (in chars, not bytes) for *sprintf() operations */ #ifndef AUTOC_BUFFER_SIZE #define AUTOC_BUFFER_SIZE 1024 #endif } super end def type_tag = "#{signature}<#{element}>" private def configure super method(:void, :create, { target: lvalue, source: const_rvalue }, instance: :custom_create, constraint:-> { custom_constructible? }).configure do header %{ @brief Create string @param[out] target string to be created @param[in] source string to be copied This function creates & initializes a new string by making an independent of the source string. This specifically means that the supplied source string may be any C string, either const or mutable, including string literal. Previous contents of `*target` is overwritten. Once constructed, the string is to be destroyed with @ref #{destroy}. @since 2.0 } inline_code %{ size_t size; assert(target); assert(source); size = strlen(source); *target = #{memory.allocate(element, 'size+1', atomic: true)}; assert(*target); memcpy(*target, source, size*sizeof(#{element})); (*target)[size] = '\\0'; } end method(:int, :create_format, { target: lvalue, format: const_rvalue }, variadic: true ).configure do code %{ int r; va_list args; #if defined(HAVE_VSNPRINTF) || __STDC_VERSION__ >= 199901L || __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER >= 1900) || defined(__POCC__) va_start(args, format); r = vsnprintf(NULL, 0, format, args); va_end(args); if(r < 0) return 0; *target = #{memory.allocate(element, 'r+1', atomic: true)}; assert(*target); va_start(args, format); r = vsnprintf(*target, r+1, format, args); va_end(args); return r >= 0; #else #if defined(_MSC_VER) #pragma message("WARNING: this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #else #warning("this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #endif va_start(args, format); #{element.lvalue} t = #{memory.allocate(element, :AUTOC_BUFFER_SIZE, atomic: true)}; assert(t); r = vsprintf(t, format, args); if(r >= 0) { if(r > AUTOC_BUFFER_SIZE-1) { /* the output spilled out of the preallocated buffer - perfer to bail out right away rather than to get likely heap corruption */ abort(); } /* prefer precision over performance and make a copy instead of returning a (possibly excessive) buffer */ #{default_create.(target, :t)}; } /* FIXME handle the case of simultaneous (r < 0 && buffer overrun) */ #{memory.free(:t)}; va_end(args); return r >= 0; #endif } header %{ @brief Create formatted string @param[out] target string to be created @param[in] format format template @param[in] ... format parameters @result non-zero value on successful construction and zero value otherwise This function employs a standard C function from the s*printf() family to create new formatted string. @note No `*target` is modified on function failure. @since 2.0 } end destroy.configure do inline_code %{ assert(target); #{memory.free('*target')}; } end copy.configure do dependencies << custom_create inline_code %{ #{custom_create.(*parameters)}; } end get.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return target[index]; } end set.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); target[index] = value; } end view.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return &target[index]; } end equal.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right) == 0; } end compare.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right); } end hash_code.configure do code %{ /* djb2 algorithm: http://www.cse.yorku.ca/~oz/hash.html */ size_t c; size_t hash; #{element.lvalue} s; assert(target); hash = 5381; s = target; while((c = *s++)) hash = hash*33 ^ c; return hash; } end contains.configure do inline_code %{ assert(target); return strchr(target, value) != NULL; } end find_first.configure do inline_code %{ assert(target); return strchr(target, value); } end check.configure do dependencies << size inline_code %{ assert(target); return index < #{size.(target)}; } end empty.configure do inline_code %{ assert(target); return *target == '\\0'; } end size.configure do inline_code %{ assert(target); return strlen(target); } end end end # CString CString::
render_forward_declarations(stream)
click to toggle source
Calls superclass method
# File lib/autoc/cstring.rb, line 60 def render_forward_declarations(stream) stream << %{ #include <stdio.h> #include <malloc.h> #include <stdarg.h> /* overridable internal buffer size (in chars, not bytes) for *sprintf() operations */ #ifndef AUTOC_BUFFER_SIZE #define AUTOC_BUFFER_SIZE 1024 #endif } super end
render_interface(stream)
click to toggle source
# File lib/autoc/cstring.rb, line 37 def render_interface(stream) if public? stream << %{ /** #{defgroup} @brief Value type wrapper of the plain C string This type represents a (paper thin) wrapper around the plain C string (char *) with proper value semantics. @since 2.0 */ } else stream << PRIVATE end stream << %{ typedef #{element.lvalue} #{signature}; } end
rvalue(= @rv ||= Value.new(self))
click to toggle source
# File lib/autoc/cstring.rb, line 29 def rvalue = @rv ||= Value.new(self) def lvalue = @lv ||= Value.new(self, reference: true) def const_rvalue = @crv ||= Value.new(self, constant: true) def const_lvalue = @clv ||= Value.new(self, reference: true, constant: true) def render_interface(stream) if public? stream << %{ /** #{defgroup} @brief Value type wrapper of the plain C string This type represents a (paper thin) wrapper around the plain C string (char *) with proper value semantics. @since 2.0 */ } else stream << PRIVATE end stream << %{ typedef #{element.lvalue} #{signature}; } end def storage(target) = target # Return C pointer to contiguous storage def render_forward_declarations(stream) stream << %{ #include <stdio.h> #include <malloc.h> #include <stdarg.h> /* overridable internal buffer size (in chars, not bytes) for *sprintf() operations */ #ifndef AUTOC_BUFFER_SIZE #define AUTOC_BUFFER_SIZE 1024 #endif } super end def type_tag = "#{signature}<#{element}>" private def configure super method(:void, :create, { target: lvalue, source: const_rvalue }, instance: :custom_create, constraint:-> { custom_constructible? }).configure do header %{ @brief Create string @param[out] target string to be created @param[in] source string to be copied This function creates & initializes a new string by making an independent of the source string. This specifically means that the supplied source string may be any C string, either const or mutable, including string literal. Previous contents of `*target` is overwritten. Once constructed, the string is to be destroyed with @ref #{destroy}. @since 2.0 } inline_code %{ size_t size; assert(target); assert(source); size = strlen(source); *target = #{memory.allocate(element, 'size+1', atomic: true)}; assert(*target); memcpy(*target, source, size*sizeof(#{element})); (*target)[size] = '\\0'; } end method(:int, :create_format, { target: lvalue, format: const_rvalue }, variadic: true ).configure do code %{ int r; va_list args; #if defined(HAVE_VSNPRINTF) || __STDC_VERSION__ >= 199901L || __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER >= 1900) || defined(__POCC__) va_start(args, format); r = vsnprintf(NULL, 0, format, args); va_end(args); if(r < 0) return 0; *target = #{memory.allocate(element, 'r+1', atomic: true)}; assert(*target); va_start(args, format); r = vsnprintf(*target, r+1, format, args); va_end(args); return r >= 0; #else #if defined(_MSC_VER) #pragma message("WARNING: this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #else #warning("this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #endif va_start(args, format); #{element.lvalue} t = #{memory.allocate(element, :AUTOC_BUFFER_SIZE, atomic: true)}; assert(t); r = vsprintf(t, format, args); if(r >= 0) { if(r > AUTOC_BUFFER_SIZE-1) { /* the output spilled out of the preallocated buffer - perfer to bail out right away rather than to get likely heap corruption */ abort(); } /* prefer precision over performance and make a copy instead of returning a (possibly excessive) buffer */ #{default_create.(target, :t)}; } /* FIXME handle the case of simultaneous (r < 0 && buffer overrun) */ #{memory.free(:t)}; va_end(args); return r >= 0; #endif } header %{ @brief Create formatted string @param[out] target string to be created @param[in] format format template @param[in] ... format parameters @result non-zero value on successful construction and zero value otherwise This function employs a standard C function from the s*printf() family to create new formatted string. @note No `*target` is modified on function failure. @since 2.0 } end destroy.configure do inline_code %{ assert(target); #{memory.free('*target')}; } end copy.configure do dependencies << custom_create inline_code %{ #{custom_create.(*parameters)}; } end get.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return target[index]; } end set.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); target[index] = value; } end view.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return &target[index]; } end equal.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right) == 0; } end compare.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right); } end hash_code.configure do code %{ /* djb2 algorithm: http://www.cse.yorku.ca/~oz/hash.html */ size_t c; size_t hash; #{element.lvalue} s; assert(target); hash = 5381; s = target; while((c = *s++)) hash = hash*33 ^ c; return hash; } end contains.configure do inline_code %{ assert(target); return strchr(target, value) != NULL; } end find_first.configure do inline_code %{ assert(target); return strchr(target, value); } end check.configure do dependencies << size inline_code %{ assert(target); return index < #{size.(target)}; } end empty.configure do inline_code %{ assert(target); return *target == '\\0'; } end size.configure do inline_code %{ assert(target); return strlen(target); } end end end # CString CString::Range
storage(target)
click to toggle source
# File lib/autoc/cstring.rb, line 58 def storage(target) = target # Return C pointer to contiguous storage def render_forward_declarations(stream) stream << %{ #include <stdio.h> #include <malloc.h> #include <stdarg.h> /* overridable internal buffer size (in chars, not bytes) for *sprintf() operations */ #ifndef AUTOC_BUFFER_SIZE #define AUTOC_BUFFER_SIZE 1024 #endif } super end def type_tag = "#{signature}<#{element}>" private def configure super method(:void, :create, { target: lvalue, source: const_rvalue }, instance: :custom_create, constraint:-> { custom_constructible? }).configure do header %{ @brief Create string @param[out] target string to be created @param[in] source string to be copied This function creates & initializes a new string by making an independent of the source string. This specifically means that the supplied source string may be any C string, either const or mutable, including string literal. Previous contents of `*target` is overwritten. Once constructed, the string is to be destroyed with @ref #{destroy}. @since 2.0 } inline_code %{ size_t size; assert(target); assert(source); size = strlen(source); *target = #{memory.allocate(element, 'size+1', atomic: true)}; assert(*target); memcpy(*target, source, size*sizeof(#{element})); (*target)[size] = '\\0'; } end method(:int, :create_format, { target: lvalue, format: const_rvalue }, variadic: true ).configure do code %{ int r; va_list args; #if defined(HAVE_VSNPRINTF) || __STDC_VERSION__ >= 199901L || __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER >= 1900) || defined(__POCC__) va_start(args, format); r = vsnprintf(NULL, 0, format, args); va_end(args); if(r < 0) return 0; *target = #{memory.allocate(element, 'r+1', atomic: true)}; assert(*target); va_start(args, format); r = vsnprintf(*target, r+1, format, args); va_end(args); return r >= 0; #else #if defined(_MSC_VER) #pragma message("WARNING: this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #else #warning("this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #endif va_start(args, format); #{element.lvalue} t = #{memory.allocate(element, :AUTOC_BUFFER_SIZE, atomic: true)}; assert(t); r = vsprintf(t, format, args); if(r >= 0) { if(r > AUTOC_BUFFER_SIZE-1) { /* the output spilled out of the preallocated buffer - perfer to bail out right away rather than to get likely heap corruption */ abort(); } /* prefer precision over performance and make a copy instead of returning a (possibly excessive) buffer */ #{default_create.(target, :t)}; } /* FIXME handle the case of simultaneous (r < 0 && buffer overrun) */ #{memory.free(:t)}; va_end(args); return r >= 0; #endif } header %{ @brief Create formatted string @param[out] target string to be created @param[in] format format template @param[in] ... format parameters @result non-zero value on successful construction and zero value otherwise This function employs a standard C function from the s*printf() family to create new formatted string. @note No `*target` is modified on function failure. @since 2.0 } end destroy.configure do inline_code %{ assert(target); #{memory.free('*target')}; } end copy.configure do dependencies << custom_create inline_code %{ #{custom_create.(*parameters)}; } end get.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return target[index]; } end set.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); target[index] = value; } end view.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return &target[index]; } end equal.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right) == 0; } end compare.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right); } end hash_code.configure do code %{ /* djb2 algorithm: http://www.cse.yorku.ca/~oz/hash.html */ size_t c; size_t hash; #{element.lvalue} s; assert(target); hash = 5381; s = target; while((c = *s++)) hash = hash*33 ^ c; return hash; } end contains.configure do inline_code %{ assert(target); return strchr(target, value) != NULL; } end find_first.configure do inline_code %{ assert(target); return strchr(target, value); } end check.configure do dependencies << size inline_code %{ assert(target); return index < #{size.(target)}; } end empty.configure do inline_code %{ assert(target); return *target == '\\0'; } end size.configure do inline_code %{ assert(target); return strlen(target); } end end end # CString CString::Range = ContiguousRange # Range end
type_tag(= "
click to toggle source
# File lib/autoc/cstring.rb, line 73 def type_tag = "#{signature}<#{element}>" private def configure super method(:void, :create, { target: lvalue, source: const_rvalue }, instance: :custom_create, constraint:-> { custom_constructible? }).configure do header %{ @brief Create string @param[out] target string to be created @param[in] source string to be copied This function creates & initializes a new string by making an independent of the source string. This specifically means that the supplied source string may be any C string, either const or mutable, including string literal. Previous contents of `*target` is overwritten. Once constructed, the string is to be destroyed with @ref #{destroy}. @since 2.0 } inline_code %{ size_t size; assert(target); assert(source); size = strlen(source); *target = #{memory.allocate(element, 'size+1', atomic: true)}; assert(*target); memcpy(*target, source, size*sizeof(#{element})); (*target)[size] = '\\0'; } end method(:int, :create_format, { target: lvalue, format: const_rvalue }, variadic: true ).configure do code %{ int r; va_list args; #if defined(HAVE_VSNPRINTF) || __STDC_VERSION__ >= 199901L || __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER >= 1900) || defined(__POCC__) va_start(args, format); r = vsnprintf(NULL, 0, format, args); va_end(args); if(r < 0) return 0; *target = #{memory.allocate(element, 'r+1', atomic: true)}; assert(*target); va_start(args, format); r = vsnprintf(*target, r+1, format, args); va_end(args); return r >= 0; #else #if defined(_MSC_VER) #pragma message("WARNING: this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #else #warning("this code employs bare sprintf() with preallocated temporary buffer of AUTOC_BUFFER_SIZE chars; expect execution bail outs upon exceeding this limit") #endif va_start(args, format); #{element.lvalue} t = #{memory.allocate(element, :AUTOC_BUFFER_SIZE, atomic: true)}; assert(t); r = vsprintf(t, format, args); if(r >= 0) { if(r > AUTOC_BUFFER_SIZE-1) { /* the output spilled out of the preallocated buffer - perfer to bail out right away rather than to get likely heap corruption */ abort(); } /* prefer precision over performance and make a copy instead of returning a (possibly excessive) buffer */ #{default_create.(target, :t)}; } /* FIXME handle the case of simultaneous (r < 0 && buffer overrun) */ #{memory.free(:t)}; va_end(args); return r >= 0; #endif } header %{ @brief Create formatted string @param[out] target string to be created @param[in] format format template @param[in] ... format parameters @result non-zero value on successful construction and zero value otherwise This function employs a standard C function from the s*printf() family to create new formatted string. @note No `*target` is modified on function failure. @since 2.0 } end destroy.configure do inline_code %{ assert(target); #{memory.free('*target')}; } end copy.configure do dependencies << custom_create inline_code %{ #{custom_create.(*parameters)}; } end get.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return target[index]; } end set.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); target[index] = value; } end view.configure do dependencies << check inline_code %{ assert(target); assert(#{check.(target, index)}); return &target[index]; } end equal.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right) == 0; } end compare.configure do inline_code %{ assert(left); assert(right); return strcmp(left, right); } end hash_code.configure do code %{ /* djb2 algorithm: http://www.cse.yorku.ca/~oz/hash.html */ size_t c; size_t hash; #{element.lvalue} s; assert(target); hash = 5381; s = target; while((c = *s++)) hash = hash*33 ^ c; return hash; } end contains.configure do inline_code %{ assert(target); return strchr(target, value) != NULL; } end find_first.configure do inline_code %{ assert(target); return strchr(target, value); } end check.configure do dependencies << size inline_code %{ assert(target); return index < #{size.(target)}; } end empty.configure do inline_code %{ assert(target); return *target == '\\0'; } end size.configure do inline_code %{ assert(target); return strlen(target); } end end end