bool Component::isNumberWithMarker(uint8_t marker) const { return (!empty() && value()[0] == marker && (value_size() == 2 || value_size() == 3 || value_size() == 5 || value_size() == 9)); }
Block::Block(uint32_t type, const Block& value) : m_buffer(value.m_buffer) , m_type(type) , m_begin(m_buffer->end()) , m_end(m_buffer->end()) , m_value_begin(value.begin()) , m_value_end(value.end()) { m_size = Tlv::sizeOfVarNumber(m_type) + Tlv::sizeOfVarNumber(value_size()) + value_size(); }
size_t Component::wireEncode(EncodingImpl<TAG>& encoder) const { size_t totalLength = 0; if (value_size() > 0) totalLength += encoder.prependByteArray(value(), value_size()); totalLength += encoder.prependVarNumber(value_size()); totalLength += encoder.prependVarNumber(type()); return totalLength; }
void Block::encode() { if (hasWire()) return; OBufferStream os; Tlv::writeVarNumber(os, type()); if (hasValue()) { Tlv::writeVarNumber(os, value_size()); os.write(reinterpret_cast<const char*>(value()), value_size()); } else if (m_subBlocks.size() == 0) { Tlv::writeVarNumber(os, 0); } else { size_t valueSize = 0; for (element_const_iterator i = m_subBlocks.begin(); i != m_subBlocks.end(); ++i) { valueSize += i->size(); } Tlv::writeVarNumber(os, valueSize); for (element_const_iterator i = m_subBlocks.begin(); i != m_subBlocks.end(); ++i) { if (i->hasWire()) os.write(reinterpret_cast<const char*>(i->wire()), i->size()); else if (i->hasValue()) { Tlv::writeVarNumber(os, i->type()); Tlv::writeVarNumber(os, i->value_size()); os.write(reinterpret_cast<const char*>(i->value()), i->value_size()); } else throw Error("Underlying value buffer is empty"); } } // now assign correct block m_buffer = os.buf(); m_begin = m_buffer->begin(); m_end = m_buffer->end(); m_size = m_end - m_begin; m_value_begin = m_buffer->begin(); m_value_end = m_buffer->end(); Tlv::readType(m_value_begin, m_value_end); Tlv::readVarNumber(m_value_begin, m_value_end); }
void Block::parse() const { if (!m_subBlocks.empty() || value_size() == 0) return; Buffer::const_iterator begin = value_begin(); Buffer::const_iterator end = value_end(); while (begin != end) { Buffer::const_iterator element_begin = begin; uint32_t type = Tlv::readType(begin, end); uint64_t length = Tlv::readVarNumber(begin, end); if (length > static_cast<uint64_t>(end - begin)) { m_subBlocks.clear(); throw Tlv::Error("TLV length exceeds buffer length"); } Buffer::const_iterator element_end = begin + length; m_subBlocks.push_back(Block(m_buffer, type, element_begin, element_end, begin, element_end)); begin = element_end; // don't do recursive parsing, just the top level } }
int value_reify(struct value *val, struct value_dict *arguments) { if (val->where != VAL_LOC_INFERIOR) return 0; assert(val->inferior != NULL); size_t size = value_size(val, arguments); if (size == (size_t)-1) return -1; void *data; enum value_location_t nloc; if (size <= sizeof(val->u.value)) { data = &val->u.value; nloc = VAL_LOC_WORD; } else { data = malloc(size); if (data == NULL) return -1; nloc = VAL_LOC_COPY; } if (umovebytes(val->inferior, val->u.inf_address, data, size) < size) { if (nloc == VAL_LOC_COPY) free(data); return -1; } val->where = nloc; if (nloc == VAL_LOC_COPY) val->u.address = data; return 0; }
bool Component::equals(const Component& other) const { return type() == other.type() && value_size() == other.value_size() && (empty() || // needed with Apple clang < 9.0.0 due to libc++ bug std::equal(value_begin(), value_end(), other.value_begin())); }
bool Interest::decode02() { auto element = m_wire.elements_begin(); // Name if (element != m_wire.elements_end() && element->type() == tlv::Name) { m_name.wireDecode(*element); ++element; } else { return false; } // Selectors? if (element != m_wire.elements_end() && element->type() == tlv::Selectors) { m_selectors.wireDecode(*element); ++element; } else { m_selectors = {}; } // Nonce if (element != m_wire.elements_end() && element->type() == tlv::Nonce) { uint32_t nonce = 0; if (element->value_size() != sizeof(nonce)) { NDN_THROW(Error("Nonce element is malformed")); } std::memcpy(&nonce, element->value(), sizeof(nonce)); m_nonce = nonce; ++element; } else { return false; } // InterestLifetime? if (element != m_wire.elements_end() && element->type() == tlv::InterestLifetime) { m_interestLifetime = time::milliseconds(readNonNegativeInteger(*element)); ++element; } else { m_interestLifetime = DEFAULT_INTEREST_LIFETIME; } // ForwardingHint? if (element != m_wire.elements_end() && element->type() == tlv::ForwardingHint) { m_forwardingHint.wireDecode(*element, false); ++element; } else { m_forwardingHint = {}; } return element == m_wire.elements_end(); }
uint64_t Component::toNumberWithMarker(uint8_t marker) const { if (!isNumberWithMarker(marker)) NDN_THROW(Error("Name component does not have the requested marker " "or the value is not a nonNegativeInteger")); Buffer::const_iterator valueBegin = value_begin() + 1; return tlv::readNonNegativeInteger(value_size() - 1, valueBegin, value_end()); }
int Component::compare(const Component& other) const { if (this->hasWire() && other.hasWire()) { // In the common case where both components have wire encoding, // it's more efficient to simply compare the wire encoding. // This works because lexical order of TLV encoding happens to be // the same as canonical order of the value. return std::memcmp(wire(), other.wire(), std::min(size(), other.size())); } int cmpType = type() - other.type(); if (cmpType != 0) return cmpType; int cmpSize = value_size() - other.value_size(); if (cmpSize != 0) return cmpSize; if (empty()) return 0; return std::memcmp(value(), other.value(), value_size()); }
size_t valuearray_size(Slapi_Value **va) { size_t s= 0; if(va!=NULL && va[0]!=NULL) { int i; for (i = 0; va[i]; i++) { s += value_size(va[i]); } s += (i + 1) * sizeof(Slapi_Value*); } return s; }
/* See pxoper.h for details. */ static int px_save_array(px_value_t * pv, px_state_t * pxs, client_name_t cname, uint nbytes) { if (pv->type & pxd_on_heap) { /* Turn off the "on heap" bit, to prevent freeing. */ pv->type &= ~pxd_on_heap; } else { /* Allocate a heap copy. Only the first nbytes bytes */ /* of the data are valid. */ uint num_elements = pv->value.array.size; uint elt_size = value_size(pv); byte *copy = gs_alloc_byte_array(pxs->memory, num_elements, elt_size, cname); if (copy == 0) return_error(errorInsufficientMemory); memcpy(copy, pv->value.array.data, nbytes); pv->value.array.data = copy; } return 0; }
Block Block::blockFromValue() const { if (value_size() == 0) throw Error("Underlying value buffer is empty"); Buffer::const_iterator begin = value_begin(), end = value_end(); Buffer::const_iterator element_begin = begin; uint32_t type = Tlv::readType(begin, end); uint64_t length = Tlv::readVarNumber(begin, end); if (length != static_cast<uint64_t>(end - begin)) throw Tlv::Error("TLV length mismatches buffer length"); return Block(m_buffer, type, element_begin, end, begin, end); }
bool ProtoMessage::from(const std::string& data) { if (m_protoMsg == nullptr || !m_protoMsg->ParseFromString(data)) { return false; } clearMap(); clearList(); clearTable(); int32_t index = -1; while (index++ != m_protoMsg->keymapdata_size() - 1) { auto protokeyMapData = m_protoMsg->mutable_keymapdata(index); const int32_t& key = protokeyMapData->key(); auto mapData = protokeyMapData->mutable_mapdata(); int32_t dataIndex = -1; while (dataIndex++ != mapData->mapkeyvalue_size() - 1) { auto mapKeyValue = mapData->mutable_mapkeyvalue(dataIndex); const int32_t& dataKey = mapKeyValue->key(); auto variantValue = mapKeyValue->mutable_value(); m_keyMapData[key][dataKey] = Variant(variantValue->data(), (Variant::VariantType)(variantValue->type()), true); } } index = -1; while (index++ != m_protoMsg->keylistdata_size() - 1) { auto protokeyListData = m_protoMsg->mutable_keylistdata(index); const int32_t& key = protokeyListData->key(); auto listData = protokeyListData->mutable_listdata(); int32_t dataIndex = -1; while (dataIndex++ != listData->value_size() - 1) { auto variantValue = listData->mutable_value(dataIndex); m_keyListData[key].push_back(Variant(variantValue->data(), (Variant::VariantType)(variantValue->type()), true)); } } index = -1; while (index++ != m_protoMsg->keytabledata_size() - 1) { auto protokeyTableData = m_protoMsg->mutable_keytabledata(index); const int32_t& key = protokeyTableData->key(); auto tableData = protokeyTableData->mutable_tabledata(); std::vector<std::vector<Variant>> vecData; int32_t lineIndex = -1; while (lineIndex++ != tableData->listdata_size() - 1) { std::vector<Variant> vecLine; auto list = tableData->mutable_listdata(lineIndex); int32_t dataIndex = -1; while (dataIndex++ != list->value_size() - 1) { auto variantValue = list->mutable_value(dataIndex); vecLine.push_back(Variant(variantValue->data(), (Variant::VariantType)(variantValue->type()), true)); } vecData.push_back(vecLine); } m_keyTableData[key] = vecData; } return true; }
void Interest::decode03() { // Interest ::= INTEREST-TYPE TLV-LENGTH // Name // CanBePrefix? // MustBeFresh? // ForwardingHint? // Nonce? // InterestLifetime? // HopLimit? // ApplicationParameters? auto element = m_wire.elements_begin(); if (element == m_wire.elements_end() || element->type() != tlv::Name) { NDN_THROW(Error("Name element is missing or out of order")); } m_name.wireDecode(*element); if (m_name.empty()) { NDN_THROW(Error("Name has zero name components")); } int lastElement = 1; // last recognized element index, in spec order m_selectors = Selectors().setMaxSuffixComponents(1); // CanBePrefix=0 m_nonce.reset(); m_interestLifetime = DEFAULT_INTEREST_LIFETIME; m_forwardingHint = {}; m_parameters = {}; for (++element; element != m_wire.elements_end(); ++element) { switch (element->type()) { case tlv::CanBePrefix: { if (lastElement >= 2) { NDN_THROW(Error("CanBePrefix element is out of order")); } if (element->value_size() != 0) { NDN_THROW(Error("CanBePrefix element has non-zero TLV-LENGTH")); } m_selectors.setMaxSuffixComponents(-1); lastElement = 2; break; } case tlv::MustBeFresh: { if (lastElement >= 3) { NDN_THROW(Error("MustBeFresh element is out of order")); } if (element->value_size() != 0) { NDN_THROW(Error("MustBeFresh element has non-zero TLV-LENGTH")); } m_selectors.setMustBeFresh(true); lastElement = 3; break; } case tlv::ForwardingHint: { if (lastElement >= 4) { NDN_THROW(Error("ForwardingHint element is out of order")); } m_forwardingHint.wireDecode(*element); lastElement = 4; break; } case tlv::Nonce: { if (lastElement >= 5) { NDN_THROW(Error("Nonce element is out of order")); } uint32_t nonce = 0; if (element->value_size() != sizeof(nonce)) { NDN_THROW(Error("Nonce element is malformed")); } std::memcpy(&nonce, element->value(), sizeof(nonce)); m_nonce = nonce; lastElement = 5; break; } case tlv::InterestLifetime: { if (lastElement >= 6) { NDN_THROW(Error("InterestLifetime element is out of order")); } m_interestLifetime = time::milliseconds(readNonNegativeInteger(*element)); lastElement = 6; break; } case tlv::HopLimit: { if (lastElement >= 7) { break; // HopLimit is non-critical, ignore out-of-order appearance } if (element->value_size() != 1) { NDN_THROW(Error("HopLimit element is malformed")); } // TLV-VALUE is ignored lastElement = 7; break; } case tlv::ApplicationParameters: { if (lastElement >= 8) { break; // ApplicationParameters is non-critical, ignore out-of-order appearance } m_parameters = *element; lastElement = 8; break; } default: { if (tlv::isCriticalType(element->type())) { NDN_THROW(Error("Unrecognized element of critical type " + to_string(element->type()))); } break; } } } }
bool Component::isNumber() const { return (value_size() == 1 || value_size() == 2 || value_size() == 4 || value_size() == 8); }
cstring_span footer(void) const noexcept { return {data()+header_size()+value_size(), header_size()}; }
cstring_span value(void) const noexcept { return {value_data(), value_size()}; }
int main(int argc, char * argv[]){ dataBase *db; createDB(&db, "myDB"); int temp = 0; while(temp != -1){ char line[50]; char data[100]; char *key = (char*)inderectMalloc((size_t)(sizeof(char)*50)); char *stringData; size_t size; printf("0 to Add key and data, 1 to get data, 2 to remove data, 3 for size, 4 for save, 5 for load, -1 for quit\n"); if(fgets(line, sizeof(line), stdin)) { if(1 == sscanf(line, "%d", &temp)){ switch(temp){ case 0: printf("Enter key\n"); fgets(line, sizeof(line), stdin); sscanf(line, "%s", key); printf("Enter data\n"); fgets(data, sizeof(data), stdin); put(db, key, data, sizeof(data)); break; case 1: printf("Enter key\n"); fgets(line, sizeof(line), stdin); sscanf(line, "%s", key); get(db, key, (void**)&stringData); printf("Data is: %s \n", stringData); break; case 2: printf("Enter key\n"); fgets(line, sizeof(line), stdin); sscanf(line, "%s", key); delete(db, key); break; case 3: printf("Enter key\n"); fgets(line, sizeof(line), stdin); sscanf(line, "%s", key); size = value_size(db, key); printf("Size is: %d\n", (int)size); break; case 4: printf("Enter path\n"); fgets(line, sizeof(line), stdin); sscanf(line, "%s", key); if(-1 == saveHT(db, key)) printf("Failed saved\n"); break; case 5: printf("Enter path\n"); fgets(line, sizeof(line), stdin); sscanf(line, "%s", key); if(-1 == loadHT(db, key)) printf("Failed load\n"); break; } } } } }
/* Process a buffer of PCL XL commands. */ int px_process(px_parser_state_t * st, px_state_t * pxs, stream_cursor_read * pr) { const byte *orig_p = pr->ptr; const byte *next_p = orig_p; /* start of data not copied to saved */ const byte *p; const byte *rlimit; px_value_t *sp = &st->stack[st->stack_count]; #define stack_limit &st->stack[max_stack - 1] gs_memory_t *memory = st->memory; int code = 0; uint left; uint min_left; px_tag_t tag; const px_tag_syntax_t *syntax = 0; st->args.parser = st; st->parent_operator_count = 0; /* in case of error */ /* Check for leftover data from the previous call. */ parse:if (st->saved_count) { /* Fill up the saved buffer so we can make progress. */ int move = min(sizeof(st->saved) - st->saved_count, pr->limit - next_p); memcpy(&st->saved[st->saved_count], next_p + 1, move); next_p += move; p = st->saved - 1; rlimit = p + st->saved_count + move; } else { /* No leftover data, just read from the input. */ p = next_p; rlimit = pr->limit; } top:if (st->data_left) { /* We're in the middle of reading an array or data block. */ if (st->data_proc) { /* This is a data block. */ uint avail = min(rlimit - p, st->data_left); uint used; st->args.source.available = avail; st->args.source.data = p + 1; code = (*st->data_proc) (&st->args, pxs); /* If we get a 'remap_color' error, it means we are dealing with a * pattern, and the device supports high level patterns. So we must * use our high level pattern implementation. */ if (code == gs_error_Remap_Color) { code = px_high_level_pattern(pxs->pgs); code = (*st->data_proc) (&st->args, pxs); } used = st->args.source.data - (p + 1); #ifdef DEBUG if (gs_debug_c('I')) { px_value_t data_array; data_array.type = pxd_ubyte; data_array.value.array.data = p + 1; data_array.value.array.size = used; trace_array_data(pxs->memory, "data:", &data_array); } #endif p = st->args.source.data - 1; st->data_left -= used; if (code < 0) { st->args.source.position = 0; goto x; } else if ((code == pxNeedData) || (code == pxPassThrough && st->data_left != 0)) { code = 0; /* exit for more data */ goto x; } else { st->args.source.position = 0; st->data_proc = 0; if (st->data_left != 0) { code = gs_note_error(errorExtraData); goto x; } clear_stack(); } } else { /* This is an array. */ uint size = sp->value.array.size; uint scale = value_size(sp); uint nbytes = size * scale; byte *dest = (byte *) sp->value.array.data + nbytes - st->data_left; left = rlimit - p; if (left < st->data_left) { /* We still don't have enough data to fill the array. */ memcpy(dest, p + 1, left); st->data_left -= left; p = rlimit; code = 0; goto x; } /* Complete the array and continue parsing. */ memcpy(dest, p + 1, st->data_left); trace_array(memory, sp); p += st->data_left; } st->data_left = 0; } else if (st->data_proc) { /* An operator is awaiting data. */ /* Skip white space until we find some. */ code = 0; /* in case we exit */ /* special case - VendorUnique has a length attribute which we've already parsed and error checked */ if (st->data_proc == pxVendorUnique) { st->data_left = st->stack[st->attribute_indices[pxaVUDataLength]].value.i; goto top; } else { while ((left = rlimit - p) != 0) { switch ((tag = p[1])) { case pxtNull: case pxtHT: case pxtLF: case pxtVT: case pxtFF: case pxtCR: ++p; continue; case pxt_dataLength: if (left < 5) goto x; /* can't look ahead */ st->data_left = get_uint32(st, p + 2); if_debug2m('i', memory, "tag= 0x%2x data, length %u\n", p[1], st->data_left); p += 5; goto top; case pxt_dataLengthByte: if (left < 2) goto x; /* can't look ahead */ st->data_left = p[2]; if_debug2m('i', memory, "tag= 0x%2x data, length %u\n", p[1], st->data_left); p += 2; goto top; default: { code = gs_note_error(errorMissingData); goto x; } } } } } st->args.source.position = 0; st->args.source.available = 0; while ((left = rlimit - p) != 0 && left >= (min_left = (syntax = &tag_syntax[tag = p[1]])->min_input) ) { int count; #ifdef DEBUG if (gs_debug_c('i')) { dmprintf1(memory, "tag= 0x%02x ", tag); if (tag == pxt_attr_ubyte || tag == pxt_attr_uint16) { px_attribute_t attr = (tag == pxt_attr_ubyte ? p[2] : get_uint16(st, p + 2)); const char *aname = px_attribute_names[attr]; if (aname) dmprintf1(memory, " @%s\n", aname); else dmprintf1(memory, " attribute %u ???\n", attr); } else { const char *format; const char *tname; bool operator = false; if (tag < 0x40) format = "%s\n", tname = px_tag_0_names[tag]; else if (tag < 0xc0) format = "%s", tname = px_operator_names[tag - 0x40], operator = true; else { tname = px_tag_c0_names[tag - 0xc0]; if (tag < 0xf0) format = " %s"; /* data values follow */ else format = "%s\n"; } if (tname) { dmprintf1(memory, format, tname); if (operator) dmprintf1(memory, " (%ld)\n", st->operator_count + 1); } else dmputs(memory, "???\n"); } } #endif if ((st->macro_state & syntax->state_mask) != syntax->state_value) { /* * We should probably distinguish here between * out-of-context operators and illegal tags, but it's too * much trouble. */ code = gs_note_error(errorIllegalOperatorSequence); if (tag >= 0x40 && tag < 0xc0) st->last_operator = tag; goto x; } st->macro_state ^= syntax->state_transition; switch (tag >> 3) { case 0: switch (tag) { case pxtNull: ++p; continue; default: break; } break; case 1: switch (tag) { case pxtHT: case pxtLF: case pxtVT: case pxtFF: case pxtCR: ++p; continue; default: break; } break; case 3: if (tag == pxt1b) { /* ESC *//* Check for UEL */ if (memcmp(p + 1, "\033%-12345X", min(left, 9))) break; /* not UEL, error */ if (left < 9) goto x; /* need more data */ p += 9; code = e_ExitLanguage; goto x; } break; case 4: switch (tag) { case pxtSpace: /* break; will error, compatible with lj */ /* ++p;continue; silently ignores the space */ ++p; continue; default: break; } break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: /* Operators */ /* Make sure that we have all the required attributes, */ /* and no attributes that are neither required nor */ /* optional. (It's up to the operator to make any */ /* more precise checks than this. */ st->operator_count++; /* if this is a passthrough operator we have to tell the passthrough module if this operator was preceded by another passthrough operator or a different xl operator */ if (tag == pxtPassThrough) { pxpcl_passthroughcontiguous(st->last_operator == tag); } else if (st->last_operator == pxtPassThrough) { pxpcl_endpassthroughcontiguous(pxs); } st->last_operator = tag; { const px_operator_definition_t *pod = &px_operator_definitions[tag - 0x40]; int left = sp - st->stack; const byte /*px_attribute_t */ * pal = pod->attrs; px_value_t **ppv = st->args.pv; bool required = true; code = 0; /* * Scan the attributes. Illegal attributes take priority * over missing attributes, which in turn take priority * over illegal data types. */ for (;; ++pal, ++ppv) { px_attribute_t attr = *pal; uint index; if (!attr) { /* * We've reached the end of either the required or * the optional attribute list. */ if (!required) break; required = false; --ppv; /* cancel incrementing */ continue; } if ((index = st->attribute_indices[attr]) == 0) { if (required) code = gs_note_error(errorMissingAttribute); else *ppv = 0; } else { /* Check the attribute data type and value. */ px_value_t *pv = *ppv = &st->stack[index]; const px_attr_value_type_t *pavt = &px_attr_value_types[attr]; int acode; if ((~pavt->mask & pv->type & (pxd_structure | pxd_representation)) || (pavt->mask == (pxd_scalar | pxd_ubyte) && (pv->value.i < 0 || pv->value.i > pavt->limit)) ) { if (code >= 0) code = gs_note_error (errorIllegalAttributeDataType); } if (pavt->proc != 0 && (acode = (*pavt->proc) (pv)) < 0) { if (code >= 0) code = acode; } --left; } } /* Make sure there are no attributes left over. */ if (left) code = gs_note_error(errorIllegalAttribute); if (code >= 0) { st->args.source.phase = 0; code = (*pod->proc) (&st->args, pxs); /* If we get a 'remap_color' error, it means we are dealing with a * pattern, and the device supports high level patterns. So we must * use our high level pattern implementation. */ if (code == gs_error_Remap_Color) { code = px_high_level_pattern(pxs->pgs); if (code < 0) goto x; code = (*pod->proc) (&st->args, pxs); } } if (code < 0) goto x; /* Check whether the operator wanted source data. */ if (code == pxNeedData) { if (!pxs->data_source_open) { code = gs_note_error(errorDataSourceNotOpen); goto x; } st->data_proc = pod->proc; ++p; goto top; } } clear_stack(); ++p; continue; case 24: sp[1].type = pxd_scalar; count = 1; goto data; case 26: sp[1].type = pxd_xy; count = 2; goto data; case 28: sp[1].type = pxd_box; count = 4; goto data; /* Scalar, point, and box data */ data:{ int i; if (sp == stack_limit) { code = gs_note_error(errorInternalOverflow); goto x; } ++sp; sp->attribute = 0; p += 2; #ifdef DEBUG # define trace_scalar(mem, format, cast, alt)\ if ( gs_debug_c('i') )\ trace_data(mem, format, cast, sp->value.alt, count) #else # define trace_scalar(mem, format, cast, alt) DO_NOTHING #endif switch (tag & 7) { case pxt_ubyte & 7: sp->type |= pxd_ubyte; for (i = 0; i < count; ++p, ++i) sp->value.ia[i] = *p; dux:trace_scalar(pxs->memory, " %lu", ulong, ia); --p; continue; case pxt_uint16 & 7: sp->type |= pxd_uint16; for (i = 0; i < count; p += 2, ++i) sp->value.ia[i] = get_uint16(st, p); goto dux; case pxt_uint32 & 7: sp->type |= pxd_uint32; for (i = 0; i < count; p += 4, ++i) sp->value.ia[i] = get_uint32(st, p); goto dux; case pxt_sint16 & 7: sp->type |= pxd_sint16; for (i = 0; i < count; p += 2, ++i) sp->value.ia[i] = get_sint16(st, p); dsx:trace_scalar(pxs->memory, " %ld", long, ia); --p; continue; case pxt_sint32 & 7: sp->type |= pxd_sint32; for (i = 0; i < count; p += 4, ++i) sp->value.ia[i] = get_sint32(st, p); goto dsx; case pxt_real32 & 7: sp->type |= pxd_real32; for (i = 0; i < count; p += 4, ++i) sp->value.ra[i] = get_real32(st, p); trace_scalar(pxs->memory, " %g", double, ra); --p; continue; default: break; } } break; case 25: /* Array data */ { const byte *dp; uint nbytes; if (sp == stack_limit) { code = gs_note_error(errorInternalOverflow); goto x; } switch (p[2]) { case pxt_ubyte: sp[1].value.array.size = p[3]; dp = p + 4; break; case pxt_uint16: if (left < 4) { if_debug0m('i', memory, "...\n"); /* Undo the state transition. */ st->macro_state ^= syntax->state_transition; goto x; } sp[1].value.array.size = get_uint16(st, p + 3); dp = p + 5; break; default: st->last_operator = tag; /* for error message */ code = gs_note_error(errorIllegalTag); goto x; } nbytes = sp[1].value.array.size; if_debug1m('i', memory, "[%u]\n", sp[1].value.array.size); switch (tag) { case pxt_ubyte_array: sp[1].type = pxd_array | pxd_ubyte; array:++sp; if (st->big_endian) sp->type |= pxd_big_endian; sp->value.array.data = dp; sp->attribute = 0; /* Check whether we have enough data for the entire */ /* array. */ if (rlimit + 1 - dp < nbytes) { /* Exit now, continue reading when we return. */ uint avail = rlimit + 1 - dp; code = px_save_array(sp, pxs, "partial array", avail); if (code < 0) goto x; sp->type |= pxd_on_heap; st->data_left = nbytes - avail; st->data_proc = 0; p = rlimit; goto x; } p = dp + nbytes - 1; trace_array(memory, sp); continue; case pxt_uint16_array: sp[1].type = pxd_array | pxd_uint16; a16:nbytes <<= 1; goto array; case pxt_uint32_array: sp[1].type = pxd_array | pxd_uint32; a32:nbytes <<= 2; goto array; case pxt_sint16_array: sp[1].type = pxd_array | pxd_sint16; goto a16; case pxt_sint32_array: sp[1].type = pxd_array | pxd_sint32; goto a32; case pxt_real32_array: sp[1].type = pxd_array | pxd_real32; goto a32; default: break; } break; } break; case 31: { px_attribute_t attr; const byte *pnext; switch (tag) { case pxt_attr_ubyte: attr = p[2]; pnext = p + 2; goto a; case pxt_attr_uint16: attr = get_uint16(st, p + 2); pnext = p + 3; a:if (attr >= px_attribute_next) break; /* * We could check the attribute value type here, but * in order to match the behavior of the H-P printers, * we don't do it until we see the operator. * * It is legal to specify the same attribute more than * once; the last value has priority. If this happens, * since the order of attributes doesn't matter, we can * just replace the former value on the stack. */ sp->attribute = attr; if (st->attribute_indices[attr] != 0) { px_value_t *old_sp = &st->stack[st->attribute_indices[attr]]; /* If the old value is on the heap, free it. */ if (old_sp->type & pxd_on_heap) gs_free_object(memory, (void *)old_sp->value. array.data, "old value for duplicate attribute"); *old_sp = *sp--; } else st->attribute_indices[attr] = sp - st->stack; p = pnext; continue; case pxt_dataLength: /* * Unexpected data length operators are normally not * allowed, but there might be a zero-length data * block immediately following a zero-size image, * which doesn't ask for any data. */ if (uint32at(p + 2, true /*arbitrary */ ) == 0) { p += 5; continue; } break; case pxt_dataLengthByte: /* See the comment under pxt_dataLength above. */ if (p[2] == 0) { p += 2; continue; } break; default: break; } } break; default: break; } /* Unknown tag value. Report an error. */ st->last_operator = tag; /* for error message */ code = gs_note_error(errorIllegalTag); break; } x: /* Save any leftover input. */ left = rlimit - p; if (rlimit != pr->limit) { /* We were reading saved input. */ if (left <= next_p - orig_p) { /* We finished reading the previously saved input. */ /* Continue reading current input, unless we got an error. */ p = next_p -= left; rlimit = pr->limit; st->saved_count = 0; if (code >= 0) goto parse; } else { /* There's still some previously saved input left over. */ memmove(st->saved, p + 1, st->saved_count = left); p = next_p; rlimit = pr->limit; left = rlimit - p; } } /* Except in case of error, save any remaining input. */ if (code >= 0) { if (left + st->saved_count > sizeof(st->saved)) { /* Fatal error -- shouldn't happen! */ code = gs_note_error(errorInternalOverflow); st->saved_count = 0; } else { memcpy(&st->saved[st->saved_count], p + 1, left); st->saved_count += left; p = rlimit; } } pr->ptr = p; st->stack_count = sp - st->stack; /* Move to the heap any arrays whose data was being referenced */ /* directly in the input buffer. */ for (; sp > st->stack; --sp) if ((sp->type & (pxd_array | pxd_on_heap)) == pxd_array) { int code = px_save_array(sp, pxs, "px stack array to heap", sp->value.array.size * value_size(sp)); if (code < 0) break; sp->type |= pxd_on_heap; } if (code < 0 && syntax != 0) { /* Undo the state transition. */ st->macro_state ^= syntax->state_transition; } return code; }