/** * @brief Reads from a buffer according to format; version without syntactic sugar for variable arguments, to call it from other functions with variable arguments * @sa SV_ReadFormat * @param[in] buf The buffer we read the data from * @param[in] format The format string may not be nullptr * @param ap The variadic function argument list corresponding to the format string */ void NET_vReadFormat (dbuffer* buf, const char* format, va_list ap) { while (*format) { const char typeID = *format++; switch (typeID) { case 'c': *va_arg(ap, int*) = NET_ReadChar(buf); break; case 'b': *va_arg(ap, int*) = NET_ReadByte(buf); break; case 's': *va_arg(ap, int*) = NET_ReadShort(buf); break; case 'l': *va_arg(ap, int*) = NET_ReadLong(buf); break; case 'p': NET_ReadPos(buf, *va_arg(ap, vec3_t*)); break; case 'g': NET_ReadGPos(buf, *va_arg(ap, pos3_t*)); break; case 'd': NET_ReadDir(buf, *va_arg(ap, vec3_t*)); break; case 'a': *va_arg(ap, float*) = NET_ReadAngle(buf); break; case '!': format++; break; case '&': { char* str = va_arg(ap, char*); const size_t length = va_arg(ap, size_t); NET_ReadString(buf, str, length); break; } case '*': { const int n = NET_ReadShort(buf); *va_arg(ap, int*) = n; byte* p = va_arg(ap, byte*); for (int i = 0; i < n; i++) *p++ = NET_ReadByte(buf); } break; default: Com_Error(ERR_DROP, "ReadFormat: Unknown type!"); } } /* Too many arguments for the given format; too few cause crash above */ #ifdef PARANOID if (!ap) Com_Error(ERR_DROP, "ReadFormat: Too many arguments!"); #endif }
void NET_SkipFormat (dbuffer* buf, const char* format) { while (*format) { const char typeID = *format++; switch (typeID) { case 'c': NET_ReadChar(buf); break; case 'b': NET_ReadByte(buf); break; case 's': NET_ReadShort(buf); break; case 'l': NET_ReadLong(buf); break; case 'p': { vec3_t v; NET_ReadPos(buf, v); break; } case 'g': { pos3_t p; NET_ReadGPos(buf, p); break; } case 'd': { vec3_t v; NET_ReadDir(buf, v); break; } case 'a': NET_ReadAngle(buf); break; case '!': format++; break; case '&': NET_ReadString(buf, nullptr, 0); break; case '*': { const int n = NET_ReadShort(buf); for (int i = 0; i < n; i++) NET_ReadByte(buf); break; } default: Com_Error(ERR_DROP, "ReadFormat: Unknown type!"); } } }
static float SV_ReadAngle (void) { return NET_ReadAngle(sv->messageBuffer); }