long MPEG_File::previousFrameOffset(long position) { // TODO: This will miss syncs spanning buffer read boundaries. while(int(position - BufferSize()) > int(BufferSize())) { position -= BufferSize(); Seek(position); SjByteVector buffer = ReadBlock(BufferSize()); // If the amount of data is smaller than an MPEG header (4 bytes) there's no // chance of this being valid. if(buffer.size() < 4) { return -1; } for(int i = buffer.size() - 2; i >= 0; i--) { if((unsigned char)(buffer[i]) == 0xff && secondSynchByte(buffer[i + 1])) { return position + i; } } } return -1; }
static bool SaveBufferCallback(const char *dest_filename, void *param, NewLineMode new_line_mode) { FILE *fp = safe_fopen(dest_filename, (new_line_mode == NewLineMode_Native) ? "wt" : "w"); if (!fp) { Log(LOG_LEVEL_ERR, "Unable to open destination file '%s' for writing. (fopen: %s)", dest_filename, GetErrorStr()); return false; } Buffer *output_buffer = param; size_t bytes_written = fwrite(BufferData(output_buffer), sizeof(char), BufferSize(output_buffer), fp); if (bytes_written != BufferSize(output_buffer)) { Log(LOG_LEVEL_ERR, "Error writing to output file '%s' when writing. %zd bytes written but expected %d. (fclose: %s)", dest_filename, bytes_written, BufferSize(output_buffer), GetErrorStr()); fclose(fp); return false; } if (fclose(fp) == -1) { Log(LOG_LEVEL_ERR, "Unable to close file '%s' after writing. (fclose: %s)", dest_filename, GetErrorStr()); return false; } return true; }
static int p_set_par_goal(value v, type t) { pword *old_tg = TG; pword term, *term_as_bytes; amsg_data_t *msg_data; if (par_goal_msg_) (void) amsg_free(par_goal_msg_); /* encode the term */ term.val.all = v.all; term.tag.kernel = t.kernel; term_as_bytes = term_to_dbformat(&term, D_UNKNOWN); /* fill into a message buffer */ if (amsg_alloc((amsg_size_t) BufferSize(term_as_bytes), &msg_data, &par_goal_msg_) != AMSG_OK) { Bip_Error(MPS_ERROR); } bmem_cpy( (generic_ptr) msg_data, (generic_ptr) BufferStart(term_as_bytes), (bmem_size_t) BufferSize(term_as_bytes)); TG = old_tg; /* pop the temporary stack string */ Succeed_; }
static void test_zeroBuffer(void) { char *element0 = xstrdup("element0"); unsigned int element0size = strlen(element0); const char *element0pointer = NULL; Buffer *buffer = BufferNew(); assert_int_equal(element0size, BufferSet(buffer, element0, element0size)); element0pointer = buffer->buffer; assert_int_equal(element0size, buffer->used); assert_int_equal(element0size, BufferSize(buffer)); BufferZero(buffer); assert_int_equal(DEFAULT_BUFFER_SIZE, buffer->capacity); assert_int_equal(0, buffer->used); assert_int_equal(0, BufferSize(buffer)); const char *data = BufferData(buffer); assert_string_equal(data, ""); assert_true(element0pointer == buffer->buffer); BufferZero(NULL); assert_int_equal(0, BufferDestroy(&buffer)); /* * Release the resources */ BufferDestroy(&buffer); free (element0); }
Rlist *RlistFromSplitRegex(const char *string, const char *regex, size_t max_entries, bool allow_blanks) { assert(string); if (!string) { return NULL; } const char *sp = string; size_t entry_count = 0; int start = 0; int end = 0; Rlist *result = NULL; Buffer *buffer = BufferNewWithCapacity(CF_MAXVARSIZE); pcre *rx = CompileRegex(regex); if (rx) { while ((entry_count < max_entries) && StringMatchWithPrecompiledRegex(rx, sp, &start, &end)) { if (end == 0) { break; } BufferClear(buffer); BufferAppend(buffer, sp, start); if (allow_blanks || BufferSize(buffer) > 0) { RlistAppendScalar(&result, BufferData(buffer)); entry_count++; } sp += end; } pcre_free(rx); } if (entry_count < max_entries) { BufferClear(buffer); size_t remaining = strlen(sp); BufferAppend(buffer, sp, remaining); if ((allow_blanks && sp != string) || BufferSize(buffer) > 0) { RlistAppendScalar(&result, BufferData(buffer)); } } BufferDestroy(buffer); return result; }
// returns NULL on success, otherwise an error string const char* BufferSearchAndReplace(Buffer *buffer, const char *pattern, const char *substitute, const char *options) { assert(buffer); assert(pattern); assert(substitute); assert(options); int err; pcre_wrap_job *job = pcre_wrap_compile(pattern, substitute, options, &err); if (job == NULL) { return pcre_wrap_strerror(err); } size_t length = BufferSize(buffer); char *result; if (0 > (err = pcre_wrap_execute(job, (char*)BufferData(buffer), length, &result, &length))) { return pcre_wrap_strerror(err); } BufferSet(buffer, result, length); free(result); pcre_wrap_free_job(job); return NULL; }
void UpdateBuffer(){ if(!mDynamic) return; if(mBufferID == GL_INVALID_INDEX) LoadBuffer(); OpenGL::BindBuffer(GL_ARRAY_BUFFER, mBufferID); OpenGL::BufferData(GL_ARRAY_BUFFER, BufferSize(), Buffer(), GL_DYNAMIC_DRAW); }
INT32 Adreno::MemoryBuffer::ExpandBuffer( INT32 num_new_bytes ) { INT32 old_size = BufferSize(); INT32 new_size = old_size + num_new_bytes; if( new_size > 0 ) { BYTE* new_buffer = new BYTE[ new_size ]; // Copy the old buffer if( m_buffer ) { for( INT32 i = 0; i < old_size; ++i ) { new_buffer[ i ] = m_buffer[ i ]; } DeleteBuffer(); } // Zero out the new bytes for( INT32 i = old_size; i < new_size; ++i ) { new_buffer[ i ] = 0; } // Use the new buffer m_size = new_size; m_buffer = new_buffer; } return old_size; }
void BufferRewrite(Buffer *buffer, BufferFilterFn filter, const bool invert) { assert(buffer); Buffer *rewrite = BufferFilter(buffer, filter, invert); BufferSet(buffer, BufferData(rewrite), BufferSize(rewrite)); BufferDestroy(rewrite); }
void SSLBufferTryWrite(struct sslbuffer_t *sslbuffer) { int res; unsigned long error; if (!sslbuffer->fl_writing) { if (BufferSize(sslbuffer->write_buffer_1) > 0) BufferCopy(sslbuffer->write_buffer_2, sslbuffer->write_buffer_1); } if (BufferSize(sslbuffer->write_buffer_2) > 0) { res = SSL_write( sslbuffer->ssl, BufferStart(sslbuffer->write_buffer_2), BufferSize(sslbuffer->write_buffer_2)); if (res <= 0) { error = SSL_get_error(sslbuffer->ssl, res); sslbuffer->fl_writing = 1; if (error == SSL_ERROR_WANT_READ) sslbuffer->fl_want_read = 1; else if (error == SSL_ERROR_WANT_WRITE) sslbuffer->fl_want_write = 1; else { printf("%s:%d: unknown error %lu\n", __FILE__, __LINE__, error); print_errors(); event_base_loopbreak(sslbuffer->base); } return; } BufferRemove(sslbuffer->write_buffer_2, (size_t) res); sslbuffer->fl_writing = 0; sslbuffer->fl_want_write = 0; sslbuffer->fl_want_read = 0; } if ( (BufferSize(sslbuffer->write_buffer_1) == 0) && (BufferSize(sslbuffer->write_buffer_2) == 0)) { event_del(sslbuffer->ev_write); } }
static void PathConcatImpl(PathBuffer* buffer, const T* other) { CHECK(!PathIsAbsolute(other)); int seg_count = buffer->m_SegCount; int min_seg_count = (buffer->m_Flags & PathBuffer::kFlagWindowsDevicePath) ? 1 : 0; // Start by throwing away .. from the other path for (int i = 0, count = other->m_LeadingDotDots; i < count; ++i) { if (seg_count > min_seg_count) { seg_count--; } else if (seg_count == 0) { buffer->m_LeadingDotDots++; } } // Can't go higher than root directory. Just clamp to there. if (PathIsAbsolute(buffer)) { buffer->m_LeadingDotDots = 0; } // Compute how much of our data buffer we need to keep int keep_buffer = BufferSize(buffer, seg_count); // Compute size of the other buffer. int other_buffer = BufferSize(other, other->m_SegCount); CHECK(seg_count + other->m_SegCount <= kMaxPathSegments); CHECK(keep_buffer + other_buffer <= kMaxPathLength); memcpy(buffer->m_Data + keep_buffer, other->m_Data, other_buffer); for (int i = 0, count = other->m_SegCount; i < count; ++i) { buffer->m_SegEnds[seg_count + i] = uint16_t(other->m_SegEnds[i] + keep_buffer); } buffer->m_SegCount = uint16_t(seg_count + other->m_SegCount); }
static void test_zeroBuffer(void **state) { char element0[] = "element0"; unsigned int element0size = strlen(element0); const char *element0pointer = NULL; Buffer *buffer = NULL; assert_int_equal(0, BufferNew(&buffer)); assert_int_equal(element0size, BufferSet(buffer, element0, element0size)); element0pointer = buffer->buffer; assert_int_equal(element0size, buffer->used); assert_int_equal(element0size, BufferSize(buffer)); BufferZero(buffer); assert_int_equal(DEFAULT_BUFFER_SIZE, buffer->capacity); assert_int_equal(0, buffer->used); assert_int_equal(0, BufferSize(buffer)); assert_true(element0pointer == buffer->buffer); BufferZero(NULL); assert_int_equal(0, BufferDestroy(&buffer)); }
bool LoadBuffer(){ OpenGL::GenBuffers(1, &mBufferID); if(!mBufferID){ mBufferID = GL_INVALID_INDEX; return false; } OpenGL::BindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferID); OpenGL::BufferData(GL_ELEMENT_ARRAY_BUFFER, BufferSize(), Buffer(), GL_STATIC_DRAW); return true; }
ScriptProcessorNode::ScriptProcessorNode(AudioContext* aContext, uint32_t aBufferSize, uint32_t aNumberOfInputChannels, uint32_t aNumberOfOutputChannels) : AudioNode(aContext, aNumberOfInputChannels, mozilla::dom::ChannelCountMode::Explicit, mozilla::dom::ChannelInterpretation::Speakers) , mBufferSize(aBufferSize ? aBufferSize : // respect what the web developer requested 4096) // choose our own buffer size -- 4KB for now , mNumberOfOutputChannels(aNumberOfOutputChannels) { MOZ_ASSERT(BufferSize() % WEBAUDIO_BLOCK_SIZE == 0, "Invalid buffer size"); ScriptProcessorNodeEngine* engine = new ScriptProcessorNodeEngine(this, aContext->Destination(), BufferSize(), aNumberOfInputChannels); mStream = AudioNodeStream::Create(aContext, engine, AudioNodeStream::NO_STREAM_FLAGS, aContext->Graph()); }
long MPEG_File::nextFrameOffset(long position) { // TODO: This will miss syncs spanning buffer read boundaries. SjByteVector buffer = ReadBlock(BufferSize()); while(buffer.size() > 0) { Seek(position); SjByteVector buffer = ReadBlock(BufferSize()); for(SjUint i = 0; i < buffer.size(); i++) { if((unsigned char)(buffer[i]) == 0xff && secondSynchByte(buffer[i + 1])) { return position + i; } } position += BufferSize(); } return -1; }
static int p_dbag_enter(value vbag, type tbag, value vterm, type tterm) { aport_id_t bag_aport_id; pword term, *term_as_bytes; pword *old_tg = TG; amsg_size_t msg_size; amsg_t msg; amsg_data_t *msg_data; Check_Integer(tbag); bag_aport_id = (aport_id_t) vbag.nint; /* encode the term */ term.val.all = vterm.all; term.tag.kernel = tterm.kernel; term_as_bytes = term_to_dbformat(&term, D_UNKNOWN); /* fill into a message buffer */ msg_size = BufferSize(term_as_bytes) + sizeof(amsg_ref_t); if (amsg_alloc(msg_size, &msg_data, &msg) != AMSG_OK) { Bip_Error(MPS_ERROR); } bmem_cpy((generic_ptr) ((char *) msg_data + sizeof(amsg_ref_t)), (generic_ptr) BufferStart(term_as_bytes), (bmem_size_t) BufferSize(term_as_bytes)); TG = old_tg; /* pop the temporary stack string */ /* send the message */ if (amsg_send(bag_aport_id, msg, MDT_BYTE, (amsg_count_t) msg_size, 0) != AMSG_OK) { Bip_Error(MPS_ERROR); } Succeed_; }
void StillsStream::NextDTSPTS( ) { StillsParams *sparms = static_cast<StillsParams*>(parms); clockticks interval = static_cast<clockticks> (sparms->Intervals()->NextFrameInterval() * CLOCKS / frame_rate); clockticks time_for_xfer; muxinto.ByteposTimecode( BufferSize(), time_for_xfer ); access_unit.DTS = current_PTS + time_for_xfer; // This frame decoded just after // Predecessor completed. access_unit.PTS = current_PTS + time_for_xfer + interval; current_PTS = access_unit.PTS; current_DTS = access_unit.DTS; fields_presented += 2; }
void Adreno::MemoryBuffer::WriteData( INT32 start_position, const void* data, INT32 size ) { if( data && size > 0 ) { if( ( start_position >= 0 ) && ( start_position + size <= BufferSize() ) ) { const BYTE* source_data = (const BYTE*)data; for( INT32 i = 0; i < size; ++i ) { BYTE& dest = m_buffer[ start_position + i ]; dest = source_data[ i ]; } } } }
void StructuredCloneHelper::MoveBufferDataToArray(FallibleTArray<uint8_t>& aArray, ErrorResult& aRv) { MOZ_ASSERT(mBuffer, "MoveBuffer() cannot be called without a Write()."); if (NS_WARN_IF(!aArray.SetLength(BufferSize(), mozilla::fallible))) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } uint64_t* buffer; size_t size; mBuffer->steal(&buffer, &size); mBuffer = nullptr; memcpy(aArray.Elements(), buffer, size); js_free(buffer); }
/** * Grow the rx buffer to the new size. */ void IncomingStreamTransport::IncreaseBufferSize(unsigned int new_size) { if (new_size <= BufferSize()) return; new_size = std::max(new_size, INITIAL_SIZE); unsigned int data_length = DataLength(); if (!m_buffer_start) data_length = 0; // allocate new buffer and copy the data over uint8_t *buffer = new uint8_t[new_size]; if (m_buffer_start) { if (data_length > 0) // this moves the data to the start of the buffer if it wasn't already memcpy(buffer, m_buffer_start, data_length); delete[] m_buffer_start; } m_buffer_start = buffer; m_buffer_end = buffer + new_size; m_data_end = buffer + data_length; }
status_t LocalDevice::_ReadBufferSize() { int8 bt_status = BT_ERROR; BluetoothCommand<> BufferSize(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE); BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); BMessage reply; request.AddInt32("hci_id", fHid); request.AddData("raw command", B_ANY_TYPE, BufferSize.Data(), BufferSize.Size()); request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE)); if (fMessenger->SendMessage(&request, &reply) == B_OK) reply.FindInt8("status", &bt_status); return bt_status; }
long MPEG_File::findID3v2() { // This method is based on the contents of Tagger_File::find(), but because // of some subtlteies -- specifically the need to look for the bit pattern of // an MPEG sync, it has been modified for use here. if( IsValid() && ID3v2_Header::fileIdentifier().size() <= BufferSize() ) { // The position in the file that the current buffer starts at. long bufferOffset = 0; SjByteVector buffer; // These variables are used to keep track of a partial match that happens at // the end of a buffer. int previousPartialMatch = -1; bool previousPartialSynchMatch = false; // Save the location of the current read pointer. We will restore the // position using seek() before all returns. long originalPosition = Tell(); // Start the search at the beginning of the file. Seek(0); // This loop is the crux of the find method. There are three cases that we // want to account for: // (1) The previously searched buffer contained a partial match of the search // pattern and we want to see if the next one starts with the remainder of // that pattern. // // (2) The search pattern is wholly contained within the current buffer. // // (3) The current buffer ends with a partial match of the pattern. We will // note this for use in the next itteration, where we will check for the rest // of the pattern. for(buffer = ReadBlock(BufferSize()); buffer.size() > 0; buffer = ReadBlock(BufferSize())) { // (1) previous partial match if(previousPartialSynchMatch && secondSynchByte(buffer[0])) { return -1; } if(previousPartialMatch >= 0 && int(BufferSize()) > previousPartialMatch) { const int patternOffset = (BufferSize() - previousPartialMatch); if(buffer.containsAt(ID3v2_Header::fileIdentifier(), 0, patternOffset)) { Seek(originalPosition); return bufferOffset - BufferSize() + previousPartialMatch; } } // (2) pattern contained in current buffer long location = buffer.find(ID3v2_Header::fileIdentifier()); if(location >= 0) { Seek(originalPosition); return bufferOffset + location; } int firstSynchByte = buffer.find(/*(char)*/((unsigned char)(255))); // Here we have to loop because there could be several of the first // (11111111) byte, and we want to check all such instances until we find // a full match (11111111 111) or hit the end of the buffer. while(firstSynchByte >= 0) { // if this *is not* at the end of the buffer if(firstSynchByte < int(buffer.size()) - 1) { if(secondSynchByte(buffer[firstSynchByte + 1])) { // We've found the frame synch pattern. Seek(originalPosition); return -1; } else { // We found 11111111 at the end of the current buffer indicating a // partial match of the synch pattern. The find() below should // return -1 and break out of the loop. previousPartialSynchMatch = true; } } // Check in the rest of the buffer. firstSynchByte = buffer.find(/*char*/((unsigned char)(255)), firstSynchByte + 1); } // (3) partial match previousPartialMatch = buffer.endsWithPartialMatch(ID3v2_Header::fileIdentifier()); bufferOffset += BufferSize(); } // for() // Since we hit the end of the file, reset the status before continuing. Clear(); Seek(originalPosition); } return -1; }
void AveragingAnalogRead::Event_ReplaceValue(int aOldValue, int aNewValue, byte aIndex) { _Total += aNewValue - aOldValue; byte count = BufferSize(); Value = (_Total / (count/2)+1) / 2; }
static void ExpandAndMapIteratorsFromScalar(EvalContext *ctx, const Bundle *bundle, char *string, size_t length, int level, Rlist **scalars, Rlist **lists, Rlist **containers, Rlist **full_expansion) { assert(string); if (!string) { return; } Buffer *value = BufferNew(); for (size_t i = 0; i < length; i++) { const char *sp = string + i; Rlist *tmp_list = NULL; BufferZero(value); if (ExtractScalarPrefix(value, sp, length - i)) { if (full_expansion) { RlistConcatInto(&tmp_list, *full_expansion, BufferData(value)); RlistDestroy(*full_expansion); *full_expansion = tmp_list; tmp_list = NULL; } sp += BufferSize(value); i += BufferSize(value); BufferZero(value); if (i >= length) { break; } } if (*sp == '$') { BufferZero(value); ExtractScalarReference(value, sp, length - i, true); if (BufferSize(value) > 0) { Rlist *inner_expansion = NULL; Rlist *exp = NULL; int success = 0; VarRef *ref = VarRefParse(BufferData(value)); int increment = BufferSize(value) - 1 + 3; // Handle any embedded variables char *substring = string + i + 2; ExpandAndMapIteratorsFromScalar(ctx, bundle, substring, BufferSize(value), level+1, scalars, lists, containers, &inner_expansion); for (exp = inner_expansion; exp != NULL; exp = exp->next) { // If a list is non-local, i.e. $(bundle.var), map it to local $(bundle#var) // NB without modifying variables as we map them, it's not // possible to handle remote lists referenced by a variable // scope. For example: // scope => "test."; var => "somelist"; $($(scope)$(var)) fails // varname => "test.somelist"; $($(varname)) also fails // TODO Unless the consumer handles it? const char *inner_ref_str = RlistScalarValue(exp); VarRef *inner_ref = VarRefParseFromBundle(inner_ref_str, bundle); // var is the expanded name of the variable in its native context // finalname will be the mapped name in the local context "this." DataType value_type = DATA_TYPE_NONE; const void *value = EvalContextVariableGet(ctx, inner_ref, &value_type); if (value) { char *mangled_inner_ref = xstrdup(inner_ref_str); MangleVarRefString(mangled_inner_ref, strlen(mangled_inner_ref)); success++; switch (DataTypeToRvalType(value_type)) { case RVAL_TYPE_LIST: if (level > 0) { RlistPrependScalarIdemp(lists, mangled_inner_ref); } else { RlistAppendScalarIdemp(lists, mangled_inner_ref); } if (full_expansion) { for (const Rlist *rp = value; rp != NULL; rp = rp->next) { // append each slist item to each of full_expansion RlistConcatInto(&tmp_list, *full_expansion, RlistScalarValue(rp)); } } break; case RVAL_TYPE_SCALAR: RlistAppendScalarIdemp(scalars, mangled_inner_ref); if (full_expansion) { // append the scalar value to each of full_expansion RlistConcatInto(&tmp_list, *full_expansion, value); } break; case RVAL_TYPE_CONTAINER: if (level > 0) { RlistPrependScalarIdemp(containers, mangled_inner_ref); } else { RlistAppendScalarIdemp(containers, mangled_inner_ref); } break; case RVAL_TYPE_FNCALL: case RVAL_TYPE_NOPROMISEE: break; } free(mangled_inner_ref); } VarRefDestroy(inner_ref); } RlistDestroy(inner_expansion); if (full_expansion) { RlistDestroy(*full_expansion); *full_expansion = tmp_list; tmp_list = NULL; } // No need to map this.* even though it's technically qualified if (success && IsQualifiedVariable(BufferData(value)) && strcmp(ref->scope, "this") != 0) { char *dotpos = strchr(substring, '.'); if (dotpos) { *dotpos = CF_MAPPEDLIST; // replace '.' with '#' } if (strchr(BufferData(value), ':')) { char *colonpos = strchr(substring, ':'); if (colonpos) { *colonpos = '*'; } } } VarRefDestroy(ref); sp += increment; i += increment; } } } BufferDestroy(value); }
int LoadFileAsItemList(Item **liststart, const char *file, EditDefaults edits) { { struct stat statbuf; if (stat(file, &statbuf) == -1) { Log(LOG_LEVEL_VERBOSE, "The proposed file '%s' could not be loaded. (stat: %s)", file, GetErrorStr()); return false; } if (edits.maxfilesize != 0 && statbuf.st_size > edits.maxfilesize) { Log(LOG_LEVEL_INFO, "File '%s' is bigger than the limit edit.max_file_size = %jd > %d bytes", file, (intmax_t) statbuf.st_size, edits.maxfilesize); return (false); } if (!S_ISREG(statbuf.st_mode)) { Log(LOG_LEVEL_INFO, "%s is not a plain file", file); return false; } } FILE *fp = safe_fopen(file, "r"); if (!fp) { Log(LOG_LEVEL_INFO, "Couldn't read file '%s' for editing. (fopen: %s)", file, GetErrorStr()); return false; } Buffer *concat = BufferNew(); size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); bool result = true; for (;;) { ssize_t num_read = CfReadLine(&line, &line_size, fp); if (num_read == -1) { if (!feof(fp)) { Log(LOG_LEVEL_ERR, "Unable to read contents of '%s'. (fread: %s)", file, GetErrorStr()); result = false; } break; } if (edits.joinlines && *(line + strlen(line) - 1) == '\\') { *(line + strlen(line) - 1) = '\0'; BufferAppend(concat, line, num_read); } else { BufferAppend(concat, line, num_read); if (!feof(fp) || (BufferSize(concat) > 0)) { AppendItem(liststart, BufferData(concat), NULL); } } BufferZero(concat); } free(line); BufferDestroy(concat); fclose(fp); return result; }
bool ExpandScalar(const EvalContext *ctx, const char *ns, const char *scope, const char *string, Buffer *out) { assert(string); bool returnval = true; if (strlen(string) == 0) { return false; } // TODO: cleanup, optimize this mess Buffer *var = BufferNew(); Buffer *current_item = BufferNew(); Buffer *temp = BufferNew(); for (const char *sp = string; /* No exit */ ; sp++) /* check for varitems */ { char varstring = false; size_t increment = 0; if (*sp == '\0') { break; } BufferZero(current_item); ExtractScalarPrefix(current_item, sp, strlen(sp)); BufferAppend(out, BufferData(current_item), BufferSize(current_item)); sp += BufferSize(current_item); if (*sp == '\0') { break; } BufferZero(var); if (*sp == '$') { switch (*(sp + 1)) { case '(': varstring = ')'; ExtractScalarReference(var, sp, strlen(sp), false); if (BufferSize(var) == 0) { BufferAppendChar(out, '$'); continue; } break; case '{': varstring = '}'; ExtractScalarReference(var, sp, strlen(sp), false); if (BufferSize(var) == 0) { BufferAppendChar(out, '$'); continue; } break; default: BufferAppendChar(out, '$'); continue; } } BufferZero(current_item); { BufferZero(temp); ExtractScalarReference(temp, sp, strlen(sp), true); if (IsCf3VarString(BufferData(temp))) { ExpandScalar(ctx, ns, scope, BufferData(temp), current_item); } else { BufferAppend(current_item, BufferData(temp), BufferSize(temp)); } } increment = BufferSize(var) - 1; char name[CF_MAXVARSIZE] = ""; if (!IsExpandable(BufferData(current_item))) { DataType type = DATA_TYPE_NONE; const void *value = NULL; { VarRef *ref = VarRefParseFromNamespaceAndScope(BufferData(current_item), ns, scope, CF_NS, '.'); value = EvalContextVariableGet(ctx, ref, &type); VarRefDestroy(ref); } if (value) { switch (type) { case DATA_TYPE_STRING: case DATA_TYPE_INT: case DATA_TYPE_REAL: BufferAppend(out, value, strlen(value)); break; case DATA_TYPE_STRING_LIST: case DATA_TYPE_INT_LIST: case DATA_TYPE_REAL_LIST: case DATA_TYPE_NONE: if (varstring == '}') { snprintf(name, CF_MAXVARSIZE, "${%s}", BufferData(current_item)); } else { snprintf(name, CF_MAXVARSIZE, "$(%s)", BufferData(current_item)); } BufferAppend(out, name, strlen(name)); returnval = false; break; default: Log(LOG_LEVEL_DEBUG, "Returning Unknown Scalar ('%s' => '%s')", string, BufferData(out)); BufferDestroy(var); BufferDestroy(current_item); BufferDestroy(temp); return false; } } else { if (varstring == '}') { snprintf(name, CF_MAXVARSIZE, "${%s}", BufferData(current_item)); } else { snprintf(name, CF_MAXVARSIZE, "$(%s)", BufferData(current_item)); } BufferAppend(out, name, strlen(name)); returnval = false; } } sp += increment; BufferZero(current_item); } BufferDestroy(var); BufferDestroy(current_item); BufferDestroy(temp); return returnval; }
DataType StringDataType(EvalContext *ctx, const char *string) { int islist = false; DataType dtype = CF_DATA_TYPE_NONE; /*------------------------------------------------------- What happens if we embed vars in a literal string "$(list)withending" - a list? "$(list1)$(list2)" - not a simple list Disallow these manual concatenations as ambiguous. Demand this syntax to work around vars: "listvar" slist => EmbellishList("prefix$(list)suffix"); ---------------------------------------------------------*/ size_t len = strlen(string); if (*string == '$') { Buffer *inner_value = BufferNew(); if (ExtractScalarReference(inner_value, string, len, true)) { if (!IsExpandable(BufferData(inner_value))) { VarRef *ref = VarRefParse(BufferData(inner_value)); if (EvalContextVariableGet(ctx, ref, &dtype)) { if (DataTypeToRvalType(dtype) == RVAL_TYPE_LIST) { if (!islist) { islist = true; } else { islist = false; } } } VarRefDestroy(ref); } if (BufferSize(inner_value) == strlen(string)) { BufferDestroy(inner_value); return dtype; } else { BufferDestroy(inner_value); return CF_DATA_TYPE_STRING; } } BufferDestroy(inner_value); } return CF_DATA_TYPE_STRING; }
static void test_appendBuffer(void) { char *element0 = xstrdup("element0"); unsigned int element0size = strlen(element0); const char *element0pointer = NULL; char *element1 = xstrdup("element1"); unsigned int element1size = strlen(element1); const char *element1pointer = NULL; char *element2 = (char *)xmalloc(2 * DEFAULT_BUFFER_SIZE + 2); unsigned int element2size = 2 * DEFAULT_BUFFER_SIZE + 1; char *element3 = (char *)xmalloc(DEFAULT_MEMORY_CAP * 2); unsigned int element3size = 2 * DEFAULT_MEMORY_CAP; Buffer *buffer = BufferNew(); assert_true(buffer != NULL); // Initialize the buffer with a small string assert_int_equal(element0size, BufferAppend(buffer, element0, element0size)); element0pointer = buffer->buffer; assert_int_equal(element0size, buffer->used); assert_int_equal(element0size, BufferSize(buffer)); assert_string_equal(element0, buffer->buffer); assert_string_equal(element0, BufferData(buffer)); assert_int_equal(DEFAULT_BUFFER_SIZE, buffer->capacity); // Attach a small string to it assert_int_equal(element0size + element1size, BufferAppend(buffer, element1, element1size)); element1pointer = buffer->buffer; assert_true(element0pointer == element1pointer); assert_int_equal(buffer->used, element0size + element1size); assert_int_equal(BufferSize(buffer), element0size + element1size); char *shortAppend = NULL; shortAppend = (char *)xmalloc(element0size + element1size + 1); strcpy(shortAppend, element0); strcat(shortAppend, element1); assert_string_equal(shortAppend, buffer->buffer); assert_string_equal(shortAppend, BufferData(buffer)); /* * Zero the string and start again. */ BufferZero(buffer); assert_int_equal(element0size, BufferAppend(buffer, element0, element0size)); element0pointer = buffer->buffer; assert_int_equal(element0size, buffer->used); assert_int_equal(element0size, BufferSize(buffer)); assert_string_equal(element0, buffer->buffer); assert_string_equal(element0, BufferData(buffer)); /* * Larger than the allocated buffer, this means we will allocate more memory * copy stuff into the new buffer and all that. */ int i = 0; for (i = 0; i < element2size; ++i) element2[i] = 'a'; element2[element2size] = '\0'; assert_int_equal(element0size + element2size, BufferAppend(buffer, element2, element2size)); assert_int_equal(buffer->used, element0size + element2size); assert_int_equal(BufferSize(buffer), element0size + element2size); char *longAppend = NULL; longAppend = (char *)xmalloc(element0size + element2size + 1); strcpy(longAppend, element0); strcat(longAppend, element2); assert_string_equal(longAppend, buffer->buffer); assert_string_equal(longAppend, BufferData(buffer)); /* * A buffer that is so large that it will get rejected by our memory cap */ BufferZero(buffer); for (i = 0; i < element3size; ++i) { element3[i] = 'b'; } element3[element3size - 1] = '\0'; assert_int_equal(-1, BufferAppend(buffer, element3, element3size)); /* * Boundary checks, BUFFER_SIZE-1, BUFFER_SIZE and BUFFER_SIZE+1 */ Buffer *bm1 = BufferNew(); Buffer *be = BufferNew(); Buffer *bp1 = BufferNew(); char buffer_m1[DEFAULT_BUFFER_SIZE - 1]; char buffer_0[DEFAULT_BUFFER_SIZE]; char buffer_p1[DEFAULT_BUFFER_SIZE + 1]; unsigned int bm1_size = DEFAULT_BUFFER_SIZE - 1; unsigned int be_size = DEFAULT_BUFFER_SIZE; unsigned int bp1_size = DEFAULT_BUFFER_SIZE + 1; for (i = 0; i < DEFAULT_BUFFER_SIZE - 1; ++i) { buffer_m1[i] = 'c'; buffer_0[i] = 'd'; buffer_p1[i] = 'e'; } /* * One shorter, that means the buffer remains the same size as before. */ buffer_m1[DEFAULT_BUFFER_SIZE - 2] = '\0'; assert_int_equal(bm1_size, BufferAppend(bm1, buffer_m1, bm1_size)); assert_int_equal(bm1->capacity, DEFAULT_BUFFER_SIZE); /* * Same size, it should allocate one more block */ buffer_0[DEFAULT_BUFFER_SIZE - 1] = '\0'; assert_int_equal(be_size, BufferAppend(be, buffer_0, be_size)); assert_int_equal(be->capacity, 2 * DEFAULT_BUFFER_SIZE); /* * 1 more, it should allocate one more block */ buffer_p1[DEFAULT_BUFFER_SIZE] = '\0'; assert_int_equal(bp1_size, BufferAppend(bp1, buffer_p1, bp1_size)); assert_int_equal(bp1->capacity, 2 * DEFAULT_BUFFER_SIZE); /* * Destroy the buffer and good night. */ free(shortAppend); free(longAppend); assert_int_equal(0, BufferDestroy(&buffer)); assert_int_equal(0, BufferDestroy(&bm1)); assert_int_equal(0, BufferDestroy(&be)); assert_int_equal(0, BufferDestroy(&bp1)); free (element0); free (element1); free (element2); free (element3); }
static void test_vprintf(void) { char *char0 = xstrdup("char0"); unsigned int char0size = strlen(char0); const char *char0pointer = NULL; char *char1 = xstrdup("char1"); unsigned int char1size = strlen(char1); const char *char1pointer = NULL; char *char2 = (char *)xmalloc(2 * DEFAULT_BUFFER_SIZE + 2); unsigned int char2size = 2 * DEFAULT_BUFFER_SIZE + 1; int int0 = 123456789; char *int0char = xstrdup("123456789"); unsigned int int0charsize = strlen(int0char); double double0 = 3.1415; char *double0char = xstrdup("3.1415"); unsigned int double0charsize = strlen(double0char); char *char0int0char1double0 = xstrdup("char0 123456789 char1 3.1415"); unsigned int char0int0char1double0size = strlen(char0int0char1double0); char *element3 = (char *)xmalloc(DEFAULT_MEMORY_CAP * 2); unsigned int element3size = 2 * DEFAULT_MEMORY_CAP; Buffer *buffer = BufferNew(); assert_true(buffer != NULL); /* * Print the first char and compare the result */ assert_int_equal(char0size, test_vprintf_helper(buffer, "%s", char0)); char0pointer = buffer->buffer; assert_string_equal(char0, buffer->buffer); assert_string_equal(char0, BufferData(buffer)); assert_int_equal(char0size, buffer->used); assert_int_equal(char0size, BufferSize(buffer)); /* * Overwrite the first char with the second one */ assert_int_equal(char1size, test_vprintf_helper(buffer, "%s", char1)); char1pointer = buffer->buffer; assert_string_equal(char1, buffer->buffer); assert_string_equal(char1, BufferData(buffer)); assert_int_equal(char1size, buffer->used); assert_int_equal(char1size, BufferSize(buffer)); assert_true(char0pointer == char1pointer); /* * Try the int now */ assert_int_equal(int0charsize, test_vprintf_helper(buffer, "%d", int0)); assert_string_equal(int0char, buffer->buffer); assert_string_equal(int0char, BufferData(buffer)); assert_int_equal(int0charsize, buffer->used); assert_int_equal(int0charsize, BufferSize(buffer)); /* * Try the double now */ assert_int_equal(double0charsize, test_vprintf_helper(buffer, "%.4f", double0)); assert_string_equal(double0char, buffer->buffer); assert_string_equal(double0char, BufferData(buffer)); assert_int_equal(double0charsize, buffer->used); assert_int_equal(double0charsize, BufferSize(buffer)); /* * Try the combination now */ assert_int_equal(char0int0char1double0size, test_vprintf_helper(buffer, "%s %d %s %.4f", char0, int0, char1, double0)); assert_string_equal(char0int0char1double0, buffer->buffer); assert_string_equal(char0int0char1double0, BufferData(buffer)); assert_int_equal(char0int0char1double0size, buffer->used); assert_int_equal(char0int0char1double0size, BufferSize(buffer)); /* * Finally, try something larger than the default buffer and see if we get the right return value. */ unsigned int i = 0; for (i = 0; i < char2size; ++i) char2[i] = 'a'; char2[char2size] = '\0'; // The buffer should resize itself assert_int_equal(char2size, test_vprintf_helper(buffer, "%s", char2)); assert_string_equal(char2, buffer->buffer); assert_string_equal(char2, BufferData(buffer)); assert_int_equal(char2size, buffer->used); assert_int_equal(char2size, BufferSize(buffer)); /* * A buffer that is so large that it will get rejected by our memory cap */ BufferZero(buffer); for (i = 0; i < element3size; ++i) { element3[i] = 'b'; } element3[element3size - 1] = '\0'; assert_int_equal(-1, test_vprintf_helper(buffer, "%s", element3)); /* * Boundary checks, BUFFER_SIZE-1, BUFFER_SIZE and BUFFER_SIZE+1 */ Buffer *bm1 = BufferNew(); Buffer *be = BufferNew(); Buffer *bp1 = BufferNew(); /* * The sizes are different for printf. If we have a size of X, then the string * is of length X-1, and so forth. */ char buffer_m1[DEFAULT_BUFFER_SIZE]; char buffer_0[DEFAULT_BUFFER_SIZE + 1]; char buffer_p1[DEFAULT_BUFFER_SIZE + 2]; unsigned int bm1_size = DEFAULT_BUFFER_SIZE - 1; unsigned int be_size = DEFAULT_BUFFER_SIZE; unsigned int bp1_size = DEFAULT_BUFFER_SIZE + 1; /* * Make sure the buffers are filled with 0. */ memset(buffer_m1, '\0', DEFAULT_BUFFER_SIZE); memset(buffer_0, '\0', DEFAULT_BUFFER_SIZE + 1); memset(buffer_p1, '\0', DEFAULT_BUFFER_SIZE + 2); /* * Write something to the buffers */ memset(buffer_m1, 'c', DEFAULT_BUFFER_SIZE); memset(buffer_0, 'd', DEFAULT_BUFFER_SIZE + 1); memset(buffer_p1, 'e', DEFAULT_BUFFER_SIZE + 2); /* * One shorter, that means the buffer remains the same size as before. */ buffer_m1[DEFAULT_BUFFER_SIZE - 1] = '\0'; assert_int_equal(bm1_size, test_vprintf_helper(bm1, "%s", buffer_m1)); assert_string_equal(buffer_m1, bm1->buffer); assert_int_equal(bm1->capacity, DEFAULT_BUFFER_SIZE); /* * Same size, it should allocate one more block. * This means retrying the operation. */ buffer_0[DEFAULT_BUFFER_SIZE] = '\0'; assert_int_equal(be_size, test_vprintf_helper(be, "%s", buffer_0)); assert_string_equal(buffer_0, be->buffer); assert_int_equal(be->capacity, 2 * DEFAULT_BUFFER_SIZE); /* * 1 more, it should allocate one more block * This means retrying the operation. */ buffer_p1[DEFAULT_BUFFER_SIZE + 1] = '\0'; assert_int_equal(bp1_size, test_vprintf_helper(bp1, "%s", buffer_p1)); assert_string_equal(buffer_p1, bp1->buffer); assert_int_equal(bp1->capacity, 2 * DEFAULT_BUFFER_SIZE); /* * Release the resources */ BufferDestroy(&buffer); BufferDestroy(&bm1); BufferDestroy(&be); BufferDestroy(&bp1); free (char0); free (char1); free (char2); free (int0char); free (double0char); free (char0int0char1double0); free (element3); }
static void test_setBuffer(void) { char *element0 = xstrdup("element0"); unsigned int element0size = strlen(element0); char *element1 = (char *)xmalloc(2 * DEFAULT_BUFFER_SIZE + 2); unsigned int element1size = 2 * DEFAULT_BUFFER_SIZE + 1; char *element2 = (char *)xmalloc(DEFAULT_MEMORY_CAP * 2); unsigned int element2size = 2 * DEFAULT_MEMORY_CAP; Buffer *buffer = BufferNew(); assert_true(buffer != NULL); // Smaller than the allocated buffer assert_int_equal(element0size, BufferSet(buffer, element0, element0size)); assert_int_equal(element0size, buffer->used); assert_int_equal(element0size, BufferSize(buffer)); assert_string_equal(element0, buffer->buffer); assert_string_equal(element0, BufferData(buffer)); assert_int_equal(DEFAULT_BUFFER_SIZE, buffer->capacity); // Larger than the allocated buffer int i = 0; for (i = 0; i < element1size; ++i) element1[i] = 'a'; element1[element1size] = '\0'; assert_int_equal(element1size, BufferSet(buffer, element1, element1size)); assert_int_equal(element1size, buffer->used); assert_string_equal(element1, buffer->buffer); assert_string_equal(element1, BufferData(buffer)); assert_int_equal(DEFAULT_BUFFER_SIZE * 3, buffer->capacity); /* * A buffer that is so large that it will get rejected by our memory cap */ BufferZero(buffer); for (i = 0; i < element2size; ++i) { element2[i] = 'b'; } element2[element2size - 1] = '\0'; assert_int_equal(-1, BufferSet(buffer, element2, element2size)); /* * Boundary checks, BUFFER_SIZE-1, BUFFER_SIZE and BUFFER_SIZE+1 */ Buffer *bm1 = BufferNew(); Buffer *be = BufferNew(); Buffer *bp1 = BufferNew(); char buffer_m1[DEFAULT_BUFFER_SIZE - 1]; char buffer_0[DEFAULT_BUFFER_SIZE]; char buffer_p1[DEFAULT_BUFFER_SIZE + 1]; unsigned int bm1_size = DEFAULT_BUFFER_SIZE - 1; unsigned int be_size = DEFAULT_BUFFER_SIZE; unsigned int bp1_size = DEFAULT_BUFFER_SIZE + 1; for (i = 0; i < DEFAULT_BUFFER_SIZE - 1; ++i) { buffer_m1[i] = 'c'; buffer_0[i] = 'd'; buffer_p1[i] = 'e'; } /* * One shorter, that means the buffer remains the same size as before. */ buffer_m1[DEFAULT_BUFFER_SIZE - 2] = '\0'; assert_int_equal(bm1_size, BufferSet(bm1, buffer_m1, bm1_size)); assert_int_equal(bm1->capacity, DEFAULT_BUFFER_SIZE); /* * Same size, it should allocate one more block */ buffer_0[DEFAULT_BUFFER_SIZE - 1] = '\0'; assert_int_equal(be_size, BufferSet(be, buffer_0, be_size)); assert_int_equal(be->capacity, 2 * DEFAULT_BUFFER_SIZE); /* * 1 more, it should allocate one more block */ buffer_p1[DEFAULT_BUFFER_SIZE] = '\0'; assert_int_equal(bp1_size, BufferSet(bp1, buffer_p1, bp1_size)); assert_int_equal(bp1->capacity, 2 * DEFAULT_BUFFER_SIZE); // Negative cases assert_int_equal(-1, BufferSet(NULL, element0, element0size)); assert_int_equal(-1, BufferSet(NULL, NULL, element0size)); assert_int_equal(-1, BufferSet(buffer, NULL, element0size)); assert_int_equal(0, BufferSet(buffer, element0, 0)); /* * Destroy the buffer and good night. */ assert_int_equal(0, BufferDestroy(&buffer)); assert_true(buffer == NULL); BufferDestroy(&bm1); BufferDestroy(&be); BufferDestroy(&bp1); free (element0); free (element1); free (element2); }